pot value

I am trying to display the pot value using the serial monitor through xbee. I have one arduino I am reading in the pot value, sending over serial to the second arduino and I want to output the value to the serial monitor. Here is my attempt, I have yet to test it as my partner has the arduinos. Can someone check the code?
arduino1

int potPin = 0; // select input pin 
int val = 0; // variable to store the value 

void setup() {
Serial.begin(9600);
}

void loop() 
{
val = analogRead(potPin); // read the value from the pot
val = map(val, 0 1023, 0, 180);
Serial.println( val );
delay(1);
}

Can someone check the code?

Sure. It looked like code. Not correct code, but it was code.

val = analogRead(potPin); // read the value from the pot
val = map(val, 0 1023, 0, 180);
Serial.println( val );

This is going to get a value from the potentiometer, and map it to a new value, and send the new value as a string, somewhere between "0" and "180".

  //converting char value into integer
  int data = Serial.read() - '0';

This is going to be called once for each character that arrives. If the string send was "145", data will be 1 on one pass, 4 on another pass, 6 on another pass, -32 on another pass, and -35 on another pass.

Hardly what you want, I would think.

  int pos = map(data,0,30,0,180); 
  pos = constrain(pos,0,180);

Even if some magic intervened, and data was 145 as sent by the sender, what are you doing here?

If the receiver XBee is connected to pins 0 and 1 of the Arduino, the data that comes in over the air will appear on the Serial Monitor as soon as it is received, even if the Arduino takes a nap. It really isn't clear what the Arduino on the receiving end is doing.

What I am trying to do is just test the xbee's and make sure they are communicating and also test a certain range on the pots as they will go into a steering wheel and I will not be using the full range. So, I want to see what my actual range is on the 0-1023 scale. Probably something like 200-800 or something.

So, I was trying to get the first arduino to send the values to the second through xbee's and have the second display the pot values to the monitor so I can see that it is receiving and is working properly as I will need it to be doing this in the testing phase of the project. I can updated my code, I can not test it till possibly tomorrow but I would like to get it somewhat correct before hand.

Input into arduino1

int potPin = 0; // select input pin 
int val = 0; // variable to store the value

void setup() {
Serial.begin(9600);
}

void loop() 
{
val = analogRead(potPin); // read the value from the pot

Serial.println( val );
delay(1);
}

arduino2 receiving and out to monitor

//read in value from first arduino of slide pot
//#include "RoboClaw.h"
//#include "BMSerial.h"

void setup()
{
  Serial.begin(9600);
}


void loop()
{
   //stays until receive value front arduino1
  while(Serial.available() == 0);
  
  //converting char value into integer
  //int data = Serial.read() - '0'; 

  int data = Serial.read();
  

  int pos = map(data,0,1023,0,1023); 
  
  Serial.println(pos); //sends the data, serial.write
  
}

Serial.print() sends strings (arrays of characters).
Serial.read() reads characters - one at a time.

Think about what this means, and whether the receiver is correct (it is not). How can you fix it? You need to read more than one character, storing the characters in an array, until the end of the packet is reached. Then, you need to convert the array to an int, to use.

Look at your sender. How will the receiver know when the end of a packet is reached?

The value being sent as a string be the sender is in the range 0 to 180. That should give you a fairly good idea how big the array needs to be.

The size of the array is NOT the defining factor in when to stop reading from the serial port. The presence of the end of packet marker IS.

The array needs to be kept NULL terminated. Otherwise, it is not a valid input to atoi().

Once you have received an end of packet marker, and you have processed the data in string, you need to reset for the next packet.

Finally, keep in mind that the whole packet may not arrive in one iteration of loop.

Hint: I regularly post code that reads packets from the serial port - "PaulS started ended" as a search term...

   while(Serial.available() >= 0); //since 0-1023

The body of your while statement is the semicolon on the end. Probably not what you want.

char string[180]; //not sure on size

Grab a pen. Write '1' on one finger. Write '8' on the next one. Write '0' on the next one. Write 0 on the last one. How many fingers did you write on? Probably not 180 of them...

You need to revise the sender to send "<180>", instead of 180 to use that code.

      int val=atoi(string); 
      Serial.println(string);

Most people would by interested in printing val, to assure that the value was received and parsed correctly. Your mileage may vary.

(Much closer, though - your 99% of the way there.)

Ok, made two errors you pointed out. Also corrected the string size, I was thinking incorrectly when writing it. The pot has a potential of four digits at it max, but more than likely I will only using a max of 3. It that the right logic?

Thank you for the help. Now onto the 'P' algorithm. Will probably be posting a little help about that soon. I am fairly new to all of this :slight_smile:

The pot has a potential of four digits at it max, but more than likely I will only using a max of 3. It that the right logic?

The pot reading can go to 4 digits, but you are mapping the value to the range 0 to 180, which is three digits. The trailing NULL means that the array needs to hold 4 characters. Making it larger, like 8 characters, won't hurt.

Post your sender and receiver code again, for a final look-see.

sender

int potPin = 0; // select input pin 
int val = 0; // variable to store the value

void setup() {
Serial.begin(9600);
}

void loop() 
{
val = analogRead(potPin); // read the value from the pot
//val = map(val, 0 1023, 0, 180);
Serial.println( val );
delay(1);
}

receiver

//read till end of packet
char string[8]; 
int x;
int index;
boolean started=false;
boolean ended=false;

void setup()
{
  Serial.begin(9600);
}

void loop()
{
   while(Serial.available() >= 0) //since 0-1023
    {
      x=Serial.read(); //read the character
      if(x=='<') //not sure what to put in if statement to run until end
      {
        started = true;
        index=0;
        string[index]='\0';
      }
      else if(x=='>')
      {
        ended = true;
      }
      
      else if(started)
      {
        string[index]=x;
        index++;
        string[index]='\0';
        string[index]=x; //store character
      }
    //x = Serial.read(); //read another string
    }
    
    if(started && ended)
    {
      //convert portion of string to integer representation
      int val=atoi(string); 
      Serial.println(val);
      
      //next time
      started = false;
      ended = false;
      
      index = 0;
      string[index]='\0';
    }
  }

Aside from the fact that x is a lousy name for a global variable, and the value read from the serial port does not need to be global, the receiver code now looks good.

It is expecting a stream of data like '<', '6', '7', '2', '>' to arrive on the serial port, at various times during the data. If such data shows up, it will be collected in an array, and eventually (when the '>' arrives, the data in string will be "672", which will be converted to an int and sent back to the sender and to the serial monitor.

Unfortunately, the sender is not sending '<', '6', '7', '2', '>'. It is sending '6', '7', '2', , , so the receiver will never do anything. The receiver needs to have:

Serial.print("<");
Serial.print(val);
Serial.print(">");

instead of

Serial.println(val);

Oh, and the receiver needs to break out of the while loop when the '>' is received:
else if(x=='>')
{
ended = true;
break;
}

Paul, just got the arduinos and for some reason not getting values to print to serial monitor from the second arduino using the sender and receiver code above. It doesn't print anything so not sure what could be the problem.

Have a friend who has code for an led through xbee and it shows values when pot turns.

It doesn't print anything so not sure what could be the problem.

I don't know either. I can't see you debug output. Oh, wait, you don't have any. Time to add some.

This is pretty much my first time ever using an arduino so not quite sure about the debug output. I will add it if you would let me know what exactly you are recommending me post.

This is pretty much my first time ever using an arduino so not quite sure about the debug output. I will add it if you would let me know what exactly you are recommending me post.

There are several things that might be interesting to know. For instance, Serial.available() returns a value. What is that value?

If it is greater than 0, you read a value. What is that value?

Thank you. Process is load the sender arduino, move usb and load receiver arduino. Then leave usb in to read serial monitor on receiver arduino. Doing this process serial.available prints out 0. I set value = serial.available and printed value.

Also printed out serial.read and it seems all it reads is -1 for awhile then seems like a continuous loop of numbers without the pot even moving.

int potPin = 0; // select input pin 
int val; // variable to store the value

void setup() {
Serial.begin(9600);
}

void loop() 
{
  val = analogRead(potPin); // read the value from the pot
  Serial.print(val); //sends 1 byte
  
}

receiver

char string[4]; //can be 4, 8 is fine
byte var;
int index = 0;
boolean started=false;
boolean ended=false;


void setup()
{
  Serial.begin(9600);
}

void loop()
{
  int value = Serial.available();
  Serial.println(value);
  
    while(Serial.available() > 0)
    {
      var=Serial.read(); //read the character
      if(var=='<') //not sure what to put in if statement to run until end
      {
        started = true;
        index=0;
        string[index]='\0';
      }
      else if(var=='>')
      {
        ended = true;
        break; //break out of while loop when '>' received
      }
      
      else if(started)
      {
        string[index]=var;
        index++;
        string[index]='\0';
        string[index]=var; //store character
      }
    //x = Serial.read(); //read another string
    }
    
    if(started && ended)
    {
      //convert portion of string to integer representation
      int val=atoi(string); 
      Serial.println("<");
      Serial.println(val);
      Serial.println(">");
      
      //next time
      started = false;
      ended = false;
      
      index = 0;
      string[index]='\0';
    }
  }

Well, I tested the xbee's and such using different code. I sent the file to both arduinos to display an led on arduino2 that is controlled by a pot in arduino1 and it works. I tried outputting the values that arduino2 is receiving to control the led to the serial monitor but not getting anything with the usb from arduino2 to computer just like the code for the pot you've helped me on. Just was letting you know that the xbee's seem to be fine.

#define potPin 0
#define ledPin 11

int inByte = -1;
char inString[6];
int stringPos = 0;
int lastValue = 0;

void setup()  {
  pinMode(ledPin, OUTPUT);
  Serial.begin(9600);
} 

void loop() {
   inByte = Serial.read();

   //only send new value if it is different than last sent value.
   //Min value change of 5 neded. Just so we dont flood the network
   int potVal = analogRead(potPin);
   if( abs(potVal - lastValue) > 5){
     Serial.println(potVal);
     lastValue = potVal;
   }

  //if there is any numerical serial available, store that
  if((inByte >= '0') && (inByte <= '9')){
    inString[stringPos] = inByte;
    stringPos ++;
  }

  //if there is a line end character, this string is done, take value and write to LED pin
  //clear the string when done
  if(inByte == '\r'){
    int brightness = atoi(inString); //convert string to int
    Serial.print(brightness);
    //incoming will be a range of 0-1023, we need 0-255
    brightness = map(brightness, 0, 1023, 0, 255);
    analogWrite(ledPin, brightness);

    //clear the values from inString
    for (int c = 0; c < stringPos; c++){
      inString[c] = 0;
    }
    stringPos = 0;
  }

}

Also printed out serial.read and it seems all it reads is -1 for awhile then seems like a continuous loop of numbers without the pot even moving.

  val = analogRead(potPin); // read the value from the pot
  Serial.print(val); //sends 1 byte

Well, duh! And, you comment is wrong. Very wrong.

  int value = Serial.available();
  Serial.println(value);

So, a number appears in the serial monitor. What does that number mean?

      if(var=='<') //not sure what to put in if statement to run until end
      {
        started = true;
<snip>
      else if(var=='>')
      {
        ended = true;
<snip>
      else if(started)
      {
        string[index]=var;

Might be worth having the sender actually send a < and a > if you expect the receiver to receive them.

...... and is a infinite loop displaying numbers continuously without the pot even moving.

I don't understand why this surprises you. You have nothing on the sender that says send a value only when a change occurs. You have code that says send a value every time through loop(), and then pause for a short period of time.

You are printing anonymous data. How are we supposed to know where you put the print statements or what is being printed?

Got to to where when it is not an infinite loop at first but once I turn past a certain point it turns into an infinite loop until I turn it back. Isn't showing values 0-1023, still range I mentioned previously.

sender

int potPin = 0; // select input pin 
int val; // variable to store the value
int lastVal = 0;

void setup() {
Serial.begin(9600);
}

void loop() 
{
  val = analogRead(potPin); // read the value from the pot
  if(abs(val - lastVal) > 5)
  {
    Serial.println("<");
    Serial.println(val); 
    Serial.println(">");
  }
}

receiver

char string[4]; //can be 4, 8 is fine
byte var;
int index = 0;
boolean started=false;
boolean ended=false;


void setup()
{
  Serial.begin(9600);
}

void loop()
{
  //int value = Serial.available();
  //Serial.print(value);
  
    while(Serial.available() > 0)
    {
      var=Serial.read(); //read the character
      if(var=='<') //not sure what to put in if statement to run until end
      {
        started = true;
        index=0;
        string[index]='\0';
      }
      else if(var=='>')
      {
        ended = true;
        break; //break out of while loop when '>' received
      }
      
      else if(started)
      {
        string[index]=var;
        index++;
        string[index]='\0';
        string[index]=var; //store character
      }
    //x = Serial.read(); //read another string
    }
    
    if(started && ended)
    {
      //convert portion of string to integer representation
      int val=atoi(string); 
      Serial.println("<");
      Serial.println(val);
      Serial.println(">");
      
      //next time
      started = false;
      ended = false;
      
      index = 0;
      string[index]='\0';
    }
  }
  val = analogRead(potPin); // read the value from the pot
  if(abs(val - lastVal) > 5)
  {
    Serial.println("<");
    Serial.println(val); 
    Serial.println(">");
  }

Would be nice to reset lastVal at some point, don't you think?

      var=Serial.read(); //read the character

What did you read?

      if(var=='<') //not sure what to put in if statement to run until end

How does this comment relate to this statement?