Howdy guys.
I am working on communicating sensors data from a remote Xbee with a temp and humidity sensor, the SHT15.
I have communication through the XBees, I can send data when I have an arduino connected to the Xbee and computer with the ATmega removed using the hyperterm, XCTU and the arduino IDE serial monitor.
Here is the code for the transmitter:
int temperatureCommand = B00000011; // command used to read temperature
int humidityCommand = B00000101; // command used to read humidity
int clockPin = 2; // pin used for clock
int dataPin = 3; // pin used for data
int ack; // track acknowledgment for errors
int val;
float temperature;
float humidity;
void setup() {
Serial.begin(9600); // open serial at 9600 bps
}
void loop() {
// read the temperature and convert it to centigrades
sendCommandSHT(temperatureCommand, dataPin, clockPin);
waitForResultSHT(dataPin);
val = getData16SHT(dataPin, clockPin);
skipCrcSHT(dataPin, clockPin);
temperature = (((float)val * 0.01 - 40) * 1.8 + 32);
Serial.print("temperature: ");
Serial.print((long)temperature, DEC);
Serial.print('\n');
// read the humidity
sendCommandSHT(humidityCommand, dataPin, clockPin);
waitForResultSHT(dataPin);
val = getData16SHT(dataPin, clockPin);
skipCrcSHT(dataPin, clockPin);
humidity = -4.0 + 0.0405 * val + -0.0000028 * val * val;
Serial.print("humidity: ");
Serial.print((long)humidity, DEC);
Serial.print('\n');
delay(5000); // wait for 5 Minutes for next reading
}
// commands for reading/sending data to a SHTx sensor
int shiftIn(int dataPin, int clockPin, int numBits) {
int ret = 0;
for (int i=0; i<numBits; ++i) {
digitalWrite(clockPin, HIGH);
//delay(10); not needed :)
ret = ret*2 + digitalRead(dataPin);
digitalWrite(clockPin, LOW);
}
return(ret);
}
// send a command to the SHTx sensor
void sendCommandSHT(int command, int dataPin, int clockPin) {
int ack;
// transmission start
pinMode(dataPin, OUTPUT);
pinMode(clockPin, OUTPUT);
digitalWrite(dataPin, HIGH);
digitalWrite(clockPin, HIGH);
digitalWrite(dataPin, LOW);
digitalWrite(clockPin, LOW);
digitalWrite(clockPin, HIGH);
digitalWrite(dataPin, HIGH);
digitalWrite(clockPin, LOW);
// shift out the command (the 3 MSB are address and must be 000, the last 5 bits are the command)
shiftOut(dataPin, clockPin, MSBFIRST, command);
// verify we get the right ACK
digitalWrite(clockPin, HIGH);
pinMode(dataPin, INPUT);
ack = digitalRead(dataPin);
if (ack != LOW)
Serial.println("ACK error 0");
digitalWrite(clockPin, LOW);
ack = digitalRead(dataPin);
if (ack != HIGH)
Serial.println("ACK error 1");
}
// wait for the SHTx answer
void waitForResultSHT(int dataPin) {
int ack;
pinMode(dataPin, INPUT);
for(int i=0; i<100; ++i) {
delay(10);
ack = digitalRead(dataPin);
if (ack == LOW)
break;
}
if (ack == HIGH)
Serial.println("ACK error 2");
}
// get data from the SHTx sensor
int getData16SHT(int dataPin, int clockPin) {
int val;
// get the MSB (most significant bits)
pinMode(dataPin, INPUT);
pinMode(clockPin, OUTPUT);
val = shiftIn(dataPin, clockPin, 8);
val *= 256; // this is equivalent to val << 8;
// send the required ACK
pinMode(dataPin, OUTPUT);
digitalWrite(dataPin, HIGH);
digitalWrite(dataPin, LOW);
digitalWrite(clockPin, HIGH);
digitalWrite(clockPin, LOW);
// get the LSB (less significant bits)
pinMode(dataPin, INPUT);
val |= shiftIn(dataPin, clockPin, 8);
return val;
}
// skip CRC data from the SHTx sensor
void skipCrcSHT(int dataPin, int clockPin) {
pinMode(dataPin, OUTPUT);
pinMode(clockPin, OUTPUT);
digitalWrite(dataPin, HIGH);
digitalWrite(clockPin, HIGH);
digitalWrite(clockPin, LOW);
}
The code for the reciever is here:
#include <glcd.h>
#include "fonts/allFonts.h" // system and arial14 fonts are used
#include "bitmaps/allBitmaps.h" // all images in the bitmap dir
int inbytes = 0;
int x = 0;
void setup()
{
Serial.begin(9600);
GLCD.Init();
GLCD.ClearScreen();
GLCD.CursorTo(5,1);
GLCD.SelectFont(System5x7, BLACK);
}
void loop()
{
// when characters arrive over the serial port...
if (Serial.available()) {
// wait a bit for the entire message to arrive
delay(100);
// clear the screen
GLCD.ClearScreen();
// read all the available characters
while (Serial.available() > 0) {
inbytes = Serial.read();
// display each character to the LCD
GLCD.print(inbytes, BYTE);
}
}
}
Like i said, i can send as much data as i want when using a terminal program. But i cant get sensor data over.
My thoughts are that the terminal programs have some form of carriage return or other character that tells it serial data is done.
But i dont have this in the sensor code.
I had the recieving xbee power through a wall wort, and the transmitter through USB so i am going to try to power the transmitter through another wall wort.
my plans for this project is to connect multiple sensors to the transmitter that will read and store the values of the sensors,
send it over through XBEE to the reciever, which stores each sensor value and displays it on the LCD.
so far i am trying the one sensor to get a grasp of what i have to do with the other sensors.
A couple of thoughts on how i think this may be possible..
- Have the transmitter send a special byte corresponding to the sensor value it would send.
For example 00001111 for temp, 11110000 for humidity.
the receiver would check the first byte and store it in its spot.
or
- Have the transmitter format the data into an array of some sort, that when transmitted to the receiver, the arduino takes that array stores it and takes pieces of the array that contains the data of each sensor and puts it out on the LCD.
What are your guys thoughts on this?
I just need a push in the right direction, thanks guys.
-Erik