Sending data from DHT11 to Xively using Xbees [SOLVED]

Hello,

I am trying to send temperature and humidity data from a DHT11 sensor between two Arduino Mega 2560’s using Xbees. The code for the transmitter is as follows

#include "DHT.h"
#define DHTPIN 2     
#define DHTTYPE DHT11   
DHT dht(DHTPIN, DHTTYPE);

void setup()
{
Serial.begin(9600);
}

void loop()
{

float h = dht.readHumidity();
float t = dht.readTemperature();

Serial.print("<T:");
Serial.print(t); 
Serial.print(">");

delay(2000);

Serial.print("<H:");
Serial.print(h); 
Serial.print(">");

delay(2000);
}

The code for the receiving Arduino is as follows:-

#include <SPI.h>
#include <Ethernet.h>
#include <HttpClient.h>
#include <Xively.h>


// MAC address for your Ethernet shield
byte mac[] = { mac address };
int hum;
int temp;
char inData[24]; // for reading serial from tx
byte index;  // for reading serial from tx
boolean started = false; // for reading serial from tx
boolean ended  = false; // for reading serial from tx

// Your Xively key to let you upload data
char xivelyKey[] = "xivelykey";

// Analog pin which we're monitoring (0 and 1 are used by the Ethernet shield)


// Define the strings for our datastream IDs
char sensorId[] = "humidity";
char sensorId2[] = "temperature";
const int bufferSize = 140;
char bufferValue[bufferSize]; // enough space to store the string we're going to send
XivelyDatastream datastreams[] = {
  XivelyDatastream(sensorId, strlen(sensorId), DATASTREAM_FLOAT),
  XivelyDatastream(sensorId2, strlen(sensorId2), DATASTREAM_FLOAT),
 
};
// Finally, wrap the datastreams into a feed
XivelyFeed feed(xxxxxx, datastreams, 2);/* number of datastreams */

EthernetClient client;
XivelyClient xivelyclient(client);


void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  
  Serial.println("Starting multiple datastream upload to Xively...");
  Serial.println();

  while (Ethernet.begin(mac) != 1)
  {
    Serial.println("Error getting IP address via DHCP, trying again...");
    delay(15000);
  }
}

void loop() {
 
 //start of code to read from transmitter
 while(Serial.available() > 0)
  {
	char aChar = Serial.read();
	if(aChar == '<')
	{
	    started = true;
	    index = 0;
	    inData[index] = '\0';
	}
	else if(aChar == '>')
	{
	    ended = true;
	}
	else if(started)
	{
	    inData[index] = aChar;
	    index++;
	    inData[index] = ',';
	}
  }

  if(started && ended)
  {
	// Use the value
	if(inData[0] == 'T')
	{
	   inData[0] = ' ';
           int temp = atoi(inData);
           Serial.println(" ");
	   Serial.print("Temp:");
           Serial.print(inData);
           Serial.print("C");
           Serial.println(" ");
         
	}
	else if(inData[0] == 'H')
     {
	   inData[0] = ' ';
           int hum = atoi(inData); 
	   Serial.println(" ");
           Serial.print("Humidity:");
           Serial.print(inData);
           Serial.print("%");
           Serial.println(" ");
           
     }

	started = false;
	ended = false;

	index = 0;
	inData[index] = '\0';
  }
  
  //end of code to read from transmitter

  datastreams[0].setFloat(temp);
  datastreams[1].setFloat(hum);
 
 
 
  Serial.print("Read sensor value temp ");
  Serial.println(datastreams[0].getFloat());
  Serial.print("Read sensor value hum ");
  Serial.println(datastreams[1].getFloat());
 

  Serial.println("Uploading it to Xively");
  int ret = xivelyclient.put(feed, xivelyKey);
  Serial.print("xivelyclient.put returned ");
  Serial.println(ret);

  Serial.println();
    
  delay(15000);
}

I can send the data to Xively directly from an Arduino ok and I can send and receive the temperature and humidity data between the two Arduino’s via the Xbees ok but I can’t seem to integrate the serial communication between the Arduino’s with Xively. Whenever I try cannot get the temperature and humidity readings. If someone could have a look at my code and suggest where I am going wrong that would be most appreciated.

Kind Regards

The network code should only be called when started==true && ended == true;
If I see it correctly now every loop it tries t send the data to Xively.

you can improve your code by defining separate function for separate steps.

void handleINcomingSerial()
{
  //start of code to read from transmitter
  while(Serial.available() > 0)
  {
    char aChar = Serial.read();
    if(aChar == '<')
    {
      started = true;
      index = 0;
      inData[index] = '\0';
    }
    else if(aChar == '>')
    {
      ended = true;
    }
    else if(started)
    {
      inData[index] = aChar;
      index++;
      inData[index] = ',';
    }
  }  
}

void printValues()
{
  // Use the value
  if(inData[0] == 'T')
  {
    inData[0] = ' ';
    int temp = atoi(inData);
    Serial.println(" ");
    Serial.print("Temp:");
    Serial.print(inData);
    Serial.print("C");
    Serial.println(" ");
  }
  else if(inData[0] == 'H')
  {
    inData[0] = ' ';
    int hum = atoi(inData); 
    Serial.println(" ");
    Serial.print("Humidity:");
    Serial.print(inData);
    Serial.print("%");
    Serial.println(" ");
  }
}

void sendoToXively()
{
  datastreams[0].setFloat(temp);
  datastreams[1].setFloat(hum);
  
  Serial.print("Read sensor value temp ");
  Serial.println(datastreams[0].getFloat());
  Serial.print("Read sensor value hum ");
  Serial.println(datastreams[1].getFloat());


  Serial.println("Uploading it to Xively");
  int ret = xivelyclient.put(feed, xivelyKey);
  Serial.print("xivelyclient.put returned ");
  Serial.println(ret);

  Serial.println();
}


void loop() 
{
  handleIncomingSerial();



  if(started && ended)
  {
    printValues();
    
    sendoToXively();

    started = false;
    ended = false;
    index = 0;
    inData[index] = '\0';
  }

  delay(15000);
}

Thank you Robtillaart!

I will try your suggestions later on today and will report back...

Hi Rob and others.

I have modified the code as you suggested however still no luck. I cannot seem to get the temperature and humidity values to be read into the datastreams for Xively. Here is the code I am now using.

#include <SPI.h>
#include <Ethernet.h>
#include <HttpClient.h>
#include <Xively.h>



// MAC address for your Ethernet shield
byte mac[] = { xxxxxx };

char inData[24]; // for reading serial from tx
byte index;  // for reading serial from tx
boolean started = false; // for reading serial from tx
boolean ended  = false; // for reading serial from tx

// Your Xively key to let you upload data
char xivelyKey[] = "xxxxx";

// Analog pin which we're monitoring (0 and 1 are used by the Ethernet shield)
//int sensorPin = 2;

// Define the strings for our datastream IDs
char sensorId[] = "humidity";
char sensorId2[] = "temperature";

const int bufferSize = 140;
char bufferValue[bufferSize]; // enough space to store the string we're going to send
XivelyDatastream datastreams[] = {
  XivelyDatastream(sensorId, strlen(sensorId), DATASTREAM_FLOAT),
  XivelyDatastream(sensorId2, strlen(sensorId2), DATASTREAM_FLOAT),

};
// Finally, wrap the datastreams into a feed
XivelyFeed feed(xxxxxx, datastreams, 2 /* number of datastreams */);

EthernetClient client;
XivelyClient xivelyclient(client);


void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);

  Serial.println("Starting multiple datastream upload to Xively...");
  Serial.println();

  while (Ethernet.begin(mac) != 1)
  {
    Serial.println("Error getting IP address via DHCP, trying again...");
    delay(15000);
  }
}


 void handleINcomingSerial()
{

//start of code to read from transmitter
while(Serial.available() > 0)
  {
    char aChar = Serial.read();
    if(aChar == '<')
    {
      started = true;
      index = 0;
      inData[index] = '\0';
    }
    else if(aChar == '>')
    {
      ended = true;
    }
    else if(started)
    {
      inData[index] = aChar;
      index++;
      inData[index] = ',';
    }
  }  
}

void printValues()
{
  // Use the value
  if(inData[0] == 'T')
  {
    inData[0] = ' ';
    int temp = atoi(inData);
    Serial.println(" ");
    Serial.print("Temp:");
    Serial.print(inData);
    Serial.print("C");
    Serial.println(" ");
  }
  else if(inData[0] == 'H')
  {
    inData[0] = ' ';
    int hum = atoi(inData); 
    Serial.println(" ");
    Serial.print("Humidity:");
    Serial.print(inData);
    Serial.print("%");
    Serial.println(" ");
  }
}


void sendoToXively()
{
  float t = temp;  //already in tx code
  float h = hum;   // already in tx code

  
  datastreams[0].setFloat(temp);
  datastreams[1].setFloat(hum);
  
  Serial.print("Read sensor value temp ");
  Serial.println(datastreams[0].getFloat());
  Serial.print("Read sensor value hum ");
  Serial.println(datastreams[1].getFloat());


  Serial.println("Uploading it to Xively");
  int ret = xivelyclient.put(feed, xivelyKey);
  Serial.print("xivelyclient.put returned ");
  Serial.println(ret);

  Serial.println();
}


void loop() 
{
  handleINcomingSerial();



  if(started && ended)
  {
    printValues();
    
    sendoToXively();

    started = false;
    ended = false;
    index = 0;
    inData[index] = '\0';
  }

  delay(15000);
}

When I compile this code I get a “temp is not definded in this scope” error message. If I define “temp” and “hum” as global variables the sketch then compiles and runs ok but I get 0 as values for temperature and humidity so I suspect the values are not getting into the “sendoToXively” function.

I’m sure I am doing something wrong but I hope another set of eyes could spot my error!

Many thanks,

Steve

1) can you try to read the sensor temp and hum and send it to serial.

If you always get 0 it might be that the Xively stream sees this as an end of string char (guess)

2) if you place dummy variables in the stream e.g. 42% does that work?

Thanks again Rob, I will follow up on your suggestions and will post my results.

When I compile this code I get a "temp is not definded in this scope" error message.

What scope are they defined in?

If I define "temp" and "hum" as global variables the sketch then compiles and runs ok but I get 0 as values for temperature and humidity

Do you still have the local variables of the same name?

Why are you sending temperature and humidity as floats and then converting them to ints?

Thanks for those suggestions and questions Paul, I will follow them through as I still haven't solved the problem but am determined to sort it out.

I am very pleased to say that I have changed the reciever sketch and can now send temperature and humidity readings to Xively via Xbees (Pro S1) .

The code below is my latest version of the reciever code and although very clumsy it works for the moment. Using Serial.parse() and making sure my coding syntax, particularly the placement of curly brackets was correct seemed to help. However I have learned much and hope to write a more efficient version soon.

Next step is to test the range of the XBees. Am hoping to get about 500 metres, line of sight, outdoors.

#include <SPI.h>
#include <Ethernet.h>
#include <HttpClient.h>
#include <Xively.h>

unsigned long lastConnectionTime = 0; // last time we connected to Xively
const unsigned long connectionInterval = 15000; // delay between connecting to Xively in milliseconds


// MAC address for your Ethernet shield
byte mac[] = { 
  XXXXXXXXXXX };

char inData[24]; // for reading serial from tx
byte index;  // for reading serial from tx
boolean started = false; // for reading serial from tx
boolean ended  = false; // for reading serial from tx

// Your Xively key to let you upload data
char xivelyKey[] = "XXXXXXXXXXXXXXXXXXX";



// Define the strings for our datastream IDs

char dht11temp[] = "temperature";
char dht11hum[] = "humidity";

const int bufferSize = 140;
char bufferValue[bufferSize]; // enough space to store the string we're going to send
XivelyDatastream datastreams[] = {
  XivelyDatastream(dht11temp, strlen(dht11temp), DATASTREAM_FLOAT),
 XivelyDatastream(dht11hum, strlen(dht11hum), DATASTREAM_FLOAT),
 
  
};

XivelyFeed feed(XXXXXXXX, datastreams, 2 /* number of datastreams */);

EthernetClient client;
XivelyClient xivelyclient(client);


void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);

  Serial.println("Starting multiple datastream upload to Xively...");
  Serial.println();

  while (Ethernet.begin(mac) != 1)
  {
    Serial.println("Error getting IP address via DHCP, trying again...");
    delay(15000);
  }
}

void loop() 
{
  // main program loop 
if (millis() - lastConnectionTime > connectionInterval) 
{ 
  Serial.flush(); 
  
  while (Serial.available() == 0); 
{ 
  char ch = Serial.read(); 
  if(ch == 'T') // Wait for the capital T.  
{ 

long t = Serial.parseInt(); //Temperature

datastreams[0].setFloat(t); // The maths is there to convert mV into V. 
Serial.print("Read Temperature "); 
Serial.println(datastreams[0].getFloat()); 



   Serial.println("Uploading it to Xively");
   int ret = xivelyclient.put(feed, xivelyKey);
   Serial.print("xivelyclient.put returned ");
   Serial.println(ret);


   
   
Serial.println(); 

lastConnectionTime = millis(); 
  }
  else if (ch == 'H')
  {
  long h = Serial.parseInt(); //Humidity

datastreams[1].setFloat(h); // The maths is there to convert mV into V. 
Serial.print("Read Humidity "); 
Serial.println(datastreams[1].getFloat()); 



   Serial.println("Uploading it to Xively");
   int ret = xivelyclient.put(feed, xivelyKey);
   Serial.print("xivelyclient.put returned ");
   Serial.println(ret);
   
   Serial.println(); 

lastConnectionTime = millis();
  }
}
}
}