I seem to have hit a dead end trying to send some BMP085 pressure data to emonCMS
The Adafruit unified driver outputs temp and pressure data with 2 decimal points so I am likely to get at least 6 digits of info for pressure unless I clip these.
Using the emonTH sketch as a start I can:
1. Send the factory test sequence of info for both variables. Even if I use int32_t or long for pressure though I seem to run out of range and the numbers wrap around (yes, not a coder by training!)
2. Get the readings updating every 30 secs
3. Confirm the correct payload variables make it into the transmit function with a simple serial.print
But then nothing - I can see quite a few examples using the Jeelib BMP library but did not want to jump ship from Adafruit as I suspect the ongoing support is going to be better simply because of the extra number of bodies they have. I am also struggling a bit on the Jeelib BMP code as a lots of examples seem to remap the SDL/SCL pins.
I have also tried a couple of versions of the RF12 transmit code - no difference on either version.
Any thoughts on where I am going wrong would be gratefully accepted - some code extracts below and full version attached.
Many thanks
Gary
#define freq RF12_433MHZ
const int nodeID = 5;
const int networkGroup = 210;
#include <JeeLib.h>
#include <Wire.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_BMP085_U.h>
Adafruit_BMP085_Unified bmp = Adafruit_BMP085_Unified(10085);
// RFM12B RF payload datastructure
typedef struct
{
int16_t temp_int;
int32_t pressure;
} Payload;
Payload weather;
void setup()
{
rf12_initialize(nodeID, freq, networkGroup); // Initialize RFM12B in transmit mode
//rf12_sleep(RF12_SLEEP);
Serial.begin(9600);
Serial.println("Weather node test for RFM12B listen then transmit");
Serial.print("Node: "); Serial.print(nodeID);
Serial.print(" Network: "); Serial.println(networkGroup);
rfTestData();
pinMode(BMP_PWR,OUTPUT); // Set up the BMP power pin
digitalWrite(BMP_PWR,LOW);
bmpSensorTest(); // Will not proceed until BMP suceeds
delay(1000);
} // end of setup
void loop()
{
// Get our BMP085 data and store into transmit structure variables
sensors_event_t event;
bmp.getEvent(&event);
Serial.println("-----data start-----");
float temperature;
bmp.getTemperature(&temperature);
Serial.print("Temperature: "); Serial.print(temperature); Serial.println(" C");
weather.temp_int = (temperature*100); // multiply by 100 to send to emonCMS
Serial.print("Pressure: "); Serial.print(event.pressure); Serial.println(" hPa");
weather.pressure = (event.pressure*10); // multiply by 10 to send to emonCMS
Serial.println("------data end------");
Serial.println();
//tinytxrfwrite(); // Transmit our data
emonthrfwrite(); // Transmit our data
delay(30000); // 30 second delay
} // End of main loop
// Functions below //
// Test the BMP is working and display some info - remember to power up
void bmpSensorTest()
{
Serial.println();
Serial.println("Pressure Sensor Test"); Serial.println("");
digitalWrite(BMP_PWR,HIGH);
delay(100);
if(!bmp.begin()) // Test BMP detected
{
Serial.print("Ooops, no BMP085 detected ... Check your wiring or I2C ADDR!");
while(1);
}
displaySensorDetails(); // Display some basic information on this sensor
digitalWrite(BMP_PWR,LOW); // Back to sleep
}
// Display of BMP085 info
void displaySensorDetails(void)
{
sensor_t sensor;
bmp.getSensor(&sensor);
Serial.println("------------------------------------");
Serial.print ("Sensor: "); Serial.println(sensor.name);
Serial.print ("Driver Ver: "); Serial.println(sensor.version);
Serial.print ("Unique ID: "); Serial.println(sensor.sensor_id);
Serial.print ("Max Value: "); Serial.print(sensor.max_value); Serial.println(" hPa");
Serial.print ("Min Value: "); Serial.print(sensor.min_value); Serial.println(" hPa");
Serial.print ("Resolution: "); Serial.print(sensor.resolution); Serial.println(" hPa");
Serial.println("------------------------------------");
Serial.println("");
delay(500);
}
// The transmit code
void tinytxrfwrite()
{
//rf12_initialize(nodeID, freq, networkGroup);
Serial.println("About to send RF data: ");
Serial.print ("Temp_int: "); Serial.println(weather.temp_int);
Serial.print ("Pressure: "); Serial.println(weather.pressure);
rf12_sleep(-1); // Wake up RF module
while (!rf12_canSend())
rf12_recvDone();
rf12_sendStart(0, &weather, sizeof weather);
rf12_sendWait(2); // Wait for RF to finish sending while in standby mode
rf12_sleep(0); // Put RF module to sleep
digitalWrite(LED,HIGH);
delay(50);
digitalWrite(LED,LOW);
return;
}
void emonthrfwrite()
{
//rf12_initialize(nodeID, freq, networkGroup);
Serial.println("About to send RF data: ");
Serial.print ("Temp_int: "); Serial.println(weather.temp_int);
Serial.print ("Pressure: "); Serial.println(weather.pressure);
rf12_sleep(RF12_WAKEUP);
rf12_sendNow(0, &weather, sizeof weather);
// set the sync mode to 2 if the fuses are still the Arduino default
// mode 3 (full powerdown) can only be used with 258 CK startup fuses
rf12_sendWait(2);
rf12_sleep(RF12_SLEEP);
digitalWrite(LED,HIGH);
delay(100);
digitalWrite(LED,LOW);
}
// Send some test data as part of setup
void rfTestData()
{
Serial.println("About to send test RF data");
for (int i=0; i<10; i++)
{
weather.temp_int=i;
weather.pressure=(i*1000);
Serial.print ("Test Temp_int: "); Serial.println(weather.temp_int);
Serial.print ("Test Pressure: "); Serial.println(weather.pressure);
rf12_sendNow(0, &weather, sizeof weather);
delay(5000);
}
rf12_sendWait(2);
rf12_sleep(RF12_SLEEP);
Serial.println("End of RF data");
weather.temp_int=0;
weather.pressure=0;
}
EDIT - the Adafruit unified driver is up and running. I have attached my updated sketch if anyone is interested. In case you are wondering what some of debris is I am slowly working at converting a sketch which grabs WH1080 Fine Offset / Maplin N96GY data and send it to the serial port to retransmit this into emonCMS. Many thanks to Mark and Andrew at HAH for doing the hard work. http://www.homeautomationhub.com/content/wh1080-weather-station-integration?page=1
Next steps: testing swapping the RFM12B from OOK to normal to transmit and then shoehorning in the WH1080 code.
Many thanks
Gary
Re: Sending BMP085 data to emonCMS using Adafruit library - solved
Second rule of house sensors....
If you are thinking about doing it Nathan Chantrell has probably already done it and posted the code :-)
http://nathan.chantrell.net/tinytx-wireless-sensor/
It does use the jeelib library but as it works it might be easier to see where the differences in approach are.
Re: Sending BMP085 data to emonCMS using Adafruit library - solved
Thanks for the quick reply, I had a look there last night and grabbed Nathan's transmit code as a check
Unfortunately Nathan is using the Jeelib BMP library and its Ports trickery - the Jeelib wiki is a little vague on the Ports I2C calls. If the Jeelib PortsBMP code defaults to A4 SDA and A5 SCL or has this as an option I should be OK but I just could not see any documenting of this at Jeelabs
https://github.com/nathanchantrell/TinyTX/blob/master/TinyTX_BMP085/Tiny...
Re: Sending BMP085 data to emonCMS using Adafruit library - solved
I might be making some progress thanks to a speedy reply to a query from JCW at Jeelabs.
It looks like there is an undocumented "0" option for the Jeelibs PortsBMP library, so using JCW's example
https://github.com/jcw/jeelib/tree/master/examples/Ports/bmp085demo
this would be:
#include <PortsBMP085.h>
PortI2C two (0); // Uses standard Uno A4 and A5
BMP085 psensor (two, 3); // ultra high resolution
There is though some different syntax floating around which I have asked JCW for some help on (this is from one of Nathan Chantrell's sketches)
#include <PortsBMP085.h> // Part of JeeLib
PortI2C i2c (2); // BMP085 SDA to D8 and SCL to D7
BMP085 psensor (i2c, 3); // ultra high resolution
Gary
Re: Sending BMP085 data to emonCMS using Adafruit library - solved
I now seem to be able to get the Adafruit library working but I am experiencing some very odd behaviour. Doing a serial print of the "struct " fields I get exactly what I expect to be see - each value in the correct order. When it gets to emonCMS though it is going haywire:
* I seem to get 6 inputs
* Struct fields 1 and 2 are ok but: 3 is zero this seesm to be sent to input 4; struct number 4 is sent to input 6; and input 5 is zero.
I am currently running emonCMS v6 off a SD card and had been planning to try and move over to v7, however, it looks like the image might need some tweaking. I had a go at updating from v6 to v7 but that was a fail.
These are the key bits of my code - any ideas if it is an Arduino or emonCMS issue?
typedef struct {
int vcc;
int32_t temp_internal;
int32_t pressure;
int test_3;
} Payload;
Payload rfdata;
from loop
#if defined BMPFITTED
if (bmpTest == 1)
{
sensors_event_t event;
bmp.getEvent(&event);
Serial.println();
Serial.println("----BMP readings---");
float temperature;
bmp.getTemperature(&temperature);
rfdata.pressure=(event.pressure*10); // Remember to divide by 10 later
rfdata.temp_internal=(temperature*100); // Remember to divide by 100 later
}
#endif
rfdata.vcc=readVccRef();
rfdata.test_3=(readVccRef()*2);
#if defined DEBUGMAX
delay(10);
Serial.println("Sending the data ...");
#endif
rf12_sleep(RF12_WAKEUP);
delay(10);
rf12_sendNow(0, &rfdata, sizeof rfdata);
rf12_sendWait(2);
rf12_sleep(RF12_SLEEP);
Many thanks
Gary
Re: Sending BMP085 data to emonCMS using Adafruit library - solved
EmonCMS expects 16-bit signed integers. Those 32 bit integers are your problem, they span two 16-bit integers. You could try combining inputs 2&3 to recover temp_internal, and 4&5 to recover pressure, but by far the best way would be to scale them at source and send a 16-bit signed value.
Re: Sending BMP085 data to emonCMS using Adafruit library - solved
Thank you - it is now up and running - the 32 bit integers were leftovers from trying to use the Jeelabs BMP library which goes to 2 decimal places for pressure