Xbee Zigbee remote sensor

Hi,

I've been trying understand and get working my project to receive analogue data from from a remote Xbee Series 2 but without much luck until I watched this XBee Basics - Lesson 5 - API mode: Send Digital Output to a Rmote XBee - YouTube

I have an Arduino with an Xbee Coordinator in API mode and a stand alone remote Xbee Router in API mode from which I wish to collect data when it is poled by the coordinator.

/*
Coordinator
ZigBee Coordinator API
Set PanID
Router
ZigBee Router AT
Set PanID
Set JV to 1
*/ 

#include <XBee.h>
#include <SoftwareSerial.h> 

// Define NewSoftSerial TX/RX pins
// Connect Arduino pin 8 to TX of usb-serial device
uint8_t ssRX = 8;
// Connect Arduino pin 9 to RX of usb-serial device
uint8_t ssTX = 9; 

// Remember to connect all devices to a common Ground: XBee, Arduino and USB-Serial device

SoftwareSerial nss(ssRX, ssTX); 

XBee xbee = XBee(); 

float temp;
int led = 13;
RemoteAtCommandResponse remoteAtResponse = RemoteAtCommandResponse();
ZBRxResponse rx = ZBRxResponse();
ZBRxIoSampleResponse ioSample = ZBRxIoSampleResponse(); 

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

void loop() {
  //setRemoteState(0x2);// HEX 32 = char 2 which = ADC
  setRemoteState();
  delay(5000);
  getData();
  delay(2000);
} 

void getData() {
  nss.println("void getData");
  unsigned long msb = 0, lsb = 0;
  xbee.readPacket(); //5000
    nss.println("read.Packet"); 

    if (xbee.getResponse().isAvailable()) {
      // got something
      nss.print("Frame Type = ");
      nss.println(xbee.getResponse().getApiId(), HEX);
      nss.print("Received I/O Sample from: ");
      nss.println(ioSample.getRemoteAddress16(), HEX);

      if (ioSample.containsAnalog()) {
        nss.println("Sample contains analog data");
        nss.println(ioSample.getAnalog(2), DEC);
      }
    }
  } 

//void setRemoteState(char value) {
void setRemoteState() {
  nss.println("void setRemoteState");

  //start byte
  Serial.write(0x7E); 

  //length
  Serial.write((byte)0x0);// Length MSB
  Serial.write(0x12);//Length LSB 

  //frame id for sending an AT command
  Serial.write(0x17); 

  //Frame ID
  Serial.write((byte)0x01); 

  //64 bit destination
  Serial.write((byte)0x00);
  Serial.write((byte)0x13);
  Serial.write((byte)0xA2);
  Serial.write((byte)0x00);
  Serial.write((byte)0x40);
  Serial.write((byte)0x6A);
  Serial.write(0x4E);
  Serial.write(0xE6); 

  //16 bit of recipient or 0xFFFE if unknown
  Serial.write(0xFF);
  Serial.write(0xFE); 

  //0x02 to apply changes immediately on remote
  Serial.write(0x02); 

  //command name in ASCII characters
  Serial.write(0x64);
  Serial.write(0x33);
  Serial.write(0x02);
  Serial.write(0x30);
  Serial.write(0x32);
  //command data in as many bytes as needed

  //Serial.write(value); 

  //checksum is all bytes after length bytes 
  long sum = 0x17 + 0x01 + 0x13 + 0xA2 + 0x40 + 0x6A + 0x4E + 0xE6 + 0xFF + 0xFE + 0x02 + 0x64 + 0x33 + 0x02 + 0x30 + 0x32; // + value; //A = 41, 3 = 33, value = 32

  Serial.write(0xFF - (sum & 0xFF));
  nss.print("sum = ");
  nss.println(sum, HEX);
  byte checksum = (0xFF -(sum & 0xFF));
  nss.print("Checksum = ");
  nss.println(checksum, HEX); 
}

Using the examples from the Youtube videos I have been able to a digital pin high and low on the remote Xbee. I have also been able to receive serial data when the remote is set to lop sending data back to the coordinator.

Strangely with the code above and with or without the remote device powered up, I see in the 'Serial Monitor' this:

void setRemoteState
sum = 5A5
Checksum = 5A
void getData
read.Packet
Frame Type = 97
Received I/O Sample from: 111

What I would like to know is:
Why do I get "Frame Type = 97" and "Received I/O Sample from 111"?
and
What do I need to do to read an analogue data from a poled Xbee pin?

I hope I have given enough information.
I have scoured the net and this forum to find the answer.
An I just to old to learn?

Many thanks

1 Like

Can somebody help me with this? Please?

I have also been able to receive serial data when the remote is set to lop sending data back to the coordinator.

"Set to lop"?

Is the XBee connected to the Serial pins or the nss pins? You appear to be sending stuff to Serial that is meant for the XBee and to be sending stuff to the XBee that is meant for the PC.

Hi PaulS

Thanks for replying.

Set to lop" should read "Set to loop" What I meant is that when I set the remote (stand-alone) Xbee's IR (IO Sampling Rate) and it periodically samples I get data back.This it with the coordinator pluged into an Arduino as per the "Series2_IoSamples" example.

Sorry for any confusion.

The Coordinator should see data on the Serial Pins (TX-1 RX-0). The nss pins are digital 8 & 9 and from these I see messages in the "Serial Monitor".

My aim is to have the Coordinator which is controlled and sat upon an Arduino pole numerious Remote (stand-alone) Xbee's using the IS command or better still individual analogue pins.

Hopefully this clarifies things and somebody can shed some light.

Thank you

Can somebody help me with this? Please?

Well, I've made some very slow progress and can now see data coming back from the remote Xbee if I use 'IS'.

I've had no luck with direct addressing and reading a single Analog input, either my command is wrong or it's not possible.

/*
Coordinator
ZigBee Coordinator API
Set PanID
Router
ZigBee Router AT
Set PanID
Set JV to 1
*/
#include <XBee.h>
#include <SoftwareSerial.h>
#define read_delay 5000 // 5 seconds 

// Define NewSoftSerial TX/RX pins
// Connect Arduino pin 8 to TX of usb-serial device
uint8_t ssRX = 8;
// Connect Arduino pin 9 to RX of usb-serial device
uint8_t ssTX = 9; 
SoftwareSerial nss(ssRX, ssTX); 

XBee xbee = XBee(); 
char inByte = '0x00';
float temp;
int led = 13;

//RemoteAtCommandResponse remoteAtResponse = RemoteAtCommandResponse();
//ZBRxIoSampleResponse ioSample = ZBRxIoSampleResponse();
//Rx64Response rx64 = Rx64Response();
//##############################################################################################
void setup() {
  pinMode(led, OUTPUT);
  Serial.begin(9600);
  nss.begin(9600);
} 
//##############################################################################################
void loop() {
  setRemoteState();
  delay(5000);
  int pos = 0; // position in read buffer
  int StartPos = 0; // starting offset of corner in string
  char buffer[32];
  while (Serial.available() > 0) {
    // read the incoming byte:
    inByte = Serial.read();
    nss.print("inByte");
    nss.println(inByte, HEX);
    // add to read buffer
    buffer[pos++] = inByte;
    
    if (inByte == 0x7E)
    {
      StartPos = pos;
      buffer[pos-1] = 0;
      nss.print("startPos");
      nss.println(StartPos);
    }
   }            
} 

//##############################################################################################
void setRemoteState() {
  nss.println("void setRemoteState");

  //start byte
  Serial.write(0x7E); 

  //length
  Serial.write((byte)0x00);// Length MSB
  Serial.write(0x0F);//Length LSB 

  //frame id for sending an AT command
  Serial.write(0x17); 
 
  //Frame ID
  Serial.write((byte)0x01); 

  //64 bit destination
  Serial.write((byte)0x00);
  Serial.write((byte)0x13);
  Serial.write((byte)0xA2);
  Serial.write((byte)0x00);
  Serial.write((byte)0x40);
  Serial.write((byte)0x6A);
  Serial.write((byte)0x4E);
  Serial.write((byte)0xE6); 

  //16 bit of recipient or 0xFFFE if unknown
  Serial.write(0xFF);
  Serial.write(0xFE); 

  //0x02 to apply changes immediately on remote
  Serial.write(0x02); 

  //command name in ASCII characters
  Serial.write(0x49);
  Serial.write(0x53);

  //checksum is all bytes after length bytes 
  long sum = 0x17 + 0x01 + 0x13 + 0xA2 + 0x40 + 0x6A + 0x4E + 0xE6 + 0xFF + 0xFE + 0x02 + 0x49 + 0x53; // + value; //A = 41, 3 = 33, value = 32

  Serial.write(0xFF - (sum & 0xFF));
  nss.print("sum = "); //print sum of sum
  nss.println(sum, HEX); //in hex
  byte checksum = (0xFF -(sum & 0xFF)); //make checksum
  nss.print("Checksum = "); //print checksum
  nss.println(checksum, HEX); // 
}

I now need to extract the analog data from the response. As you see I can find the '0x7E' I just need to determine the position of the analog value. I've read the web and data info but not sure of its exact position or the code to extract it.

If anyone has ideas on how to get the analog data I would appreciate your help.

Well I seem to have got it working. I'm sure the code could be improved and I will be modifying it as I go to include more End Devices.

Here is my code for any that are interested.

/*
Coordinator
ZigBee Coordinator API
Set PanID
Set AP API Enabled to 1
Router
ZigBee Router AT
Set PanID
Set JV to 1
Set D0 to ADC[2]
Set D1 to ADC[2]
Set D2 to Digital Out Low[4]
Set D3 to Digital Out Low[4]
Set D4 to Disabled[0]
Set D5 to Assoc Ind[1]
Set P0,1,2 to Disabled[0]
*/

#include <XBee.h>
#include <SoftwareSerial.h>
#define read_delay 5000 // 5 seconds 

// Define NewSoftSerial TX/RX pins
// Connect Arduino pin 8 to TX of usb-serial device
uint8_t ssRX = 8;
// Connect Arduino pin 9 to RX of usb-serial device
uint8_t ssTX = 9; 

SoftwareSerial nss(ssRX, ssTX); 

XBee xbee = XBee(); 

int pos = 0; // position in read buffer
int StartPos = 0; // starting offset of corner in string
char buffer[32];
byte inByte = '0x00';
byte lengthMSB = '0x00';
byte lengthLSB = '0x00';
float temp;
int led = 13;

//##############################################################################################
void setup() {
  pinMode(led, OUTPUT);
  Serial.begin(9600);
  nss.begin(9600);
} 
//##############################################################################################
void loop() {
  int anal1LSB;
  int anal1MSB;
  setRemoteState();
  delay(5000);

  while (Serial.available() > 0) {
    // read the incoming byte:
    inByte = Serial.read();
    //nss.print("inByte = ");
    //nss.println(inByte, HEX);
    // add to read buffer
    buffer[pos++] = inByte;
    //look for first byte of command

    if (inByte == 0x7E) { 
      pos = 1;
      //nss.print("Pos = ");
      //nss.println(pos);

    }
    /*if (pos == 2) { //find length 
      lengthMSB = inByte;
    }

    if (pos == 3) {
      lengthLSB = inByte;
    }*/
    if (pos == 27) { //first byte of analog 1
       anal1MSB = inByte;
    }

    if (pos == 28) { //second byte of analog 1
      anal1LSB = inByte;      
    }
   }
   //nss.print("anal1LSB = ");
   //nss.println(anal1LSB);
   int anal1Total = (anal1MSB * 256 + anal1LSB); //move MSB left and add to LSB
   //nss.print("anal1Total = ");
   //nss.println(anal1Total);
   temp = anal1Total / 20.0; //output should be 500mV @ 25 C
   temp = temp * 1.1922; //frig factor as Ithere is a difference in output
   nss.print("Temp = ");
   nss.println(temp);
   //nss.print("Total Bytes Received = ");
   //nss.println(pos);
}
//##############################################################################################
void setRemoteState() {
  //nss.println("void setRemoteState");

  //start byte
  Serial.write(0x7E); 

  //length
  Serial.write((byte)0x00);// Length MSB
  Serial.write(0x0F);//Length LSB 

  //frame id for sending an AT command
  Serial.write(0x17); 
 
  //Frame ID
  Serial.write((byte)0x01); 

  //64 bit destination
  Serial.write((byte)0x00);
  Serial.write((byte)0x13);
  Serial.write((byte)0xA2);
  Serial.write((byte)0x00);
  Serial.write((byte)0x40);
  Serial.write((byte)0x6A);
  Serial.write((byte)0x4E);
  Serial.write((byte)0xE6); 

  //16 bit of recipient or 0xFFFE if unknown
  Serial.write(0xFF);
  Serial.write(0xFE); 

  //0x02 to apply changes immediately on remote
  Serial.write(0x02); 

  //command name in ASCII characters
  Serial.write(0x49);
  Serial.write(0x53);

  //checksum is all bytes after length bytes 
  long sum = 0x17 + 0x01 + 0x13 + 0xA2 + 0x40 + 0x6A + 0x4E + 0xE6 + 0xFF + 0xFE + 0x02 + 0x49 + 0x53;

  Serial.write(0xFF - (sum & 0xFF));
  //nss.print("sum = ");
  //nss.println(sum, HEX);
  //byte checksum = (0xFF -(sum & 0xFF));
  //nss.print("Checksum = ");
  //nss.println(checksum, HEX); 
}