Permalink
Browse files

Add BMP085 and ATmega328 sensor

  • Loading branch information...
1 parent ae752a4 commit 506b5bc5b03e847391a9b666a51b9aa5f0daf198 @nathanchantrell committed Feb 12, 2013
Showing with 139 additions and 0 deletions.
  1. +139 −0 BMP085_TX/BMP085_TX.ino
View
@@ -0,0 +1,139 @@
+
+//----------------------------------------------------------------------------------------------------------------------
+// BMP085 Barometric Pressure & Temperature Sensor Node
+// By Nathan Chantrell.
+//
+// Using the BMP085 sensor and ATmega328
+//
+// Licenced under the Creative Commons Attribution-ShareAlike 3.0 Unported (CC BY-SA 3.0) licence:
+// http://creativecommons.org/licenses/by-sa/3.0/
+//----------------------------------------------------------------------------------------------------------------------
+
+// Power pin of the BMP085 sensor is connected to A3 or 3.3V (Not 5V!)
+// Connect GND to Ground
+// Connect SCL to Analogue 5
+// Connect SDA to Analogue 4
+// EOC & XCLR are not used
+
+#include <Wire.h>
+#include <Adafruit_BMP085.h> // https://github.com/adafruit/Adafruit-BMP085-Library
+#include <JeeLib.h> // https://github.com/jcw/jeelib
+
+ISR(WDT_vect) { Sleepy::watchdogEvent(); } // interrupt handler for JeeLabs Sleepy power saving
+
+#define myNodeID 1 // RF12 node ID in the range 1-30
+#define network 210 // RF12 Network group
+#define freq RF12_433MHZ // Frequency of RFM12B module
+
+#define USE_ACK // Enable ACKs, comment out to disable
+#define RETRY_PERIOD 5 // How soon to retry (in seconds) if ACK didn't come in
+#define RETRY_LIMIT 5 // Maximum number of times to retry
+#define ACK_TIME 10 // Number of milliseconds to wait for an ack
+
+#define BMP085_POWER A3 // BMP085 power pin is connected on A3
+Adafruit_BMP085 bmp;
+
+//########################################################################################################################
+//Data Structure to be sent
+//########################################################################################################################
+
+ typedef struct {
+ int temp; // Temperature reading
+ int supplyV; // Supply voltage
+ int press; // Pressure reading
+ } Payload;
+
+ Payload tinytx;
+
+// Wait a few milliseconds for proper ACK
+ #ifdef USE_ACK
+ static byte waitForAck() {
+ MilliTimer ackTimer;
+ while (!ackTimer.poll(ACK_TIME)) {
+ if (rf12_recvDone() && rf12_crc == 0 &&
+ rf12_hdr == (RF12_HDR_DST | RF12_HDR_CTL | myNodeID))
+ return 1;
+ }
+ return 0;
+ }
+ #endif
+
+//--------------------------------------------------------------------------------------------------
+// Send payload data via RF
+//-------------------------------------------------------------------------------------------------
+ static void rfwrite(){
+ #ifdef USE_ACK
+ for (byte i = 0; i <= RETRY_LIMIT; ++i) { // tx and wait for ack up to RETRY_LIMIT times
+ rf12_sleep(-1); // Wake up RF module
+ while (!rf12_canSend())
+ rf12_recvDone();
+ rf12_sendStart(RF12_HDR_ACK, &tinytx, sizeof tinytx);
+ rf12_sendWait(2); // Wait for RF to finish sending while in standby mode
+ byte acked = waitForAck(); // Wait for ACK
+ rf12_sleep(0); // Put RF module to sleep
+ if (acked) { return; } // Return if ACK received
+
+ Sleepy::loseSomeTime(RETRY_PERIOD * 1000); // If no ack received wait and try again
+ }
+ #else
+ rf12_sleep(-1); // Wake up RF module
+ while (!rf12_canSend())
+ rf12_recvDone();
+ rf12_sendStart(0, &tinytx, sizeof tinytx);
+ rf12_sendWait(2); // Wait for RF to finish sending while in standby mode
+ rf12_sleep(0); // Put RF module to sleep
+ return;
+ #endif
+ }
+
+
+//--------------------------------------------------------------------------------------------------
+// Read current supply voltage
+//--------------------------------------------------------------------------------------------------
+ long readVcc() {
+ bitClear(PRR, PRADC); ADCSRA |= bit(ADEN); // Enable the ADC
+ long result;
+ // Read 1.1V reference against Vcc
+ #if defined(__AVR_ATtiny84__)
+ ADMUX = _BV(MUX5) | _BV(MUX0); // For ATtiny84
+ #else
+ ADMUX = _BV(REFS0) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1); // For ATmega328
+ #endif
+ delay(2); // Wait for Vref to settle
+ ADCSRA |= _BV(ADSC); // Convert
+ while (bit_is_set(ADCSRA,ADSC));
+ result = ADCL;
+ result |= ADCH<<8;
+ result = 1126400L / result; // Back-calculate Vcc in mV
+ ADCSRA &= ~ bit(ADEN); bitSet(PRR, PRADC); // Disable the ADC to save power
+ return result;
+}
+//########################################################################################################################
+
+
+void setup() {
+
+ rf12_initialize(myNodeID,freq,network); // Initialize RFM12 with settings defined above
+ rf12_sleep(0); // Put the RFM12 to sleep
+
+ // Turn on power pin for the BMP085
+ pinMode(BMP085_POWER, OUTPUT);
+ digitalWrite(BMP085_POWER, HIGH);
+
+ bmp.begin(); // Initialise the BMP085
+
+}
+
+void loop() {
+
+ tinytx.temp = (bmp.readTemperature()*100); // Get temperature
+
+ tinytx.press = (bmp.readPressure()/100); // Get pressure & convert to mb
+
+ tinytx.supplyV = readVcc(); // Get supply voltage
+
+ rfwrite(); // Send data via RF
+
+ Sleepy::loseSomeTime(60000); //JeeLabs power save function: enter low power mode for 60 seconds (valid range 16-65000 ms)
+
+}

0 comments on commit 506b5bc

Please sign in to comment.