Permalink
Switch branches/tags
Nothing to show
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
251 lines (205 sloc) 6.88 KB
#include <Wire.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_BMP085_U.h>
#include <JeeLib.h> // https://github.com/jcw/jeelib
#include <Ports.h> // https://github.com/jcw/jeelib
#include <avr/pgmspace.h> // http://excamera.com/sphinx/article-crc.html
#include <avr/sleep.h>
//#define BLIP_DEBUG
#define BLIP_NODE 4 // set this to a unique ID to disambiguate multiple nodes
#define BLIP_GRP 17 // wireless net group to use for sending blips
#define SEND_MODE 2 // set to 3 if fuses are e=06/h=DE/l=CE, else set to 2
#define RF_CHIPSELECT 10
// this must be defined since we're using the watchdog for low-power waiting
ISR(WDT_vect) {
Sleepy::watchdogEvent();
}
Adafruit_BMP085_Unified bmp = Adafruit_BMP085_Unified(10085);
typedef struct payload_t {
unsigned long id;
unsigned long counter;
float value1;
float value2;
float value3;
float value4;
float value5;
unsigned long crc;
};
payload_t payload;
float previous1 = 0, previous2 = 0, previous3 = 0;
/**************************************************************************/
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);
}
/**************************************************************************/
void setup(void)
{
#ifdef BLIP_DEBUG
Serial.begin(57600);
Serial.print("\n[rfm12b_send_bmp085 / ");
Serial.print(__DATE__);
Serial.print(" / ");
Serial.print(__TIME__);
Serial.println("]");
#endif
pinMode(RF_CHIPSELECT, OUTPUT);
rf12_set_cs(RF_CHIPSELECT);
rf12_initialize(BLIP_NODE, RF12_868MHZ, BLIP_GRP);
rf12_sleep(RF12_SLEEP);
delay(100); // give it some time to send before falling asleep
/* Initialise the sensor */
if (!bmp.begin()) {
/* There was a problem detecting the BMP085 ... check your connections */
Serial.print("Ooops, no BMP085 detected ... Check your wiring or I2C ADDR!");
while (1);
}
else {
Serial.print("BMP085 detected.");
}
/* Display some basic information on this sensor */
displaySensorDetails();
payload.id = BLIP_NODE;
payload.counter = 0;
payload.value1 = NAN;
payload.value2 = NAN;
payload.value3 = NAN;
payload.value4 = NAN;
payload.value5 = NAN;
}
/**************************************************************************/
void loop(void)
{
boolean stable = false;
float pressure, temperature;
while (!stable) {
bmp.getTemperature(&temperature);
bmp.getPressure(&pressure);
payload.value1 = 0.001 * readVcc(); // this is in mV, we want V
payload.value2 = temperature; // this is in Celcius
payload.value3 = 0.01 * pressure; // this is in Pa, we want hPa, i.e. mbar
// compute the difference with the previous values
previous1 -= payload.value1;
previous1 = abs(previous1);
previous2 -= payload.value2;
previous2 = abs(previous2);
previous3 -= payload.value3;
previous3 = abs(previous3);
// the voltage should be stable within 0.1, the temperature withing 1, the pressure within 1
stable = (previous1 < 0.1) && (previous2 < 1) && (previous3 < 1);
#ifdef BLIP_DEBUG
// DISPLAY DATA
Serial.print("BMP085,\t");
Serial.print(payload.id);
Serial.print(",\t");
Serial.print(payload.counter);
Serial.print(",\t");
Serial.print(payload.value1, 2);
Serial.print(",\t");
Serial.print(payload.value2, 2);
Serial.print(",\t");
Serial.print(payload.value3, 2);
Serial.print(",\t");
Serial.print(payload.value4, 2);
Serial.print(",\t");
Serial.print(payload.value5, 2);
Serial.print(",\t");
Serial.println(payload.crc);
if (!stable)
Serial.println("Not stable");
else
Serial.println("Stable");
#endif
// update the previous values
previous1 = payload.value1;
previous2 = payload.value2;
previous3 = payload.value3;
delay(100);
} // if stable
payload.counter += 1;
payload.crc = crc_buf((char *)&payload, sizeof(payload_t) - sizeof(unsigned long));
#ifdef BLIP_DEBUG
Serial.println("Sending...");
delay(100);
#endif
rf12_sleep(RF12_WAKEUP);
rf12_sendNow(0, &payload, sizeof payload);
rf12_sendWait(SEND_MODE);
rf12_sleep(RF12_SLEEP);
delay(100); // give it some time to send before falling asleep
Sleepy::loseSomeTime(64000);
}
/*****************************************************************************/
long readVcc() {
// Read 1.1V reference against AVcc
// set the reference to Vcc and the measurement to the internal 1.1V reference
#if defined(__AVR_ATmega32U4__) || defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
ADMUX = _BV(REFS0) | _BV(MUX4) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
#elif defined (__AVR_ATtiny24__) || defined(__AVR_ATtiny44__) || defined(__AVR_ATtiny84__)
ADMUX = _BV(MUX5) | _BV(MUX0);
#elif defined (__AVR_ATtiny25__) || defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny85__)
ADMUX = _BV(MUX3) | _BV(MUX2);
#else
ADMUX = _BV(REFS0) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
#endif
delay(2); // Wait for Vref to settle
ADCSRA |= _BV(ADSC); // Start conversion
while (bit_is_set(ADCSRA, ADSC)); // measuring
uint8_t low = ADCL; // must read ADCL first - it then locks ADCH
uint8_t high = ADCH; // unlocks both
long result = (high << 8) | low;
result = 1155700L / result; // Calculate Vcc (in mV); 1125300 = 1.1*1023*1000
return result; // Vcc in millivolts
}
/*****************************************************************************/
PROGMEM const uint32_t crc_table[16] = {
0x00000000, 0x1db71064, 0x3b6e20c8, 0x26d930ac,
0x76dc4190, 0x6b6b51f4, 0x4db26158, 0x5005713c,
0xedb88320, 0xf00f9344, 0xd6d6a3e8, 0xcb61b38c,
0x9b64c2b0, 0x86d3d2d4, 0xa00ae278, 0xbdbdf21c
};
unsigned long crc_update(unsigned long crc, byte data)
{
byte tbl_idx;
tbl_idx = crc ^ (data >> (0 * 4));
crc = pgm_read_dword_near(crc_table + (tbl_idx & 0x0f)) ^ (crc >> 4);
tbl_idx = crc ^ (data >> (1 * 4));
crc = pgm_read_dword_near(crc_table + (tbl_idx & 0x0f)) ^ (crc >> 4);
return crc;
}
unsigned long crc_buf(char *b, long l)
{
unsigned long crc = ~0L;
for (unsigned long i = 0; i < l; i++)
crc = crc_update(crc, ((char *)b)[i]);
crc = ~crc;
return crc;
}
unsigned long crc_string(char *s)
{
unsigned long crc = ~0L;
while (*s)
crc = crc_update(crc, *s++);
crc = ~crc;
return crc;
}