This is the solution that I posed to my senior design in Biomedical Engineering class (BME 440).  Over the last few weeks we covered basic Arduino programming (e.g. debounced toggle, DHT sensor), we did some basic ZigBee communication (AT mode).  The final project was to build a wireless Humidity, Temperature sensor that can transmit the data to a central computer. Above you can see the wiring to connect the humidity sensor DHT22 (see Adafruit’s tutorial) to the Arduino/Xbee Shield.  For this solution we configured the XBee S2’s to “ZigBee End Device API” with AP = 2 (escape enabled).  The central computer is connected to the Network coordinator XBee (“ZigBee Coordinator API AP=1).  The Arduino code uses the XBee-Arduino library and the Adafruit DHT library.  The python code is using the python-Xbee library.




untitled

/**
 * Copyright 2012, Helmut Strey
 *
 * This is an Arduino sketch that reads the humidity and temperature
 * from a DHT 22 sensor and transmits it using a ZigBee RF module.
 * It combines two example sketches that came from the XBee-Arduino library: Series2_Tx
 * and DHTtester from the adafruit DHT arduino library.
 * *
 * HumindityTempZigBee is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see http://www.gnu.org/licenses
 */
 
#include "XBee.h"
#include "DHT.h"
 
#define DHTPIN 2     // data pin of the DHT sensor
 
// Uncomment whatever type you're using!
//#define DHTTYPE DHT11   // DHT 11 
#define DHTTYPE DHT22   // DHT 22  (AM2302)
//#define DHTTYPE DHT21   // DHT 21 (AM2301)
 
// Connect pin 1 (on the left) of the sensor to +5V
// Connect pin 2 of the sensor to whatever your DHTPIN is
// Connect pin 4 (on the right) of the sensor to GROUND
// Connect a 10K resistor from pin 2 (data) to pin 1 (power) of the sensor
 
DHT dht(DHTPIN, DHTTYPE);
 
/*
This example is for Series 2 XBee
 Sends a ZB TX request with the value of analogRead(pin5) and checks the status response for success
*/
 
// create the XBee object
XBee xbee = XBee();
 
// we are going to send two floats of 4 bytes each
uint8_t payload[8] = { 0, 0, 0, 0, 0, 0, 0, 0};
 
// union to convery float to byte string
union u_tag {
    uint8_t b[4];
    float fval;
} u;
 
 
// SH + SL Address of receiving XBee
XBeeAddress64 addr64 = XBeeAddress64(0x0013a200, 0x406F4973);
ZBTxRequest zbTx = ZBTxRequest(addr64, payload, sizeof(payload));
ZBTxStatusResponse txStatus = ZBTxStatusResponse();
 
int statusLed = 13;
int errorLed = 13;
 
void flashLed(int pin, int times, int wait) {
 
  for (int i = 0; i < times; i++) {
    digitalWrite(pin, HIGH);
    delay(wait);
    digitalWrite(pin, LOW);
 
    if (i + 1 < times) {
      delay(wait);
    }
  }
}
 
void setup() {
  pinMode(statusLed, OUTPUT);
  pinMode(errorLed, OUTPUT);
  dht.begin();
  xbee.begin(9600);
}
 
void loop() {
  // Reading temperature or humidity takes about 250 milliseconds!
  // Sensor readings may also be up to 2 seconds 'old' (its a very slow sensor)
  float h = dht.readHumidity();
  float t = dht.readTemperature();
 
  // check if returns are valid, if they are NaN (not a number) then something went wrong!
  if (!isnan(t) && !isnan(h)) {
     
    // convert humidity into a byte array and copy it into the payload array
    u.fval = h;
    for (int i=0;i<4;i++){
      payload[i]=u.b[i];
    }
     
    // same for the temperature
    u.fval = t;
    for (int i=0;i<4;i++){
      payload[i+4]=u.b[i];
    }
     
    xbee.send(zbTx);
 
    // flash TX indicator
    flashLed(statusLed, 1, 100);
 
    // after sending a tx request, we expect a status response
    // wait up to half second for the status response
    if (xbee.readPacket(500)) {
      // got a response!
 
      // should be a znet tx status             
      if (xbee.getResponse().getApiId() == ZB_TX_STATUS_RESPONSE) {
        xbee.getResponse().getZBTxStatusResponse(txStatus);
 
        // get the delivery status, the fifth byte
        if (txStatus.getDeliveryStatus() == SUCCESS) {
          // success.  time to celebrate
          flashLed(statusLed, 5, 50);
        } else {
          // the remote XBee did not receive our packet. is it powered on?
          flashLed(errorLed, 3, 500);
        }
      }
    } else if (xbee.getResponse().isError()) {
      //nss.print("Error reading packet.  Error code: ");  
      //nss.println(xbee.getResponse().getErrorCode());
    } else {
      // local XBee did not provide a timely TX Status Response -- should not happen
      flashLed(errorLed, 2, 50);
    }
  }
  delay(1000);
}


Below is my python script that I used to receive the data.




untitled

#! /usr/bin/python
 
"""
HumidityTempZigBee.py
 
Copyright 2012, Helmut Strey
 
This is a python script that receives and outputs the humidity and temperature
that was wirelessly transmitted from a DHT 22 / ZigBee RF module.
 
HumindityTempZigBee is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
 
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.
 
You should have received a copy of the GNU General Public License
along with this program.  If not, see http://www.gnu.org/licenses/.
 
"""
 
from xbee import ZigBee
import serial
import struct
 
PORT = '/dev/tty.usbserial-AE01CQ5N'
BAUD_RATE = 9600
 
def hex(bindata):
    return ''.join('%02x' % ord(byte) for byte in bindata)
 
# Open serial port
ser = serial.Serial(PORT, BAUD_RATE)
 
# Create API object
xbee = ZigBee(ser,escaped=True)
 
# Continuously read and print packets
while True:
    try:
        response = xbee.wait_read_frame()
        sa = hex(response['source_addr_long'][4:])
        rf = hex(response['rf_data'])
        datalength=len(rf)
        # if datalength is compatible with two floats
        # then unpack the 4 byte chunks into floats
        if datalength==16:
            h=struct.unpack('f',response['rf_data'][0:4])[0]
            t=struct.unpack('f',response['rf_data'][4:])[0]
            print sa,' ',rf,' t=',t,'h=',h
        # if it is not two floats show me what I received
        else:
            print sa,' ',rf
    except KeyboardInterrupt:
        break
         
ser.close()


30 thoughts on “Sending Humidity and Temperature data with ZigBee

  1. Great tutorial. I wanted to ask you how can i modify the python script to run on another arduino?
    Thanks
    Jack

  2. hey lets say i want to send 4 float values would it be correct if i do it the following way :

    // we are going to send 4 floats of 4 bytes each
    uint8_t payload[16] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
    //value 1
    u.fval = h;
    for (int i=0;i<4;i++){
    payload[i]=u.b[i];
    }
    // value 2
    u.fval = t;
    for (int i=0;i<4;i++){
    payload[i+4]=u.b[i];
    }

    //value 3
    u.fval = value3;
    for (int i=0;i<4;i++){
    payload[i+8]=u.b[i];
    }
    //value4
    u.fval = value4;
    for (int i=0;i<4;i++){
    payload[i+12]=u.b[i];
    }

    xbee.send(zbTx);

  3. I get an error if the payload is not a rf_data packet. How do you ensure that only ‘rf’ packets are sent or get parsed?

    {’sourceaddrlong’: ‘x00x13xa2x00@xcaxb4x13’, ‘sourceaddr’: ‘xa7xd1’, ‘id’: ‘rxiodatalong_addr’, ‘samples’: [{’dio-0′: True}], ‘options’: ‘A’}

    Traceback (most recent call last):
    File "C:Python27motiondetectorv4", line 31, in <module>
    rf = hex(response[‘rf
    data’])
    KeyError: ‘rf_data’
    >>>

  4. for the newbies. I had to modify the setup() routine for mine to work…
    void setup() {
    pinMode(statusLed, OUTPUT);
    pinMode(errorLed, OUTPUT);
    dht.begin();
    Serial.begin(9600);
    }

    used Serial.begin(9600) instead of xbee.begin(9600) and that worked

  5. Hello,
    I copied your codes and i got no matching function for xbee.begin(9600);
    Do you have any idea why?

    Thanks

  6. Hi, I managed to send the DHT22 data for temperature, relative humidity and heat index using xbee and arduino. But I couldnt received the heat index value with xbee and raspberry pi. Kindly help. Thank you.

  7. no matching function for call to ‘XBee::begin(int)’
    this is what an error shown when i try to verify the code. plss any one tell why and also how to rectify it

  8. The Arduino and Python codes are working fine but the communication is not working. I am not getting any data from the Arduino to the Raspberry Pi. It seems that it is stuck on the Python’s response=xbee.wait_read_frame(). Any idea why this might be?
    I have configured the XBee S2’s as mentioned.

    • Simply because you are not reciving any frame this is my conclusion because i had the same problem i changed the DH and DL of my end device with xctu and every things work fine

      • I flip-flopped the DL and MY values of the XBees but it is still not working. I also made sure that the XBees are working by connecting both of them to the computer and by sending messages via the serial console.

  9. Hello every one i followed your tutorial i did the same thing i configured the two module with the correct mode but there is no communication between them
    i tried something else i configured the Xbee connected to the arduino in AT mode everything worked fine except the frame recived by the coordinator here is what i recive as a payload
    What i try to send is : HI
    uint8_t data[] = {’H’,’I’};

    this is what the coordinator recive
    ASCII : ~}3¢AlÁÿþHI7

    i would like to know what is the issue thank you

  10. How do I add another end device to the code, would it be the same only that in the coordinator code I add both devices or how?

Leave a Reply

Your email address will not be published. Required fields are marked *