root / Ports / examples / bmp085demo / bmp085demo.pde
History | View | Annotate | Download (4 KB)
| 1 | 7763 | jcw | //>>> The latest version of this code can be found at https://github.com/jcw/ !! |
|---|---|---|---|
| 2 | 7763 | jcw | |
| 3 | 4727 | jcw | // Ports demo, reads out a BMP085 sensor connected via I2C |
| 4 | 4727 | jcw | // 2009-02-17 <jcw@equi4.com> http://opensource.org/licenses/mit-license.php |
| 5 | 4727 | jcw | // $Id$ |
| 6 | 4727 | jcw | |
| 7 | 5725 | jcw | // 2010-05-22: added support for all resolution modes |
| 8 | 5725 | jcw | // 2010-05-25: extended to also broadcast all readings over wireless |
| 9 | 5826 | jcw | // 2010-06-17: add power saving logic, should reduce consumption by over 90% |
| 10 | 5853 | jcw | // 2010-06-24: improved power savings, several "hot spots" optimized |
| 11 | 5725 | jcw | |
| 12 | 5858 | jcw | // see http://news.jeelabs.org/2010/06/20/battery-savings-for-the-pressure-plug/ |
| 13 | 5858 | jcw | // see http://news.jeelabs.org/2010/06/30/going-for-gold-with-the-bmp085/ |
| 14 | 5858 | jcw | |
| 15 | 5402 | jcw | #include <Ports.h> |
| 16 | 4727 | jcw | #include "PortsBMP085.h" |
| 17 | 5725 | jcw | #include <RF12.h> |
| 18 | 5826 | jcw | #include <avr/sleep.h> |
| 19 | 4727 | jcw | |
| 20 | 4727 | jcw | PortI2C two (2); |
| 21 | 5741 | jcw | BMP085 psensor (two, 3); // ultra high resolution |
| 22 | 5725 | jcw | MilliTimer timer; |
| 23 | 4727 | jcw | |
| 24 | 5826 | jcw | // This power-saving code was shamelessly stolen from the rooms.pde sketch, |
| 25 | 5826 | jcw | // see http://code.jeelabs.org/viewvc/svn/jeelabs/trunk/jeemon/sketches/rooms/ |
| 26 | 5826 | jcw | |
| 27 | 5826 | jcw | EMPTY_INTERRUPT(WDT_vect); // just wakes us up to resume |
| 28 | 5826 | jcw | |
| 29 | 5826 | jcw | static void watchdogInterrupts (char mode) {
|
| 30 | 5826 | jcw | MCUSR &= ~(1<<WDRF); // only generate interrupts, no reset |
| 31 | 5826 | jcw | cli(); |
| 32 | 5826 | jcw | WDTCSR |= (1<<WDCE) | (1<<WDE); // start timed sequence |
| 33 | 5826 | jcw | WDTCSR = mode >= 0 ? bit(WDIE) | mode : 0; |
| 34 | 5826 | jcw | sei(); |
| 35 | 5826 | jcw | } |
| 36 | 5826 | jcw | |
| 37 | 5826 | jcw | static void lowPower (byte mode) {
|
| 38 | 5826 | jcw | // prepare to go into power down mode |
| 39 | 5826 | jcw | set_sleep_mode(mode); |
| 40 | 5826 | jcw | // disable the ADC |
| 41 | 5826 | jcw | byte prrSave = PRR, adcsraSave = ADCSRA; |
| 42 | 5826 | jcw | ADCSRA &= ~ bit(ADEN); |
| 43 | 5909 | jcw | PRR |= bit(PRADC); |
| 44 | 5826 | jcw | // zzzzz... |
| 45 | 5826 | jcw | sleep_mode(); |
| 46 | 5826 | jcw | // re-enable the ADC |
| 47 | 5826 | jcw | PRR = prrSave; |
| 48 | 5826 | jcw | ADCSRA = adcsraSave; |
| 49 | 5826 | jcw | } |
| 50 | 5826 | jcw | |
| 51 | 5826 | jcw | static byte loseSomeTime (word msecs) {
|
| 52 | 5854 | jcw | // only slow down for periods longer than the watchdog granularity |
| 53 | 5854 | jcw | if (msecs >= 16) {
|
| 54 | 5826 | jcw | // watchdog needs to be running to regularly wake us from sleep mode |
| 55 | 5826 | jcw | watchdogInterrupts(0); // 16ms |
| 56 | 5826 | jcw | for (word ticks = msecs / 16; ticks > 0; --ticks) {
|
| 57 | 5826 | jcw | lowPower(SLEEP_MODE_PWR_DOWN); // now completely power down |
| 58 | 5826 | jcw | // adjust the milli ticks, since we will have missed several |
| 59 | 5826 | jcw | extern volatile unsigned long timer0_millis; |
| 60 | 5826 | jcw | timer0_millis += 16; |
| 61 | 5826 | jcw | } |
| 62 | 5826 | jcw | watchdogInterrupts(-1); // off |
| 63 | 5826 | jcw | return 1; |
| 64 | 5826 | jcw | } |
| 65 | 5826 | jcw | return 0; |
| 66 | 5826 | jcw | } |
| 67 | 5826 | jcw | |
| 68 | 5826 | jcw | // End of new power-saving code. |
| 69 | 5826 | jcw | |
| 70 | 4727 | jcw | void setup() {
|
| 71 | 4727 | jcw | Serial.begin(57600); |
| 72 | 4727 | jcw | Serial.print("\n[bmp085demo]");
|
| 73 | 5827 | jcw | rf12_initialize(3, RF12_868MHZ, 5); // 868 Mhz, net group 5, node 3 |
| 74 | 4727 | jcw | |
| 75 | 4727 | jcw | psensor.getCalibData(); |
| 76 | 4727 | jcw | } |
| 77 | 4727 | jcw | |
| 78 | 4727 | jcw | void loop() {
|
| 79 | 5851 | jcw | // spend most of the waiting time in a low-power sleep mode |
| 80 | 5851 | jcw | // note: the node's sense of time is no longer 100% accurate after sleeping |
| 81 | 7502 | jcw | rf12_sleep(RF12_SLEEP); // turn the radio off |
| 82 | 5851 | jcw | loseSomeTime(timer.remaining()); // go into a (controlled) comatose state |
| 83 | 5853 | jcw | |
| 84 | 5725 | jcw | while (!timer.poll(1000)) |
| 85 | 5853 | jcw | lowPower(SLEEP_MODE_IDLE); // still not running at full power |
| 86 | 4727 | jcw | |
| 87 | 5853 | jcw | // sensor readout takes some time, so go into power down while waiting |
| 88 | 5853 | jcw | // int32_t traw = psensor.measure(BMP085::TEMP); |
| 89 | 5853 | jcw | // int32_t praw = psensor.measure(BMP085::PRES); |
| 90 | 4727 | jcw | |
| 91 | 5853 | jcw | psensor.startMeas(BMP085::TEMP); |
| 92 | 5854 | jcw | loseSomeTime(16); |
| 93 | 5853 | jcw | int32_t traw = psensor.getResult(BMP085::TEMP); |
| 94 | 5853 | jcw | |
| 95 | 5853 | jcw | psensor.startMeas(BMP085::PRES); |
| 96 | 5853 | jcw | loseSomeTime(32); |
| 97 | 5853 | jcw | int32_t praw = psensor.getResult(BMP085::PRES); |
| 98 | 4727 | jcw | |
| 99 | 5725 | jcw | struct { int16_t temp; int32_t pres; } payload;
|
| 100 | 5853 | jcw | psensor.calculate(payload.temp, payload.pres); |
| 101 | 5725 | jcw | |
| 102 | 5853 | jcw | // this code is not needed for use as remote node, keep it for debugging |
| 103 | 5853 | jcw | Serial.print("\nBMP ");
|
| 104 | 5853 | jcw | Serial.print(traw); |
| 105 | 4727 | jcw | Serial.print(' ');
|
| 106 | 5853 | jcw | Serial.print(praw); |
| 107 | 5853 | jcw | Serial.print(' ');
|
| 108 | 5725 | jcw | Serial.print(payload.temp); |
| 109 | 4727 | jcw | Serial.print(' ');
|
| 110 | 5725 | jcw | Serial.print(payload.pres); |
| 111 | 5725 | jcw | |
| 112 | 7502 | jcw | rf12_sleep(RF12_WAKEUP); // turn radio back on at the last moment |
| 113 | 5872 | jcw | |
| 114 | 5872 | jcw | MilliTimer wait; // radio needs some time to power up, why? |
| 115 | 5872 | jcw | while (!wait.poll(5)) {
|
| 116 | 5872 | jcw | rf12_recvDone(); |
| 117 | 5872 | jcw | lowPower(SLEEP_MODE_IDLE); |
| 118 | 5872 | jcw | } |
| 119 | 5872 | jcw | |
| 120 | 5741 | jcw | while (!rf12_canSend()) |
| 121 | 5741 | jcw | rf12_recvDone(); |
| 122 | 5872 | jcw | |
| 123 | 5834 | jcw | rf12_sendStart(0, &payload, sizeof payload, 1); // sync mode! |
| 124 | 4727 | jcw | } |