4

I tried testing the system and I’m not sure if the problem is with the XBee’s, the transmitting code, or the receiving code. Before I post my code, I will explain what we are doing with the signals.

We have three analog signals that will be sent serially through one XBee using an Arduino and XBee shield. We want to send these signals to the receiving xbee where the Arduino will output these signals to be connected to a third Arduino through wires to be used in a Simulink program.

We are using an Arduino mega for the transmitting side and an Arduino uno for the receiving side. I was told I need to do serial streaming but I’m not sure how that’s done. I understand the XBee and Arduinos both digitize signals but we are hoping to get a signal very similar to the analog signals we are transmitting. Any amount of help is greatly appreciated!!

This is how I have my XBees configured (series 1) both in AT mode:

Transmitting XBee:
Channel:10
Pan id: 1234
MY: 10
DL: 11

Receiving XBee:
Channel:10
Pan ID: 1234 MY: 11
DL: 10

Transmitting Arduino code:

void setup() {  
  Serial.begin(9600);  
}  
void loop() {  
  // read the input on analog pins 
  int sensorValue1 = analogRead(A0);  
  int sensorValue2 = analogRead(A1);  
  int sensorValue3 = analogRead(A2);  
  // print out the value you read: 
  Serial.println(sensorValue1);  
  Serial.println(sensorValue2);  
  Serial.println(sensorValue3);  
  delay(1);   
}  

Receiving Arduino code:

int received1=8;  
int received2=9;  
int received3=10;  
void setup(){  
  pinMode(received1, OUTPUT);  
  pinMode(received2, OUTPUT);  
  pinMode(received3, OUTPUT);  
  Serial.begin(9600);  
}  
void loop(){  
  if(Serial.available() )  
  {  
    byte output1 = Serial.read();  
    byte output2 = Serial.read();  
    byte output3 = Serial.read();  
    digitalWrite(received1, HIGH);  
    digitalWrite(received2, HIGH);  
    digitalWrite(received3, HIGH);  
  }  
}
3

There are several things here:

  1. Increase your delay, you don't want to be sending the data that often, even if you only increase it to 100-200ms, although I'd recommend making it in the order of 1-30 seconds.

  2. You're reading in analog inputs which will be in the range of 0-1023 but your serial reads are in byte format (which will actually be reading the first three bytes (or the first three DIGITS of the first reading). More about this below.

  3. You're reading in three arbitrary bytes, you're not identifying them at all, you have no idea what you're reading (other than by testing for a 1ms delay--which over XBee is not practical).

You have two options, transmit the data as ASCII (not a good idea IMHO), pre-pending some identifier such that:

1:259
2:0
3:1019

or even some other delimiter:

259:0:1019

But I would probably lean towards byte encoding:

byte0 :0xEA    // just some custom header for yourself
byte1H:0x01
byte1L:0x03
byte2H:0x00
byte2L:0x00
byte3H:0x03
byte3L:0xFB
byte4 :0xXX    // checksum

Or you could map the inputs down to a range of 0-255 for single byte transmission.

Next you'll need to work on receiving the data, how you do that is going to depend on how you encode the stream.

edit: I've removed the code sample that was here and replaced it with two working sketches below.


I have two XBees, running in AT mode, mine are Series 2, but programatically I THINK they are the same. If not, you'll have to tweak these, but I'm pretty sure you'll be right.

What we have are two apps, the first is the "SENDING" app, it takes three arbitrary values, they are: minutes (0-60) the micro has been running, seconds (0-60) the micro has been running, and 100 (it was random, and you can put that back if you want). Also, if you comment out the #define TESTAPP instead of using these values, it can pull three analog values from A0-A2 instead. (If you change it in the receiving app, you could have three LEDS on Pulse Width channels and vary the brightness).

/* * * * * * * */

XBEE SENDER (131) 

#define TESTAPP        // Just serial data based on time

#define PACKETLENGTH   7
#define LED            13

/* * * * * * * */

void setup(){
    Serial.begin(9600);  
    Serial.println("\nSender");
    randomSeed(analogRead(0));   
    pinMode(LED,OUTPUT);
}

unsigned long m1 = 0;
unsigned long m2 = 0;

void loop(){
    m1 = millis()/1000;
    if(m2 != m1){
        m2 = m1;

#ifdef TESTAPP        
        uint8_t  s = m1 % 60;           // how many seconds on millis()
        m1 /= 60;                       // now we're working with minutes
        uint8_t  m = m1 % 60;           // how manu minutes on millis()
        uint8_t  r = 100; //random(256);
        Serial.print("x.x");            // this is just pre-pended data for testing
        Serial.print('<');  
        Serial.write(m);  
        Serial.print('-');  
        Serial.write(s);  
        Serial.print('-');  
        Serial.write(r);  
        Serial.print(">  x-x");        // we want to ignore these chars
#else
        Serial.print('<');  
        Serial.write(map(analogRead(A0),0,1023,0,255));  
        Serial.print('-');  
        Serial.write(map(analogRead(A1),0,1023,0,255));  
        Serial.print('-');  
        Serial.write(map(analogRead(A2),0,1023,0,255));  
        Serial.print('>');        
#endif
        digitalWrite(LED,!digitalRead(LED));  // toggle the LED everytime we're here
    }
    // do other stuff here...
}

You'll notice garbage characters around the data we are transporting, this is to demonstrate cycling through all serial communications to arrive at the 7 particular characters we need. That's done in the next app, the receiver:

/* * * * * * * * */

XBEE RECEIVER (121) 

#define TESTAPP  // if you attach 3 LEDS to 9, 10 and 11, the remove this line.

//#define DEBUG  // uncomment this line to see all the data stream coming in

#define PACKETLENGTH  7

/* * * * * * * * */

int LED[3]={9, 10, 11};

void setup(){
  Serial.begin(9600);  
  Serial.println("\nReceiver");
}

byte  buffer[PACKETLENGTH]; // what holds our serial data
byte  idx         = 0;      // the index for the buffer character being written
byte  validBuffer = 0;      // flag to tell us if we're ready to go

void loop(){
  if(validBuffer){
      #ifdef TESTAPP
          // we're just going to print it out in a different format
          validBuffer=0;
          #ifdef DEBUG
              Serial.print('\n');
          #endif
          Serial.print("Data: (");
          if (buffer[1]<10) Serial.print("0");
          Serial.print(buffer[1]);
          Serial.print(":");
          if (buffer[3]<10) Serial.print("0");
          Serial.print(buffer[3]);
          Serial.print(") (");
          Serial.print(buffer[5]);
          Serial.println(")");
      #else
          // this is the more practical side of things
          // instead of serial.printing, change the brightness 
          // on three attached LEDs via PWM Pins (9, 10, 11)
          analogWrite(LED[0],buffer[1]); 
          analogWrite(LED[1],buffer[3]);
          analogWrite(LED[2],buffer[5]);
      #endif
      memset(buffer, 0, PACKETLENGTH);  // we've used the data, clear it out
      idx = 0;                          // and reset the index marker
  }  
}

// This is where the real magic is done. We have a buffer of
// PACKETLENGTH that takes in all Serial data and waits until
// it finds PACKETLENGTH characters in the format we're after
// Probably not the best method, but it would be unlikely to
// stumble across this pattern, although not impossible :) 
// use at your own risk 

void serialEvent(){
    if(validBuffer) return; //we don't want to process new Serial
                            //until we've processed the buffer
    buffer[idx] = Serial.read();
        #ifdef DEBUG
        Serial.write(buffer[idx]);
        #endif

    if (++idx==PACKETLENGTH){
        // we have enough bytes for testing, this next part could be handled better
        if(  buffer[0]=='<' && 
             buffer[2]=='-' &&     
             buffer[4]=='-' &&     
             buffer[6]=='>' ) { // we have a valid data packet     
               validBuffer=1;
        } else {    // we don't have valid data yet, but keep
                    // what we have, shift it all over one byte and
                    // we'll check again once the next byte is received
            memmove(buffer, buffer + 1, PACKETLENGTH-1);
        }  
        idx--;
    }
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.