Hi,
I am working on a quadcopter originally from http://aeroquad.com/ which is using a Arduino Mega board.
It is a great platform for quads, but now I've run into a frustrating problem. I wanna add a BMP085 which is a I2C barometer for altitude hold control/height sensoring. I have managed to get this: http://interactive-matter.org/2009/12/arduino-barometric-pressure-sensor-bmp085/ and this: BMP085 with Arduino (tested & working) | mitat.tuu.fi to work great as stand alone read code. I have already managed to get an analog sensor to regulate height fine but only to a maximum distance above ground of 1.5m due to use of SHARP IR sensor. Now I need to evolve.
The values I get are expected in the range around 1004.00-1006.00hPa, and expected temperature too.
The problem is that I cannot use the delay() function which delays and stops the whole flight program for 26ms (read time from sensor) because then it gets out of control and really wild.
Therefore I have made a change so that the code that writes to the "start measure sensor" registers are called at the end of a time interval state code and in the beginning of that code when it comes the second time to the loop it is ready to be read.
The problem is that the way the code works the values read in are in the range of 600.00hPa the way I implemented this and does not correspond as good to the real pressure as the original code. As soon as I comment in the delay in the read function again the sensor gives out relevant and correct data again.
The question is why?
I'll try to put in relevant bits of code:
//in 26ms loop for the highest resolution of BMP085
byte updateFlag = 0;
if (updateFlag == 1) { //prevent measurement before conversion started
bmp085_read_temperature_and_pressure(&temperature,&pressure);
actualPressure = pressure;
//do something useful with the read in value
}
updateCommandBMP085(); //this function I added to make "write_register" to start reading the values and then wait 26ms
updateFlag = 1;
this is the original code for starting measurement:
long bmp085_read_up() {
write_register(0xf4,0x34+(oversampling_setting<<6)); //this needs to be done in state loop
delay(pressure_waittime[oversampling_setting]); //this needs to be replaced by the loop time
unsigned char msb, lsb, xlsb;
Wire.beginTransmission(I2C_ADDRESS);
Wire.send(0xf6); // register to read
Wire.endTransmission();
Wire.requestFrom(I2C_ADDRESS, 3); // read a byte
while(!Wire.available()) {
// waiting
}
msb = Wire.receive();
while(!Wire.available()) {
// waiting
}
lsb |= Wire.receive();
while(!Wire.available()) {
// waiting
}
xlsb |= Wire.receive();
return (((long)msb<<16) | ((long)lsb<<8) | ((long)xlsb)) >>(8-oversampling_setting);
}
and what I did to get rid of the delay() was:
void updateCommandBMP085 () {
write_register(0xf4,0x2e); //start temperature reading
write_register(0xf4,0x34+(oversampling_setting<<6)); //start pressure reading
};
And all this should work exactly as the original test code for BMP085 and Arduino, but just by commenting in/out the "delay(pressure_waittime[oversampling_setting]);" line, I get two totally different readings, when using delay() the reading is correct and the quad goes wild, when commented out and the "write_register" is called from the state loop, the values read in from the sensor is off.
My question is: what am I missing? What is the difference here between using the delay() and calling the write register from a loop instead?
Thanks for any answer!