Closed exsertus closed 11 years ago
Hi, I believe you are overflowing, see your log structure struct LogType { char dataset; int val; int vcc; int offset; }; int is only 16 bit, values above 32767 won't fix. Your pressure would be about 100000 though. try to use int32_t instead
Gah!, schoolboy error!. Yup, worked a charm. Just took the value and divided by 100 before writing it to my struct, as I'm interested in HPa rather than Pa.
Brilliant lib, thanks for the quick response.
Steve
Hi, just started using this great port for an ATTiny84 / XBee / BMP085 sensor module. I've modded the TinyWireM.h and .cpp files to cater for my ATTiny84 running at 8MHz and I can successfully call the the bmp.readTemperature10C(); function.
However, when I call readPressure() I get a value of around -30055. This suggests that the I2C calls are working between the MCU and BMP085.
I'm in London, so I'd expect the pressure value to be around 1000-1020 Hpa
Here's the code (apologies its quite verbose!). I've also tried this without all the WDT and sleep modes to see if it was those that we messing with the I2C comms. Also my linker is the 8K, so it compiles fine (around 7K)
/*============================================================ Name : XBeeBMP085Sensor Author : exsertus.com (Steve Bowerman)
Summary Generic Xbee sensor program.
Version : 2.0
Credits
============================================================*/
include
include <avr/power.h>
include <avr/sleep.h>
include <avr/wdt.h>
include
include
// Setup 85 and 84 Specifics
if defined (AVR_ATtiny24) || defined(AVR_ATtiny44) || defined(AVR_ATtiny84)
define TX 7
define RX 8
define SLEEP 10
define SENSPWR 9
define DIO1 1
define DIO2 2
define DIO3 5
define AIO1 1
define AIO2 2
define AIO3 5
elif defined (AVR_ATtiny25) || defined(AVR_ATtiny45) || defined(AVR_ATtiny85)
define TX 4
define RX 3
define SLEEP 1
define SENSPWR 0
define D1 2
define A1 1
endif
define INTERVAL 60
define CACHESIZE 1
define DATASETS 1
ifndef cbi
define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
endif
ifndef sbi
define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
endif
struct LogType { char dataset; int val; int vcc; int offset; };
// Globals
SoftwareSerial XBee (RX, TX); long Vcc = 0; String XBeeAddress = ""; LogType logs[CACHESIZE*DATASETS]; int logcount = 0; int offset = 0;
tinyBMP085 bmp;
ISR(WDT_vect) { // Don't do anything here but we must include this // block of code otherwise the interrupt calls an // uninitialized interrupt handler. }
/*---------------------------------------------------------- Function : setup_watchdog Inputs : li Return : None Globals : None
Summary Sets watchdog interupt up Watchdog timeout values 0=16ms, 1=32ms, 2=64ms, 3=128ms, 4=250ms, 5=500ms 6=1sec, 7=2sec, 8=4sec, 9=8sec Caters for different names for WDT between ATTiny84 and ATTiny85 ----------------------------------------------------------*/
void setup_watchdog(int ii) {
// The prescale value is held in bits 5,2,1,0 // This block moves ii itno these bits byte bb; if (ii > 9 ) ii=9; bb=ii & 7; if (ii > 7) bb|= (1<<5); bb|= (1<<WDCE);
// Reset the watchdog reset flag MCUSR &= ~(1<<WDRF);
if defined (AVR_ATtiny24) || defined(AVR_ATtiny44) || defined(AVR_ATtiny84)
elif defined (__AVR_ATtiny25__) || defined(AVR_ATtiny45) || defined(AVR_ATtiny85)
endif
}
/*---------------------------------------------------------- Function : deepsleep Inputs : waitTime Return : None Globals : None
Summary Puts Attiny into sleep mode (consumes around 10uA)
----------------------------------------------------------*/
void deepsleep(int waitTime) { // Calculate the delay time waitTime = waitTime / 4; int waitCounter = 0; while (waitCounter != waitTime) { set_sleep_mode(SLEEP_MODE_PWR_DOWN); // Set sleep mode sleep_mode(); // System sleeps here waitCounter++; } }
/*----------------------------------------------------------
Function : setup Inputs : None Return : None Globals : Vcc, XBee, SLEEP, SENSPWR
Summary Sets up program, called once when the circuit is powered up. Sets pins, creates software serial object, watchdog and gets XBee Address
----------------------------------------------------------*/
void setup() {
pinMode(SENSPWR,OUTPUT); pinMode(SLEEP,OUTPUT);
XBee.begin(9600);
getXBeeAddress(); setup_watchdog(8);
}
/*----------------------------------------------------------
Function : loop Inputs : None Return : None Globals : Vcc, XBee, XBeeAddress, INTERVAL, SENSPWR, SLEEP
Summary Main loop routine. Wakes up Xbee, takes reading, sends reading, puts XBee back to sleep, then finally puts ATTIny into sleep mode. Avg awake consumption = 20mAh, sleep consumption = 10uAh
----------------------------------------------------------*/
void loop() { /*
*/
digitalWrite(SENSPWR, HIGH);
// Enable ADC ADCSRA |= (1 << ADEN); ADCSRA |= (1 << ADSC);
delay(1000); bmp.begin(); int32_t readAltitudemm(int32_t sealevelPressure = 101325);
logs[logcount].dataset = 'T'; logs[logcount].val = bmp.readTemperature10C(); //bmp.readPressure(); logs[logcount].vcc = readVcc(); logs[logcount].offset = INTERVAL*(CACHESIZE-offset-1); logcount++;
offset++;
// Disable ADC
ACSR |= _BV(ACD);
ADCSRA &= ~_BV(ADEN);
digitalWrite(SENSPWR, LOW);
/* Upload readings to server
*/
if (logcount >= (DATASETS*CACHESIZE)) { // Wake up Xbee from sleep digitalWrite(SLEEP,LOW); delay(1000);
}
// Go back to sleep deepsleep(INTERVAL);
}
/*----------------------------------------------------------
Function : readVcc Inputs : None Return : None Globals : Vcc
Summary Sets the Vcc global variable with the current supply voltage to the Attiny. Works by reading 1.1V reference against AVcc set the reference to Vcc and the measurement to the internal 1.1V reference
----------------------------------------------------------*/
long readVcc() {
if defined (AVR_ATtiny24) || defined(AVR_ATtiny44) || defined(AVR_ATtiny84)
elif defined (__AVR_ATtiny25__) || defined(AVR_ATtiny45) || defined(AVR_ATtiny85)
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 = 1125300L / result; // Calculate Vcc (in mV); 1125300 = 1.1_1023_1000 return result; // Vcc in millivolts }
/*----------------------------------------------------------
Function : getXBeeAddress Inputs : None Return : None Globals : XBee, XBeeAddress
Summary Gets the low part of the XBee 64 bit address using the AT command mode persists XBeeAddress in global variable. Only called once during setup.
----------------------------------------------------------*/
void getXBeeAddress() { int inByte; XBeeAddress = "";
digitalWrite(SLEEP,LOW); // wake up XBee delay(1000);
XBee.print("+++"); delay(2000); XBee.flush();
XBee.print("ATSL\r"); delay(500); while (XBee.available() > 0) { inByte = XBee.read(); if (inByte != '\n' && inByte != '\r') XBeeAddress += (char)inByte; }
XBee.print("ATCN\r"); XBee.flush(); delay(1000);
digitalWrite(SLEEP,HIGH); // Put XBee back to sleep
}