Sending BMP085 data to emonCMS using Adafruit library - solved

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

ukmoose's picture

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.

 

 

GJPickard's picture

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...

GJPickard's picture

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

 

GJPickard's picture

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

Robert Wall's picture

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.

GJPickard's picture

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

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.