Wireless humidity and temperature sensor
This project is a wireless zigbee based wireless temperature and humidity sensor.
This is a writeup on how I created this project to wirelessly send data from a temperature and humidity sensor.
It's not pretty, but it works. Here is a picture of the end product:
Click to enlarge
It's not going to be pretty, but it is pretty easy to put together. It took me about 8 hours to think out, assemble, and program.
I used the following parts:
The components get hooked up as follows:
Arduino:
Wired as follows:
Digital pins:
0 - to a jumper, then xbee pin 2
1 - to a jumper, then xbee pin 3
2 - LCD D6
3 - LCD D7
4 - nc
5 - hh10d output pin
6 - LCD D4
7 - LCD D5
8 - LCD Enable Pin
9 - LCD RS pin
Analog pins:
A4 - temp and humidity sensor SDA
A5 - temp and humidity sensor SCL
hh10d:
SDA - arduino pin a4
SDL - arduuino pin a5
FOUT - arduino pin 5
tmp102:
SDA - arduino pin a4
SDL - arduuino pin a5
ALT - nc
ADD0 - ground
xbee module:
1 - 3.3v
2 - first a jumpe, then arduino pin 0
3 - first a jumpe, then arduino pin 1
5 - to a 10k resistor to vcc and a button connected to ground
6 - input pin to the available led on the protoshield
10 - ground
I start by configuring the xbee modules.
I first gathered the addresses of my xbee modules. In my case, my values are:
router module:
0013A200 40627E7E
cordinator module:
0013A200 403045E1
Everything can be configured on the xbee modules via AT commands, but I already had a windows machine with a config utility on it, and I needed to upgrade the firmware on the modules, so I followed the following steps to configure my modules:
1. Download the config utility here:
http://www.digi.com/support/productdetl.jsp?pid=3352&osvid=57&s=316&tp=5&tp2=0
For the next steps, you will need the high and low addresses for your modules. Get them from the bottom of your modules. The bottom of the modules look like this:
In this case, the high and low address for this module are:
high - 0013A200
low - 40627E74
Program the xbee modules with these steps
1. plug the xbee module into the usb breakout board.
2. plug the breakout board into your computer
3. open x-ctu
4. select the correct serial port for your xbee module.
5. Select the "modem configuration" tab.
6. Read the modem parameters and firmware.
7. one of your modules is going to need to be a router, and one is going to need to be a coordinator.
Set up the router first. So, select "ZIGBEE ROUTER AT" from the "Function Set" dropdown
8. Set the pan ID to any number from 0 to FFFF will work. I like something small, like "21"
9. Place the high address of your coordinator into the "Destination High Address" field of this module.
10. Place the low address of your coordinator into the "Destination Low Address" field of this module.
11. Select the highest version number possible in the version number dropdown.
12. Program it.
Now, take this module and set it aside, we will be installing it in our sensor device later.
Repeat steps 1-12 for your coordinator module. Just change step 7 to add "ZIGBEE CORDINATOR AT" instead of the router at.
Also, step 9 and 10 will need you to put the router module's high and low address instead of the address from the coordinator.
great, so I mashed all of my components into my device like this:
I put my battries on the top under the lcd, with the lcd glued to the batteries.
You can see the rx and tx jumper header between the lcd and the zigbee module.
I put a 12 v coaxial connector in the case to allow for easy charging from 12 volts.
The code output looks like this:
offset is 7847
humidity reading device hh10d
Calibrating:
0 Freq: 0
Relitive humidity: 727
Converted temp is 27.69
Corrected temp is 22.69
Output is: Seconds since start, humidity, temp in Deg C,temp in Deg F
3.4,-6039,27.69,81.84
4.0,41,27.75,81.95
4.5,41,27.62,81.72
5.0,44,27.69,81.84
5.6,47,29.00,84.20
And here is all of the code, syntax highlighted by the cool little program found here:
http://www.palfrader.org/code2html/
This project is a wireless zigbee based wireless temperature and humidity sensor.
This is a writeup on how I created this project to wirelessly send data from a temperature and humidity sensor.
It's not pretty, but it works. Here is a picture of the end product:
![]() |
| From turtlebot-projects |
It's not going to be pretty, but it is pretty easy to put together. It took me about 8 hours to think out, assemble, and program.
I used the following parts:
- 2 xbee series 2 modules. Like this one: http://www.sparkfun.com/products/10415
- 1 xbee usb breakout board http://www.robotshop.com/parallax-breakout-board-for-xbee-module.html?utm_source=google&utm_medium=base&utm_campaign=jos
- 1 arduino protoshield http://www.sparkfun.com/products/7914
- 1 3.3 volt arduino pro http://www.sparkfun.com/products/9221
- 1 Stackable header pins for the arduino pro http://www.sparkfun.com/products/10007
- tmp102 temp sensor http://www.sparkfun.com/products/9418
- hh10d humidity sensor http://www.sparkfun.com/products/10239
- 1 ftdi breakout to program the arduino with http://www.sparkfun.com/products/9873
- 1 3.3 volt 2x8 lcd http://www.newhavendisplay.com/index.php?main_page=product_info&cPath=2_80&products_id=1908
- some number of batteries. I with with three lipo batteries that fit well in my case, and they are something that I can charge off of 12 volts. I got mine off of ebay, and do not have a link
- 1 A arduino project enclosure http://www.sparkfun.com/products/10088
- 1 little button for the xbe reset pin http://www.sparkfun.com/products/97
The components get hooked up as follows:
Arduino:
Wired as follows:
Digital pins:
0 - to a jumper, then xbee pin 2
1 - to a jumper, then xbee pin 3
2 - LCD D6
3 - LCD D7
4 - nc
5 - hh10d output pin
6 - LCD D4
7 - LCD D5
8 - LCD Enable Pin
9 - LCD RS pin
Analog pins:
A4 - temp and humidity sensor SDA
A5 - temp and humidity sensor SCL
hh10d:
SDA - arduino pin a4
SDL - arduuino pin a5
FOUT - arduino pin 5
tmp102:
SDA - arduino pin a4
SDL - arduuino pin a5
ALT - nc
ADD0 - ground
xbee module:
1 - 3.3v
2 - first a jumpe, then arduino pin 0
3 - first a jumpe, then arduino pin 1
5 - to a 10k resistor to vcc and a button connected to ground
6 - input pin to the available led on the protoshield
10 - ground
I start by configuring the xbee modules.
I first gathered the addresses of my xbee modules. In my case, my values are:
router module:
0013A200 40627E7E
cordinator module:
0013A200 403045E1
Everything can be configured on the xbee modules via AT commands, but I already had a windows machine with a config utility on it, and I needed to upgrade the firmware on the modules, so I followed the following steps to configure my modules:
1. Download the config utility here:
http://www.digi.com/support/productdetl.jsp?pid=3352&osvid=57&s=316&tp=5&tp2=0
For the next steps, you will need the high and low addresses for your modules. Get them from the bottom of your modules. The bottom of the modules look like this:
![]() |
| From turtlebot-projects |
In this case, the high and low address for this module are:
high - 0013A200
low - 40627E74
Program the xbee modules with these steps
1. plug the xbee module into the usb breakout board.
2. plug the breakout board into your computer
3. open x-ctu
4. select the correct serial port for your xbee module.
5. Select the "modem configuration" tab.
6. Read the modem parameters and firmware.
7. one of your modules is going to need to be a router, and one is going to need to be a coordinator.
Set up the router first. So, select "ZIGBEE ROUTER AT" from the "Function Set" dropdown
8. Set the pan ID to any number from 0 to FFFF will work. I like something small, like "21"
9. Place the high address of your coordinator into the "Destination High Address" field of this module.
10. Place the low address of your coordinator into the "Destination Low Address" field of this module.
11. Select the highest version number possible in the version number dropdown.
12. Program it.
Now, take this module and set it aside, we will be installing it in our sensor device later.
Repeat steps 1-12 for your coordinator module. Just change step 7 to add "ZIGBEE CORDINATOR AT" instead of the router at.
Also, step 9 and 10 will need you to put the router module's high and low address instead of the address from the coordinator.
great, so I mashed all of my components into my device like this:
![]() |
| From turtlebot-projects |
I put my battries on the top under the lcd, with the lcd glued to the batteries.
You can see the rx and tx jumper header between the lcd and the zigbee module.
I put a 12 v coaxial connector in the case to allow for easy charging from 12 volts.
The code output looks like this:
offset is 7847
humidity reading device hh10d
Calibrating:
0 Freq: 0
Relitive humidity: 727
Converted temp is 27.69
Corrected temp is 22.69
Output is: Seconds since start, humidity, temp in Deg C,temp in Deg F
3.4,-6039,27.69,81.84
4.0,41,27.75,81.95
4.5,41,27.62,81.72
5.0,44,27.69,81.84
5.6,47,29.00,84.20
And here is all of the code, syntax highlighted by the cool little program found here:
http://www.palfrader.org/code2html/
// humidity and temp transmitter with a lcd output. /* Michael Gregg Wired as follows: 0 - to a jumper, then xbee pin 2 1 - to a jumper, then xbee pin 3 2 - LCD D6 3 - LCD D7 4 - nc 5 - hh10d output pin 6 - LCD D4 7 - LCD D5 8 - LCD Enable Pin 9 - LCD RS pin A4 - temp and humidity sensor SDA A5 - temp and humidity sensor SCL Code based off of: http://tushev.org/articles/electronics/46-interfacing-hh10d-with-arduino http://www.arduino.cc/playground/Code/TMP102 http://www.arduino.cc/en/Tutorial/LiquidCrystal */ #include <FreqCounter.h> #include <Wire.h> #include <LiquidCrystal.h> #define TMP102_I2C_ADDRESS 72 LiquidCrystal lcd(8, 9, 6, 7, 2, 3); int freq, offset, sens, RH; char buff[30]; float convertedtemp, tempf; /* We then need to multiply our two bytes by a scaling factor, mentioned in the datasheet. */ float correctedtemp; unsigned long frq; int cnt,seconds,partialseconds; int pinLed=13; int val; /* an int is capable of storing two bytes, this is where we "chuck" the two bytes together. */ // arrays used to build custom characters byte UP[8] = // array to make an arrow pointing up { B00000, B00100, B01110, B11111, B00100, B00100, B00100, B00000 }; byte Down[8] = // array to make an arrow pointing down { B00000, B00100, B00100, B00100, B11111, B01110, B00100, B00000 }; void setup() { pinMode(pinLed, OUTPUT); lcd.createChar(0, UP); lcd.createChar(1, Down); lcd.begin(8, 2); lcd.setCursor(0, 0); lcd.print("hello "); lcd.setCursor(0, 1); lcd.print("World "); Wire.begin(); Serial.begin(9600); sens = i2cRead2bytes(81, 10); //Read sensitivity from EEPROM offset = i2cRead2bytes(81, 12); //Same for offset sprintf(buff, "sensitivity is %d", sens); Serial.println(buff); sprintf(buff, "offset is %d", offset); Serial.println(buff); Serial.println("humidity reading device hh10d"); Serial.println("Calibrating:"); FreqCounter::f_comp=10; // Cal Value / Calibrate with professional Freq Counter FreqCounter::start(500); // 100 ms Gate Time FreqCounter::start(500); // 100 ms Gate Time FreqCounter::f_comp=10; // Cal Value / Calibrate with professional Freq Counter FreqCounter::start(500); // 100 ms Gate Time while (FreqCounter::f_ready == 0) frq=FreqCounter::f_freq; Serial.print(cnt++); Serial.print(" Freq: "); Serial.println(frq); delay(20); digitalWrite(pinLed,!digitalRead(pinLed)); // blink Led //Calculate RH //frq = frq / 2; // for 8 mhz devices sampeling at 1 hz RH = (offset-frq)*sens/4096; //Sure, you can use int - depending on what do you need Serial.print("Relitive humidity: "); Serial.println(RH); getTemp102(); Serial.print("Converted temp is "); Serial.print("\t"); Serial.println(val*0.0625); Serial.print("Corrected temp is "); Serial.print("\t"); Serial.println(correctedtemp); Serial.println(); Serial.println("Output is: Seconds since start, humidity, temp in Deg C,temp in Deg F"); } void loop() { // wait if any serial is going on FreqCounter::f_comp=10; // Cal Value / Calibrate with professional Freq Counter FreqCounter::start(500); // 100 ms Gate Time while (FreqCounter::f_ready == 0) frq=FreqCounter::f_freq; //Serial.print(cnt++); //Serial.print(" Freq: "); //Serial.println(frq); delay(20); digitalWrite(pinLed,!digitalRead(pinLed)); // blink Led //Calculate RH //frq = frq / 2; // for 8 mhz devices sampeling at 1 hz RH = (offset-frq)*sens/4096; //Sure, you can use int - depending on what do you need getTemp102(); partialseconds = millis()/10; seconds=partialseconds / 10; partialseconds = partialseconds - ( seconds * 10 ); sprintf(buff,"%d.%d,%d,", seconds, partialseconds, RH); Serial.print(buff); Serial.print(convertedtemp); Serial.print(","); Serial.println(tempf); //Serial.println(millis()); lcd.setCursor(0, 0); lcd.print("Temp:"); lcd.print(tempf); lcd.print("F"); lcd.setCursor(0, 1); lcd.print("Humd:"); lcd.print(RH); lcd.print("%"); } int i2cRead2bytes(int deviceaddress, byte address) { // SET ADDRESS Wire.beginTransmission(deviceaddress); Wire.send(address); // address for sensitivity Wire.endTransmission(); // REQUEST RETURN VALUE Wire.requestFrom(deviceaddress, 2); // COLLECT RETURN VALUE int rv = 0; for (int c = 0; c < 2; c++ ) if (Wire.available()) rv = rv * 256 + Wire.receive(); return rv; } void getTemp102() { byte firstbyte, secondbyte; //these are the bytes we read from the TMP102 temperature registers /* Reset the register pointer (by default it is ready to read temperatures) You can alter it to a writeable register and alter some of the configuration - the sensor is capable of alerting you if the temperature is above or below a specified threshold. */ Wire.beginTransmission(TMP102_I2C_ADDRESS); //Say hi to the sensor. //Serial.println("done with wire begin"); Wire.send(0x00); Wire.endTransmission(); //Serial.println("done with wire send"); Wire.requestFrom(TMP102_I2C_ADDRESS, 2); Wire.endTransmission(); //Serial.println("firstbyte"); firstbyte = (Wire.receive()); /*read the TMP102 datasheet - here we read one byte from each of the temperature registers on the TMP102*/ secondbyte = (Wire.receive()); /*The first byte contains the most significant bits, and the second the less significant */ val = ((firstbyte) << 4); /* MSB */ val |= (secondbyte >> 4); /* LSB is ORed into the second 4 bits of our byte. Bitwise maths is a bit funky, but there's a good tutorial on the playground*/ convertedtemp = val*0.0625; correctedtemp = convertedtemp - 5; tempf = convertedtemp * 1.8 + 32; /* See the above note on overreading */ }


