Go Down

Topic: arduino to arduino via XBee, multiple data unsynchronized (Read 2451 times) previous topic - next topic

cfc

Jan 30, 2011, 12:31 am Last Edit: Jan 30, 2011, 12:34 am by cfc Reason: 1
Guys,

Had success sending light sensor data(first divide by 10 to convert to char data type before transmitting) from remote Arduino/Data Shield/XBee----->XBee/Arduino/PC. The data made sense and identical to that when I monitor the Serial output of the transmitting unit alone.

However: when I try to send temp AND light sensor data(again divided by 10 to keep within integer range of char data type), the light reading is way too high and in fact not consistent. I know there's a simple explanation, but I've struggled with different timing, checked Forum with as many search strings as I could think of, checked Tom Igoe's book which I own, tried to adapt SerialCallResponse for use with Arduino without Processing, and as I'm not a programmer I am stuck.

Light data should be ranging between 40-60(raw data would be 400-600), but I'm getting 191, 170's and inconsistent.

It's been two weeks for me to bother you all with this.

Without posting code yet, is there any code for synchronization you can suggest or general suggestions for newbie pitfalls?


PaulS

If the data you are transmitting is from analogRead, dividing by 4 will give the best results (greatest precision). We'd need to see the code that you are using to send/receive the data to suggest any good solutions.

cfc

#2
Jan 30, 2011, 05:51 am Last Edit: Jan 30, 2011, 05:52 am by cfc Reason: 1
Re: dividing by four: yes, but that will cause the values to excede 127 and therefore be beyond range of char data type - that is, out of range of the integer equivalent of char data type....I tried dividing by 4, but even the single data case did not work out.

/*TRANSMITTER:

COM 12
Arduino/Xbee TRANSMITTER using NewSoftSerial to be able to
program Arduino without messing having to disconnect Tx and Rx pins to program, then
reconnect to use the Xbee
*/

#include <NewSoftSerial.h>

int lightPin = 1;  //analog input pin 1
int tempPin=0;
int light = 0;
int temp=0;


NewSoftSerial mySerial=NewSoftSerial(5,6);  //use these pins on DataLoggerShield,
//...connect to XBee Tx(Arduino Rx) and XBee Rx(Arduino Tx), respectively


void setup () {
 mySerial.begin(57600);


 Serial.begin(57600);

}  //END SETUP

void loop () {
 temp=analogRead(tempPin)/10;
 delay(10);
 light = analogRead(lightPin)/10;  //scale down for char data type transmission
 mySerial.print(char(temp));  //always send as CHAR data type for Rx to work
 mySerial.print(char(light));
 Serial.print(temp);
 Serial.print("  ");
 Serial.println(light);
 delay(100);

}


/*RECEIVER:




 COM 8
Arduino/Xbee RECEIVER using NewSoftSerial to be able to
program Arduino without messing having to disconnect Tx and Rx pins to program, then
reconnect to use the Xbee
Also we use Ethernet Shield once the below works

*/

#include <NewSoftSerial.h>
int light=0;
int temp=0;
int inByte=0;
int dataArray[]={0,0};

NewSoftSerial mySerial=NewSoftSerial(5,6);  //use these pins on Arduino,
//...connect to XBee Tx(Arduino Rx) and XBee Rx(Arduino Tx), respectively


void setup () {
 mySerial.begin(57600);
 Serial.begin(57600); // use the COM8 monitor to test this; if OK then do the server thing


}  //END SETUP

void loop () {
 while(mySerial.available()>0){
   for(int i=0;i<2;i++){
   inByte=mySerial.read();    
     dataArray=inByte;
   }
   temp=dataArray[0];
   light=dataArray[1];
   Serial.print(temp);
   Serial.print("  ");
   Serial.println(light);
 }
 inByte=0;
 
 
}


PaulS

Quote
that is, out of range of the integer equivalent of char data type

So what? The type that Serial.write() outputs is byte, not char. The range of values for byte is 0 to 255. That happens also to be that same type that Serial.read() returns. Coincidence? Not hardly.

Code: [Select]
//always send as CHAR data type for Rx to work
Wrong. Always use byte data type.

You should be using either Serial.write(temp) or Serial.print(temp, BYTE). Otherwise, the value is converted to a string, to be sent. That is what is happening to you. Then, you only read the first character of the string, and treat that as the value,

If temp is, after dividing by 10, 75 for instance, it is sent as '7' and '5'. The ascii codes for 7 and 5 are 55 and 53.

cfc

#4
Jan 30, 2011, 05:53 pm Last Edit: Jan 30, 2011, 06:32 pm by cfc Reason: 1
I tried dividing by 4 then sending as BYTE, with same result.....light data(second column) still wrong and inconsistent. So, now what?
Is there a way to synchronize the two Arduinos? Something like a SerialCallResponse for only Arduino without Processing being involved?

BY the way, the SoftSerial library shows that the read() function reads a character,  not a BYTE(?)

Thank you.

PaulS

Quote
I tried dividing by 4 then sending as BYTE, with same result

Where is the new code?

Code: [Select]
while(mySerial.available()>0){
    for(int i=0;i<2;i++){
    inByte=mySerial.read();   
      [color=orange]dataArray=inByte;[/color]
    }
    temp=dataArray[0];
    light=dataArray[1];
    Serial.print(temp);
    Serial.print("  ");
    Serial.println(light);
  }

I'm surprised that this even compiles. You have an array on one side of the = and a scalar variable on the other.

Try dataArray = inByte; instead.

Quote
BY the way, the SoftSerial library shows that the read() function reads a character,  not a BYTE(?)

That's NewSoftSerial, and bytes and chars are the same size, so they are interchangeable to some extent. Some functions behave differently (like Serial.print()) when called with a char vs. when called with a byte.

cfc

The code posted above is not what I had...it was for RECEIVER:

while(mySerial.available()>0){
    for(int i=0;i<2;i++){
    inByte=mySerial.read();   
      dataArray=inByte;
    }
    temp=dataArray[0];
    light=dataArray[1];
    Serial.print(temp);
    Serial.print("  ");
    Serial.println(light);
  }
  inByte=0;
 
 
}


FOR THE TX: I divided the raw analog data/4 then mySerial.print(temp, BYTE) and same for light data

PaulS

Idiotic forum software is interpreting [ i ] without spaces as italics.

Code: [Select]
while(mySerial.available()>0){
    for(int i=0;i<2;i++){
    inByte=mySerial.read();   
      dataArray=inByte;
    }
    temp=dataArray[0];
    light=dataArray[1];
    Serial.print(temp);
    Serial.print("  ");
    Serial.println(light);
  }

This code contains several problems. The mySerial.available() test determines that there is at least one byte to read. If that is the case, you read two. Hmmm, OK.

Then, both bytes are stored in dataArray, which is an array. So, it can't be assigned a value like this:
dataArray = inByte;

It needs to be assigned values like this:
dataArray[ i ] = inByte;

cfc

yes, that's what my code indeed does, it just does not post correctly here

Go Up