I am using an RFBee in a XBee Carrier to measure temperature and humidity (via a Grove DHT11 module) and soil moisture via a homemade resistive probe and send a measurement to a second RFBee connected via a XBee Shield to a Freetronics EtherTen board. I am using the “RFbee firmware for Arduino 1.0(new)” RFBee firmware from the RFBee wiki page on both RFBees, but have modified the code on the RFBee in the XBee Carrier in order to connect with the sensors.
The code I am using is as follows
// Use to send temperature and humidty measurements from a DHT11 sensor
// using a RFBee in a Grove Carrier
// Note DHT11 sensor needs to be connected to D5/D6 grove connector
// XBee Carrier
// Pins
// When using an RFBee, the following pinouts apply for using the arduino IDE
// Pin 5 is the Grove connector for I/O - Yellow wire
// Pin 6 is the Grove connector for I/O - White wire
// Note: you can use the x2 Grove cable with the white and yellow wires swapped on one to access both I/O.
// Pin 16 may need to be driven low to provide enough power to the I/O Grove [via mosfet]
// Pin 17 may need to be driven low to provide enough power to the I2C Grove [via mosfet]
// Compile using
// Arduino Pro or Pro Mini (3.3v, 8MHz) w/ATmega168
#define ENABLE_SERIAL true
#define ENABLE_HEADER false
#define ENABLE_RFBEE true
#define ENABLE_DHT11 true
#define ENABLE_SEND_DHT11_CHK false
#define ENABLE_MOISTURE true
#define ALLOW_RECEIVE false
#define ENABLE_MEMORY_REPORTING true
#define ENABLE_STRING_RESERVE false
#define SEND_EXTENDED_HEADER false
#define ENABLE_TEST_RFBEE false
#if ENABLE_TEST_RFBEE
#undef ENABLE_RFBEE
#define ENABLE_RFBEE true
#undef ENABLE_DHT11
#define ENABLE_DHT11 true
#undef ENABLE_MOISTURE
#define ENABLE_MOISTURE false
#undef ALLOW_RECEIVE
#define ALLOW_RECEIVE false
#endif
#if ENABLE_MEMORY_REPORTING
#include <MemoryFree.h>
#endif
#if ENABLE_RFBEE
#include <EEPROM.h>
#include <RFBeeSendRev.h>
#include <RFBeeCore.h>
//#include <Sleep_n0m1.h>
#define power_adc_enable() (PRR &= (uint8_t)~(1 << PRADC))
#define power_adc_disable() (PRR |= (uint8_t)(1 << PRADC))
#define power_spi_enable() (PRR &= (uint8_t)~(1 << PRSPI))
#define power_spi_disable() (PRR |= (uint8_t)(1 << PRSPI))
#define power_usart0_enable() (PRR &= (uint8_t)~(1 << PRUSART0))
#define power_usart0_disable() (PRR |= (uint8_t)(1 << PRUSART0))
#define power_timer0_enable() (PRR &= (uint8_t)~(1 << PRTIM0))
#define power_timer0_disable() (PRR |= (uint8_t)(1 << PRTIM0))
#define power_timer1_enable() (PRR &= (uint8_t)~(1 << PRTIM1))
#define power_timer1_disable() (PRR |= (uint8_t)(1 << PRTIM1))
#define power_timer2_enable() (PRR &= (uint8_t)~(1 << PRTIM2))
#define power_timer2_disable() (PRR |= (uint8_t)(1 << PRTIM2))
#define power_twi_enable() (PRR &= (uint8_t)~(1 << PRTWI))
#define power_twi_disable() (PRR |= (uint8_t)(1 << PRTWI))
#if ALLOW_RECEIVE
unsigned char dtaUart[100];
unsigned char dtaUartLen = 0;
bool stringComplete = false; // if get data
unsigned char rxData1[200]; // data len
unsigned char len1; // len
unsigned char srcAddress1;
unsigned char destAddress1;
char rssi1;
unsigned char lqi1;
int result1;
#endif
#endif
#if ENABLE_DHT11
#include <dht11.h>
dht11 DHT11;
const int DHT11_PIN = 5;
#endif
#if ENABLE_MOISTURE
// code from gardenbot
// analogue pin for measurement
const int MOISTURE_SENSOR_PIN = A5;
// digital pins for sensor potential
const int DIVIDER_TOP = 7;
const int DIVIDER_BOTTOM = 8;
// Calibration parameters
// value at pin MOISTURE_PIN when open circuit (no moisture)
const int NO_MOISTURE = 0;
// value at pin MOISTURE_PIN when sensor submerged in water (full moisture)
const int FULL_MOISTURE = 990;
// time for capacitance to settle (milliseconds)
const int CAP_TIME = 1000;
void setSensorPolarity(boolean flip)
{
if(flip)
{
digitalWrite(DIVIDER_TOP, HIGH);
digitalWrite(DIVIDER_BOTTOM, LOW);
}
else
{
digitalWrite(DIVIDER_TOP, LOW);
digitalWrite(DIVIDER_BOTTOM, HIGH);
}
}
int getSoilMoistureLevel()
{
int reading; // a value between 0 and 1023
#if ENABLE_RFBEE
// enable analogue to digital reading
power_adc_enable();
#endif
setSensorPolarity(true);
delay(CAP_TIME);
int val1 = analogRead(MOISTURE_SENSOR_PIN);
#if ENABLE_SERIAL
Serial.print("val1: ");
Serial.println(val1);
#endif
delay(CAP_TIME);
setSensorPolarity(false);
delay(CAP_TIME);
// invert the reading
int val2 = 1023 - analogRead(MOISTURE_SENSOR_PIN);
#if ENABLE_SERIAL
Serial.print("val2: ");
Serial.println(val2);
#endif
// stop the current
digitalWrite(DIVIDER_TOP,LOW);
digitalWrite(DIVIDER_BOTTOM,LOW);
#if ENABLE_RFBEE
// disable analogue to digital reading
power_adc_disable();
#endif
reading = (val1 + val2) / 2;
#if ENABLE_SERIAL
Serial.print("Soil moisture raw reading is ");
Serial.println(reading);
#endif
return reading;
}
#endif
const char DATA_PREFIX = '$';
const char DATA_SEPARATOR = ',';
const char SYSTEM_REF = 'M';
#if ENABLE_STRING_RESERVE
const int MAX_DATA_SIZE = 32;
const int MAX_HEADER_SIZE = 16;
#endif
//const int MAX_TX_SIZE = 32;
const unsigned long iamaliveInterval = 10000;
static unsigned long iamalivePrev = 0;
const unsigned long measurementInterval = 30000UL; // take a measurement every 30 seconds
static unsigned long measurementPrev = 0;
static unsigned long measurementCount = 0;
/*--------------------------------------------------------------------------------------
setup()
Called by the Arduino framework once, before the main loop begins
--------------------------------------------------------------------------------------*/
void setup()
{
#if ENABLE_SERIAL
Serial.begin(38400);
#endif
#if ENABLE_SERIAL && ENABLE_MEMORY_REPORTING
Serial.println("Begin setup()");
Serial.print("freeMemory()= ");
Serial.println(freeMemory());
#endif
#if ENABLE_RFBEE
RFBEE.init();
// power_adc_disable();
// power_timer1_disable();
// power_timer2_disable();
// power_twi_disable();
#endif
#if ENABLE_SERIAL
Serial.println("RFBee Grove Carrier Remote Module");
#if ENABLE_DHT11
Serial.print("DHT11 library version ");
Serial.println(DHT11LIB_VERSION);
#endif
#endif
#if ENABLE_MOISTURE
pinMode(MOISTURE_SENSOR_PIN, INPUT);
pinMode(DIVIDER_TOP, OUTPUT);
pinMode(DIVIDER_BOTTOM, OUTPUT);
#endif
#if ENABLE_SERIAL && ENABLE_MEMORY_REPORTING
Serial.println("End setup()");
Serial.print("freeMemory()= ");
Serial.println(freeMemory());
#endif
}
/*--------------------------------------------------------------------------------------
loop()
Arduino main loop
--------------------------------------------------------------------------------------*/
void loop()
{
// at beginning of loop get time program has been running
unsigned long runTime = millis();
// Check to see if it is time to get another temperature reading
if ( runTime - measurementPrev > measurementInterval )
{
measurementPrev = runTime;
measurementCount++;
#if ENABLE_SERIAL
Serial.print("\n\n");
Serial.print("Measurement ");
Serial.print(measurementCount);
Serial.print(" at ");
Serial.print((long)runTime/1000);
Serial.print(" seconds");
Serial.println();
#endif
#if ENABLE_SERIAL && ENABLE_MEMORY_REPORTING
Serial.print("freeMemory()= ");
Serial.println(freeMemory());
#endif
#if ENABLE_DHT11
// read DHT11 data
int chk = DHT11.read(DHT11_PIN);
#if ENABLE_SERIAL
Serial.print("DHT reading from pin ");
Serial.println(DHT11_PIN);
Serial.print("DHT status: ");
switch (chk)
{
case 0:
Serial.println("OK");
break;
case -1:
Serial.println("Checksum error");
break;
case -2:
Serial.println("Time out error");
break;
default:
Serial.println("Unknown error");
break;
}
#endif
#if ENABLE_SERIAL
Serial.print("Humidity (%): ");
Serial.println((int)DHT11.humidity);
Serial.print("Temperature (oC): ");
Serial.println((int)DHT11.temperature);
#endif
#endif
// create data string
String dataString = "";
#if ENABLE_STRING_RESERVE
dataString.reserve(MAX_DATA_SIZE); // reserve MAX_DATA_SIZE bytes for the dataString
#endif
int dataFieldCount = 0;
#if !ENABLE_HEADER
dataString += DATA_PREFIX;
dataString += DATA_SEPARATOR;
dataString += SYSTEM_REF;
dataString += DATA_SEPARATOR;
#endif
#if ENABLE_DHT11
#if ENABLE_SEND_DHT11_CHK
dataString += chk;
dataString += DATA_SEPARATOR;
#endif
dataFieldCount++;
dataString += DHT11.temperature;
dataString += DATA_SEPARATOR;
dataFieldCount++;
dataString += DHT11.humidity;
dataString += DATA_SEPARATOR;
dataFieldCount++;
#endif
#if ENABLE_MOISTURE
dataString += getSoilMoistureLevel();
dataFieldCount++;
#endif
// dataString += '\n';
#if ENABLE_HEADER
// create header string (after dataString to include data length)
String headerString = "";
#if ENABLE_STRING_RESERVE
headerString.reserve(MAX_HEADER_SIZE); // reserve MAX_HEADER_SIZE bytes for the dataString
#endif
headerString += DATA_PREFIX;
headerString += DATA_SEPARATOR;
headerString += SYSTEM_REF;
headerString += DATA_SEPARATOR;
#if SEND_EXTENDED_HEADER
headerString += (int)(measurementInterval/1000);
headerString += DATA_SEPARATOR;
headerString += dataFieldCount;
headerString += DATA_SEPARATOR;
headerString += dataString.length();
headerString += DATA_SEPARATOR;
#endif
String txString = headerString + dataString;
int txStringLength = txString.length();
char txChar[txStringLength+1];
txString.toCharArray(txChar, sizeof(txChar));
#else
int txStringLength = dataString.length();
char txChar[txStringLength+1];
dataString.toCharArray(txChar, sizeof(txChar));
#endif
#if ENABLE_SERIAL
Serial.println("Measurement string:");
Serial.println(txChar);
#endif
#if ENABLE_SERIAL && ENABLE_MEMORY_REPORTING
Serial.print("freeMemory()= ");
Serial.println(freeMemory());
#endif
#if ENABLE_RFBEE
RFBEE.sendDta(txStringLength, (unsigned char *)txChar);
#endif
#if ENABLE_SERIAL
Serial.println("Data sent by RFBee");
#endif
#if ENABLE_SERIAL && ENABLE_MEMORY_REPORTING
Serial.print("freeMemory()= ");
Serial.println(freeMemory());
#endif
} // end if ( runTime - measurementPrev > measurementInterval )
#if ENABLE_RFBEE && ALLOW_RECEIVE
if(RFBEE.isDta())
{
result1=receiveData(rxData1, &len1, &srcAddress1, &destAddress1, (unsigned char *)&rssi1 , &lqi1);
Serial.println("Data received ...");
Serial.print("Length = ");
Serial.println(len1);
for(int i = 0; i< len1; i++)
{
Serial.write(rxData1[i]);
}
}
#endif
}
The issue I am having is that the RFBee in the XBee Carrier will work for a low number (< 30) of measurement loops and will then stop working. I have done a some debugging and found that the program appears to get stuck in an infinite loop within the
while(1)
statement, within the
transmitData
function as located in the RFBeeCore.cpp file.
I therefore wondered whether other people have had a similar issue or whether anyone could provide any suggestions to resolve the issue.
Many thanks in advance