Discussion:
[ethersex-devel] BMP085 mit unbrauchbaren Daten
Florian Asche
2013-08-18 14:36:06 UTC
Permalink
Hallo zusammen,


 

ich habe gestern ein paar neue BMP085 aus China erhalten. GÃŒnstig bei Ebay bekommen ;)


Leider wohl etwas zu gÃŒnstig. Die Sensoren an sich sehen aber 1:1 identisch aus, aber die Daten sind unterschiedlich.


 

WÀhrend der vorhandene Sensor <http://www.ebay.com/itm/New-GY-65-BMP085-Digital-Barometric-Pressure-Sensor-Module-Board-For-Arduino-/350638469110?ssPageName=ADME:L:OC:DE:3160> sauber mit Ethersex lÀuft:


   bmp085 temp


301


   bmp085 temp


300


   bmp085 temp


299


   bmp085 apress


99817


     bmp085 apress


99820


     bmp085 apress


99828


 

Werfen die neuen <http://cgi.ebay.de/ws/eBayISAPI.dll?ViewItem&amp;item=300889452484> nur Daten, mit denen man nichts anfangen kann:


     bmp085 temp


-2525


     bmp085 temp


-2525


     bmp085 temp


-2525


     bmp085 apress


53049


     bmp085 apress


53053


     bmp085 apress


53047


 

Hat jemand schon die selbe Erfahrung gemacht und einen Tipp fÃŒr mich?


 

Gruß Florian
reiner
2013-11-21 11:35:48 UTC
Permalink
Hallo zusammen, ich habe gestern ein paar neue BMP085 aus China erhalten.
Günstig bei Ebay bekommen ;)Leider wohl etwas zu günstig. Die Sensoren an
sich sehen aber 1:1 identisch aus, aber die Daten sind
unterschiedlich. Während der vorhandene Sensor sauber mit Ethersex läuft:
   bmp085 temp301   bmp085 temp300   bmp085 temp299   bmp085 apress99817    
bmp085 apress99820     bmp085 apress99828 Werfen die neuen nur Daten, mit
denen man nichts anfangen kann:     bmp085 temp-2525     bmp085
temp-2525     bmp085 temp-2525     bmp085 apress53049     bmp085
apress53053     bmp085 apress53047 Hat jemand schon die selbe Erfahrung
gemacht und einen Tipp für mich? Gruß Florian

Ahoi,

kann ich bestätigen. Allerdings habe ich auch einen DS75 der mit dem LM75
kompatibel sein soll, getestet und der macht folgendes seltsame Verhalten:
i2c detect
detected at: 0x48 (72)
detected at: 0x77 (119)
OK
lm75 0
41.0
lm75 0
9.0
lm75 0
9.0
bmp085 temp
-2620
bmp085 temp
-2620
bmp085 apress
48962
bmp085 apress
48957
.....

beim BMP habe ich die beiden Anschlüsse extra-reset und noch irgendwas
unbeschaltet gelassen. Kann es sein dass das Übel hier sitzt?
Bleiben aber immer noch die seltsamen Werte vom DS75 ... Muss da nicht was
aus dem ROM gelesen werden um es dann zu verrechnen, zumindest beim bmp
müsste das so sein, da m. W. n. die Eichung im Werk da abgelegt wird.

MfG
Reiner
Florian Asche
2013-11-21 16:38:10 UTC
Permalink
Hi,

ich habe den BMP085 inzwischen mit einem anderen Sourcecode (Bascom) getestet, dort funktioniert er mit Erfolg. Das Problem liegt also bei Ethersex.
Was die Anschlüsse angeht, so habe ich I2C (SDA,SCL), VCC und GND angeschlossen. XCLR und EOC habe ich nicht verbunden.

Zu dem DS75/LM75 kann ich dir nichts sagen, ich benutze für die reine Temperaturmessung die DS18B20.

Gruß Florian

-----Ursprüngliche Nachricht-----
Von: ethersex-devel-***@list.zerties.org [mailto:ethersex-devel-***@list.zerties.org] Im Auftrag von reiner
Gesendet: Donnerstag, 21. November 2013 12:36
An: ethersex-***@list.zerties.org
Betreff: Re: [ethersex-devel] BMP085 mit unbrauchbaren Daten
Hallo zusammen, ich habe gestern ein paar neue BMP085 aus China erhalten.
Günstig bei Ebay bekommen ;)Leider wohl etwas zu günstig. Die Sensoren an sich sehen aber 1:1 identisch aus, aber die Daten sind unterschiedlich. Während der vorhandene Sensor sauber mit Ethersex läuft:
   bmp085 temp301   bmp085 temp300   bmp085 temp299   bmp085 apress99817
bmp085 apress99820     bmp085 apress99828 Werfen die neuen nur Daten, mit denen man nichts anfangen kann:     bmp085 temp-2525     bmp085
temp-2525     bmp085 temp-2525     bmp085 apress53049     bmp085
apress53053     bmp085 apress53047 Hat jemand schon die selbe Erfahrung gemacht und einen Tipp für mich? Gruß Florian

Ahoi,

kann ich bestätigen. Allerdings habe ich auch einen DS75 der mit dem LM75 kompatibel sein soll, getestet und der macht folgendes seltsame Verhalten:
i2c detect
detected at: 0x48 (72)
detected at: 0x77 (119)
OK
lm75 0
41.0
lm75 0
9.0
lm75 0
9.0
bmp085 temp
-2620
bmp085 temp
-2620
bmp085 apress
48962
bmp085 apress
48957
.....

beim BMP habe ich die beiden Anschlüsse extra-reset und noch irgendwas unbeschaltet gelassen. Kann es sein dass das Übel hier sitzt?
Bleiben aber immer noch die seltsamen Werte vom DS75 ... Muss da nicht was aus dem ROM gelesen werden um es dann zu verrechnen, zumindest beim bmp müsste das so sein, da m. W. n. die Eichung im Werk da abgelegt wird.

MfG
Reiner
e***@users.sourceforge.net
2013-11-22 07:06:09 UTC
Permalink
Hallo Florian,
Post by Florian Asche
ich habe den BMP085 inzwischen mit einem anderen Sourcecode (Bascom)
getestet, dort funktioniert er mit Erfolg. Das Problem liegt also bei Ethersex.
Patch willkommen.
Florian Asche
2014-05-23 21:50:22 UTC
Permalink
Hi,

konnte das Problem leider nicht wirklich eingrenzen.
:/

Gruß Flo

-----Ursprüngliche Nachricht-----
Von: ***@users.sourceforge.net [mailto:***@users.sourceforge.net]
Gesendet: Freitag, 22. November 2013 08:06
An: Florian Asche
Cc: reiner; ethersex-***@list.zerties.org
Betreff: Re: [ethersex-devel] BMP085 mit unbrauchbaren Daten

Hallo Florian,
Post by Florian Asche
ich habe den BMP085 inzwischen mit einem anderen Sourcecode (Bascom)
getestet, dort funktioniert er mit Erfolg. Das Problem liegt also bei Ethersex.
Patch willkommen.
reiner
2014-08-24 09:13:24 UTC
Permalink
Post by Florian Asche
Hi,
konnte das Problem leider nicht wirklich eingrenzen.
:/
Gruß Flo
-----Ursprüngliche Nachricht-----
Gesendet: Freitag, 22. November 2013 08:06
An: Florian Asche
Betreff: Re: [ethersex-devel] BMP085 mit unbrauchbaren Daten
Hallo Florian,
Post by Florian Asche
ich habe den BMP085 inzwischen mit einem anderen Sourcecode (Bascom)
getestet, dort funktioniert er mit Erfolg. Das Problem liegt also bei Ethersex.
Patch willkommen.
Nachdem ich nun ein breadboard habe und mal eben vernünftige Tests
machen kann anstelle der Net-IO Krokoklemkrämpfe ....

Mit Arduino Mini einen BMP085 via I2C Bus mit je zwei mal 10k pullups!!!
nach vcc siehe

Example.ino
Adafruit_BMP085.h
Adafruit_BMP085.cpp

*Ursachen bzw. Nebenbedingungen:*
Ohne die Pullups bei I2C nur Schrott. Hängt von der individuellen
Schaltung ab in der man arbeitet ob die bereits drin sind oder nicht und
ist immer im Einzelfall zu prüfen. Ob das mit 5k oder 15k geht weiss ich
auch nicht, testen testen .....
Nächste Besonderheit beim BMP085:
*BMP085 arbeitet NATIV mit 3.3 Volt !!!!*
Mein Modul - gesponsort von Wody2001 - hat einen *Miniregler* onboard so
das es mit*5 Volt* arbeitet!!!! Ich habe das erst gar nicht bemerkt da
sooooo klitzeklein und war dadurch auch nie auf der grünen Seite was die
Arbeitsbedingungen angeht.

Mein Teil macht jetzt jedenfalls sauber das was es soll. Habe für den
Fall der F_e_lle mal dazu gepackt. Mich würde interessieren ob es an
den elektrischen Bedingungen oder am Code liegt bei Ethersex.

BTW hat jemand einen DS75 dazu bringen können mit mehr als 9 Bit
Genauigkeit zu arbeiten?
Der DS75 hat lt. Datenblatt im gegensatz zum LM75 eine programmierbare
Auflösung im Konfigregister Bit 5 und 7.
Ich kann das Register setzen wie ich will (default immer 0 nach
einschalten) 0x20 = 10 Bit, 0x40 = 11Bit oder 0x60= 12 Bit resolution
aber ich bekomme immer nur 0,5 Grad Sprünge raus.
Irgend jemand da schon mal erfolg gehabt oder mache ich da einen
Denkfehler?
Suche auch noch Infos um eine Arduino mini (ist so praktisch auf
kleiner Platine fertig zum spottpreis) im low power mode laufen zu
lassen wegen Solarbetrieb und Solarmessungen. Möchte die Panels
möglichst klein halten bzw. mit einem 2*2cm Panel auskommen für alles.


MfG
Reiner


Example.ino:
#######################################################
/* An Arduino Mini and BMP085 and a 4*20 LCD. To put Data to LCD you
have to convert to string!
to get the correct altitude you have to pass the actual barometric
pressure in PASCAL not hektopascal!! along with the call.
*/
#include <LiquidCrystal.h>
const int numRows = 4;
const int numCols = 20;

LiquidCrystal lcd(12, 11, 5, 4, 3, 2); // Pinbelegung LCD definieren
hier 4draht = Nibble

#include <Wire.h> // I2C einbinden
#include <Adafruit_BMP085.h> // Adafruit Bibliothek einbinden

#define bmp85Adresse 0x77 // Andresse unter der ein BMP85 zu
erreichen ist

Adafruit_BMP085 bmp; // Variable für Adafruit Lib definieren

char dataString[7]; // gelesene Daten als String aufbereitet:
(-xx)x.x
double temp; // gelesene Temperatur als double
double druck; // gelesener Druck bzw. Höhe als double
float high; // geleseene Hoehe als float
int i; // Zählvariable um das Display
jeden100. loop zu löschen um Dezimalverschiebungen zu bereinigen

void setup() {
lcd.begin(numCols,numRows);
lcd.setCursor(0,0);
lcd.write(" Temperatur und ");
lcd.setCursor(0,1);
lcd.write("Luftdruck von BMP085");
lcd.setCursor(0,3);
lcd.write(" C by Netzadmins.de");
delay(10000);
lcd.clear();

Serial.begin(9600);

// Sensor BMP085 initialisieren
if (!bmp.begin()) {
Serial.println("Keinen gültigen BMP085 Sensor gefunden!");
while (true) {}
}
Wire.begin();
}

void loop()
{
for (i = 1; i<=100; i++) {
Serial.print("Temperatur: ");
// readTemperature() Temperatur °C auslesen und anzeigen
Serial.print(bmp.readTemperature());
Serial.print(" "); // Hier müssen wir ein wenig tricksen
Serial.write(176); // um das °-Zeichen korrekt darzustellen
Serial.println("C");

temp=bmp.readTemperature();
dtostrf(temp, 4, 1, dataString); //dtostrf(floatVar,
minStringWidthIncDecimalPoint, numVarsAfterDecimal, charBuf); (standard
avr-libc function)
lcd.setCursor(0,0);
lcd.write(dataString);
lcd.write(" Grad Celsius");

Serial.print("Luftdruck: ");
// readPressure() Luftdruck in Pa auslesen und anzeigen
druck = bmp.readPressure();
Serial.print(druck);
Serial.print(" Pa = ");
druck = druck / 100;
Serial.print(druck);
Serial.println(" hektoPascal");

druck=bmp.readPressure();
dtostrf(druck, 4, 1, dataString); //dtostrf(floatVar,
minStringWidthIncDecimalPoint, numVarsAfterDecimal, charBuf); (standard
avr-libc function)
lcd.setCursor(0,1);
lcd.write(dataString);
lcd.write(" Pascal");
druck=druck/100;
dtostrf(druck, 4, 2, dataString); //dtostrf(floatVar,
minStringWidthIncDecimalPoint, numVarsAfterDecimal, charBuf); (standard
avr-libc function)
lcd.setCursor(0,2);
lcd.write(dataString);
lcd.write(" hektoPascal");

Serial.print("Hoehe: ");
// readAltitude() Höhe in meter auslesen und anzeigen
high = bmp.readAltitude(101500);
Serial.print(high);
Serial.println(" Meter");

dtostrf(high, 4, 2, dataString); //dtostrf(floatVar,
minStringWidthIncDecimalPoint, numVarsAfterDecimal, charBuf); (standard
avr-libc function)
lcd.setCursor(0,3);
lcd.write(dataString);
lcd.write(" m Altitude");

Serial.println(); // Leerzeile anzeigen
delay(200); // 0,2 Sekunden warten
}
if (i=99) {
lcd.clear();
}
}

#######################################################

Adafruit_BMP085.h:
/***************************************************
This is a library for the Adafruit BMP085/BMP180 Barometric Pressure
+ Temp sensor

Designed specifically to work with the Adafruit BMP085 or BMP180
Breakout
----> http://www.adafruit.com/products/391
----> http://www.adafruit.com/products/1603

These displays use I2C to communicate, 2 pins are required to
interface
Adafruit invests time and resources providing this open source code,
please support Adafruit and open-source hardware by purchasing
products from Adafruit!

Written by Limor Fried/Ladyada for Adafruit Industries.
BSD license, all text above must be included in any redistribution
****************************************************/

#ifndef ADAFRUIT_BMP085_H
#define ADAFRUIT_BMP085_H

#if (ARDUINO >= 100)
#include "Arduino.h"
#else
#include "WProgram.h"
#endif
#include "Wire.h"

#define BMP085_DEBUG 0

#define BMP085_I2CADDR 0x77

#define BMP085_ULTRALOWPOWER 0
#define BMP085_STANDARD 1
#define BMP085_HIGHRES 2
#define BMP085_ULTRAHIGHRES 3
#define BMP085_CAL_AC1 0xAA // R Calibration data (16 bits)
#define BMP085_CAL_AC2 0xAC // R Calibration data (16 bits)
#define BMP085_CAL_AC3 0xAE // R Calibration data (16 bits)
#define BMP085_CAL_AC4 0xB0 // R Calibration data (16 bits)
#define BMP085_CAL_AC5 0xB2 // R Calibration data (16 bits)
#define BMP085_CAL_AC6 0xB4 // R Calibration data (16 bits)
#define BMP085_CAL_B1 0xB6 // R Calibration data (16 bits)
#define BMP085_CAL_B2 0xB8 // R Calibration data (16 bits)
#define BMP085_CAL_MB 0xBA // R Calibration data (16 bits)
#define BMP085_CAL_MC 0xBC // R Calibration data (16 bits)
#define BMP085_CAL_MD 0xBE // R Calibration data (16 bits)

#define BMP085_CONTROL 0xF4
#define BMP085_TEMPDATA 0xF6
#define BMP085_PRESSUREDATA 0xF6
#define BMP085_READTEMPCMD 0x2E
#define BMP085_READPRESSURECMD 0x34


class Adafruit_BMP085 {
public:
Adafruit_BMP085();
boolean begin(uint8_t mode = BMP085_ULTRAHIGHRES); // by default go
highres
float readTemperature(void);
int32_t readPressure(void);
int32_t readSealevelPressure(float altitude_meters = 0);
float readAltitude(float sealevelPressure = 101325); // std atmosphere
uint16_t readRawTemperature(void);
uint32_t readRawPressure(void);

private:
int32_t computeB5(int32_t UT);
uint8_t read8(uint8_t addr);
uint16_t read16(uint8_t addr);
void write8(uint8_t addr, uint8_t data);

uint8_t oversampling;

int16_t ac1, ac2, ac3, b1, b2, mb, mc, md;
uint16_t ac4, ac5, ac6;
};


#endif // ADAFRUIT_BMP085_H

#######################################################

Adafruit_BMP085.cpp:
/***************************************************
This is a library for the Adafruit BMP085/BMP180 Barometric Pressure
+ Temp sensor

Designed specifically to work with the Adafruit BMP085 or BMP180
Breakout
----> http://www.adafruit.com/products/391
----> http://www.adafruit.com/products/1603

These displays use I2C to communicate, 2 pins are required to
interface
Adafruit invests time and resources providing this open source code,
please support Adafruit and open-source hardware by purchasing
products from Adafruit!

Written by Limor Fried/Ladyada for Adafruit Industries.
BSD license, all text above must be included in any redistribution
****************************************************/

#include "Adafruit_BMP085.h"

Adafruit_BMP085::Adafruit_BMP085() {
}


boolean Adafruit_BMP085::begin(uint8_t mode) {
if (mode > BMP085_ULTRAHIGHRES)
mode = BMP085_ULTRAHIGHRES;
oversampling = mode;

Wire.begin();

if (read8(0xD0) != 0x55) return false;

/* read calibration data */
ac1 = read16(BMP085_CAL_AC1);
ac2 = read16(BMP085_CAL_AC2);
ac3 = read16(BMP085_CAL_AC3);
ac4 = read16(BMP085_CAL_AC4);
ac5 = read16(BMP085_CAL_AC5);
ac6 = read16(BMP085_CAL_AC6);

b1 = read16(BMP085_CAL_B1);
b2 = read16(BMP085_CAL_B2);

mb = read16(BMP085_CAL_MB);
mc = read16(BMP085_CAL_MC);
md = read16(BMP085_CAL_MD);
#if (BMP085_DEBUG == 1)
Serial.print("ac1 = "); Serial.println(ac1, DEC);
Serial.print("ac2 = "); Serial.println(ac2, DEC);
Serial.print("ac3 = "); Serial.println(ac3, DEC);
Serial.print("ac4 = "); Serial.println(ac4, DEC);
Serial.print("ac5 = "); Serial.println(ac5, DEC);
Serial.print("ac6 = "); Serial.println(ac6, DEC);

Serial.print("b1 = "); Serial.println(b1, DEC);
Serial.print("b2 = "); Serial.println(b2, DEC);

Serial.print("mb = "); Serial.println(mb, DEC);
Serial.print("mc = "); Serial.println(mc, DEC);
Serial.print("md = "); Serial.println(md, DEC);
#endif

return true;
}

int32_t Adafruit_BMP085::computeB5(int32_t UT) {
int32_t X1 = (UT - (int32_t)ac6) * ((int32_t)ac5) >> 15;
int32_t X2 = ((int32_t)mc << 11) / (X1+(int32_t)md);
return X1 + X2;
}

uint16_t Adafruit_BMP085::readRawTemperature(void) {
write8(BMP085_CONTROL, BMP085_READTEMPCMD);
delay(5);
#if BMP085_DEBUG == 1
Serial.print("Raw temp: "); Serial.println(read16(BMP085_TEMPDATA));
#endif
return read16(BMP085_TEMPDATA);
}

uint32_t Adafruit_BMP085::readRawPressure(void) {
uint32_t raw;

write8(BMP085_CONTROL, BMP085_READPRESSURECMD + (oversampling << 6));

if (oversampling == BMP085_ULTRALOWPOWER)
delay(5);
else if (oversampling == BMP085_STANDARD)
delay(8);
else if (oversampling == BMP085_HIGHRES)
delay(14);
else
delay(26);

raw = read16(BMP085_PRESSUREDATA);

raw <<= 8;
raw |= read8(BMP085_PRESSUREDATA+2);
raw >>= (8 - oversampling);

/* this pull broke stuff, look at it later?
if (oversampling==0) {
raw <<= 8;
raw |= read8(BMP085_PRESSUREDATA+2);
raw >>= (8 - oversampling);
}
*/

#if BMP085_DEBUG == 1
Serial.print("Raw pressure: "); Serial.println(raw);
#endif
return raw;
}


int32_t Adafruit_BMP085::readPressure(void) {
int32_t UT, UP, B3, B5, B6, X1, X2, X3, p;
uint32_t B4, B7;

UT = readRawTemperature();
UP = readRawPressure();

#if BMP085_DEBUG == 1
// use datasheet numbers!
UT = 27898;
UP = 23843;
ac6 = 23153;
ac5 = 32757;
mc = -8711;
md = 2868;
b1 = 6190;
b2 = 4;
ac3 = -14383;
ac2 = -72;
ac1 = 408;
ac4 = 32741;
oversampling = 0;
#endif

B5 = computeB5(UT);

#if BMP085_DEBUG == 1
Serial.print("X1 = "); Serial.println(X1);
Serial.print("X2 = "); Serial.println(X2);
Serial.print("B5 = "); Serial.println(B5);
#endif

// do pressure calcs
B6 = B5 - 4000;
X1 = ((int32_t)b2 * ( (B6 * B6)>>12 )) >> 11;
X2 = ((int32_t)ac2 * B6) >> 11;
X3 = X1 + X2;
B3 = ((((int32_t)ac1*4 + X3) << oversampling) + 2) / 4;

#if BMP085_DEBUG == 1
Serial.print("B6 = "); Serial.println(B6);
Serial.print("X1 = "); Serial.println(X1);
Serial.print("X2 = "); Serial.println(X2);
Serial.print("B3 = "); Serial.println(B3);
#endif

X1 = ((int32_t)ac3 * B6) >> 13;
X2 = ((int32_t)b1 * ((B6 * B6) >> 12)) >> 16;
X3 = ((X1 + X2) + 2) >> 2;
B4 = ((uint32_t)ac4 * (uint32_t)(X3 + 32768)) >> 15;
B7 = ((uint32_t)UP - B3) * (uint32_t)( 50000UL >> oversampling );

#if BMP085_DEBUG == 1
Serial.print("X1 = "); Serial.println(X1);
Serial.print("X2 = "); Serial.println(X2);
Serial.print("B4 = "); Serial.println(B4);
Serial.print("B7 = "); Serial.println(B7);
#endif

if (B7 < 0x80000000) {
p = (B7 * 2) / B4;
} else {
p = (B7 / B4) * 2;
}
X1 = (p >> 8) * (p >> 8);
X1 = (X1 * 3038) >> 16;
X2 = (-7357 * p) >> 16;

#if BMP085_DEBUG == 1
Serial.print("p = "); Serial.println(p);
Serial.print("X1 = "); Serial.println(X1);
Serial.print("X2 = "); Serial.println(X2);
#endif

p = p + ((X1 + X2 + (int32_t)3791)>>4);
#if BMP085_DEBUG == 1
Serial.print("p = "); Serial.println(p);
#endif
return p;
}

int32_t Adafruit_BMP085::readSealevelPressure(float altitude_meters) {
float pressure = readPressure();
return (int32_t)(pressure / pow(1.0-altitude_meters/44330, 5.255));
}

float Adafruit_BMP085::readTemperature(void) {
int32_t UT, B5; // following ds convention
float temp;

UT = readRawTemperature();

#if BMP085_DEBUG == 1
// use datasheet numbers!
UT = 27898;
ac6 = 23153;
ac5 = 32757;
mc = -8711;
md = 2868;
#endif

B5 = computeB5(UT);
temp = (B5+8) >> 4;
temp /= 10;

return temp;
}

float Adafruit_BMP085::readAltitude(float sealevelPressure) {
float altitude;

float pressure = readPressure();

altitude = 44330 * (1.0 - pow(pressure /sealevelPressure,0.1903));

return altitude;
}


/*********************************************************************/

uint8_t Adafruit_BMP085::read8(uint8_t a) {
uint8_t ret;

Wire.beginTransmission(BMP085_I2CADDR); // start transmission to device
#if (ARDUINO >= 100)
Wire.write(a); // sends register address to read from
#else
Wire.send(a); // sends register address to read from
#endif
Wire.endTransmission(); // end transmission

Wire.beginTransmission(BMP085_I2CADDR); // start transmission to device
Wire.requestFrom(BMP085_I2CADDR, 1);// send data n-bytes read
#if (ARDUINO >= 100)
ret = Wire.read(); // receive DATA
#else
ret = Wire.receive(); // receive DATA
#endif
Wire.endTransmission(); // end transmission

return ret;
}

uint16_t Adafruit_BMP085::read16(uint8_t a) {
uint16_t ret;

Wire.beginTransmission(BMP085_I2CADDR); // start transmission to device
#if (ARDUINO >= 100)
Wire.write(a); // sends register address to read from
#else
Wire.send(a); // sends register address to read from
#endif
Wire.endTransmission(); // end transmission

Wire.beginTransmission(BMP085_I2CADDR); // start transmission to device
Wire.requestFrom(BMP085_I2CADDR, 2);// send data n-bytes read
#if (ARDUINO >= 100)
ret = Wire.read(); // receive DATA
ret <<= 8;
ret |= Wire.read(); // receive DATA
#else
ret = Wire.receive(); // receive DATA
ret <<= 8;
ret |= Wire.receive(); // receive DATA
#endif
Wire.endTransmission(); // end transmission

return ret;
}

void Adafruit_BMP085::write8(uint8_t a, uint8_t d) {
Wire.beginTransmission(BMP085_I2CADDR); // start transmission to device
#if (ARDUINO >= 100)
Wire.write(a); // sends register address to read from
Wire.write(d); // write data
#else
Wire.send(a); // sends register address to read from
Wire.send(d); // write data
#endif
Wire.endTransmission(); // end transmission
}

Florian Asche
2014-06-11 19:00:36 UTC
Permalink
Hi,
)das hört sich schon mal gut an.

Ich werde mal schauen sobald ich Zeit finde,
ob im Ethersex Source ein entsprechendes Problem zu sehen ist.

Von deiner Beschreibung her passt das aber sehr gut.

Gruß Florian

-----Ursprüngliche Nachricht-----
Von: Stefan Teubel [mailto:***@sync-hv.de]
Gesendet: Dienstag, 10. Juni 2014 20:50
An: Florian Asche
Betreff: Re: [ethersex-devel] BMP085 mit unbrauchbaren Daten

Hallo Florian,

ich hatte das selbe Problem bei meiner eigenen Implementation für den BMP085.

Der Fehler liegt in den Datentypen, an einigen Stellen kann es zu Integerpromotion kommen, wodurch die im Datenblatt beschriebenen Datentypen nicht mehr ausreichen und es zu den Mondwerten kommt.

Den Ethersex Code habe ich mir noch nicht genau angeschaut, aber auf den ersten Blick dürfte das der Fehler sein.

Viele Grüße,

Stefan
e***@users.sourceforge.net
2014-06-12 09:57:53 UTC
Permalink
Hallo,
Post by Florian Asche
Ich werde mal schauen sobald ich Zeit finde,
ob im Ethersex Source ein entsprechendes Problem zu sehen ist.
Von deiner Beschreibung her passt das aber sehr gut.
...
Post by Florian Asche
Der Fehler liegt in den Datentypen, an einigen Stellen kann es zu Integerpromotion kommen,
wodurch die im Datenblatt beschriebenen Datentypen nicht mehr ausreichen und es zu den
Mondwerten kommt.
wie immer bei solchen Problemem gibt es zwei Optionen:

1) ihr kämpft euch selber durch und liefert die Korrektur in Form eines
Pull Requests auf Github

2) ihr spendet dem Ethersex-Entwicklerteam ein Examplar der Hardware

Letzterem sind z.B. die Erweiterungen für Multi-DHT zu verdanken.
Florian Asche
2014-08-26 14:15:06 UTC
Permalink
Hi,

 
nur noch mal zur Info...

 
der Bug wurde gefunden und behoben!

Siehe https://github.com/ethersex/ethersex/commit/bb9c079805473d0c8f35a5b7d752dab305b2c487

 
Danke fr den Tipp mit den Pullups. Ich habe bisher keine im Einsatz.

 
Gru Florian

 
Von: reiner [mailto:***@netzadmins.de]
Gesendet: Sonntag, 24. August 2014 11:13
An: Florian Asche; ***@users.sourceforge.net
Cc: ethersex-***@list.zerties.org
Betreff: Re: [ethersex-devel] BMP085 mit unbrauchbaren Daten - UrsacheN & LsungEN .cpp .h example

 
 
Am 23.05.2014 um 23:50 schrieb Florian Asche:


Hi,


 

konnte das Problem leider nicht wirklich eingrenzen.


:/


 

Gru Flo


 

-----Ursprngliche Nachricht-----


Von: ***@users.sourceforge.net <mailto:***@users.sourceforge.net> [mailto:***@users.sourceforge.net <mailto:***@users.sourceforge.net> ]


Gesendet: Freitag, 22. November 2013 08:06


An: Florian Asche


Cc: reiner; ethersex-***@list.zerties.org <mailto:ethersex-***@list.zerties.org>


Betreff: Re: [ethersex-devel] BMP085 mit unbrauchbaren Daten


 

Hallo Florian,


 

ich habe den BMP085 inzwischen mit einem anderen Sourcecode (Bascom)


getestet, dort funktioniert er mit Erfolg. Das Problem liegt also bei Ethersex.


 

Patch willkommen.


 

 

Nachdem ich nun ein breadboard habe und mal eben vernnftige Tests machen kann anstelle der Net-IO Krokoklemkrmpfe ....

Mit Arduino Mini einen BMP085 via I2C Bus mit je zwei mal 10k pullups!!! nach vcc siehe

Example.ino
Adafruit_BMP085.h
Adafruit_BMP085.cpp

Ursachen bzw. Nebenbedingungen:
Ohne die Pullups bei I2C nur Schrott. Hngt von der individuellen Schaltung ab in der man arbeitet ob die bereits drin sind oder nicht und ist immer im Einzelfall zu prfen. Ob das mit 5k oder 15k geht weiss ich auch nicht, testen testen .....
Nchste Besonderheit beim BMP085:
BMP085 arbeitet NATIV mit 3.3 Volt !!!!
Mein Modul - gesponsort von Wody2001 - hat einen Miniregler onboard so das es mit 5 Volt arbeitet!!!! Ich  habe das erst gar nicht bemerkt da sooooo klitzeklein und war dadurch auch nie auf der grnen Seite was die Arbeitsbedingungen angeht.

Mein Teil macht jetzt jedenfalls sauber das was es soll. Habe fr den Fall der F_e_lle mal dazu gepackt.  Mich wrde interessieren ob es an den elektrischen Bedingungen oder am Code liegt bei Ethersex.

BTW hat jemand einen DS75 dazu bringen knnen mit mehr als 9 Bit Genauigkeit zu arbeiten?
Der DS75 hat lt. Datenblatt im gegensatz zum LM75 eine programmierbare Auflsung im Konfigregister Bit 5 und 7.
Ich kann das Register setzen wie ich will (default immer 0 nach einschalten) 0x20 = 10 Bit, 0x40 = 11Bit oder 0x60= 12 Bit resolution aber ich bekomme immer nur 0,5 Grad Sprnge raus.
Irgend jemand da schon mal erfolg gehabt oder mache ich da einen Denkfehler?
Suche auch noch Infos um eine Arduino mini  (ist so praktisch auf kleiner Platine fertig zum spottpreis) im low power mode laufen zu lassen wegen Solarbetrieb und Solarmessungen. Mchte die Panels mglichst klein halten bzw. mit einem 2*2cm Panel auskommen fr alles.


MfG
Reiner


Example.ino:
#######################################################
/* An Arduino Mini and BMP085 and a 4*20 LCD. To put Data to LCD you have to convert to string!
to get the correct altitude you have to pass the actual barometric pressure in PASCAL not hektopascal!! along with the call.
*/
#include <LiquidCrystal.h>
const int numRows = 4;
const int numCols = 20;

LiquidCrystal lcd(12, 11, 5, 4, 3, 2);    // Pinbelegung LCD definieren hier 4draht = Nibble

#include <Wire.h>                            // I2C einbinden
#include <Adafruit_BMP085.h>        // Adafruit Bibliothek einbinden

#define bmp85Adresse 0x77     // Andresse unter der ein BMP85 zu erreichen ist

Adafruit_BMP085 bmp;               // Variable fr Adafruit Lib definieren

char dataString[7];           // gelesene Daten als String aufbereitet: (-xx)x.x
double temp;                    // gelesene Temperatur als double
double druck;                   // gelesener Druck bzw. Hhe als double
float high;                        // geleseene Hoehe als float
int i;                                 // Zhlvariable um das Display jeden100. loop zu lschen um Dezimalverschiebungen zu bereinigen

void setup() {
  lcd.begin(numCols,numRows);
  lcd.setCursor(0,0);
  lcd.write("  Temperatur und ");
  lcd.setCursor(0,1);
  lcd.write("Luftdruck von BMP085");
  lcd.setCursor(0,3);
  lcd.write(" C by Netzadmins.de");
  delay(10000);
  lcd.clear();

  Serial.begin(9600);

  // Sensor BMP085 initialisieren
 if (!bmp.begin()) {
  Serial.println("Keinen gltigen BMP085 Sensor gefunden!");
  while (true) {}
 }
  Wire.begin();
}

void loop() 

 for (i = 1; i<=100; i++) { 
 Serial.print("Temperatur: ");
// readTemperature() Temperatur C auslesen und anzeigen
 Serial.print(bmp.readTemperature());
 Serial.print(" ");  // Hier mssen wir ein wenig tricksen
 Serial.write(176);  // um das -Zeichen korrekt darzustellen
 Serial.println("C");
 
  temp=bmp.readTemperature();
  dtostrf(temp, 4, 1, dataString);        //dtostrf(floatVar, minStringWidthIncDecimalPoint, numVarsAfterDecimal, charBuf); (standard avr-libc function)
  lcd.setCursor(0,0);
  lcd.write(dataString);
  lcd.write("    Grad Celsius");

 Serial.print("Luftdruck: ");
// readPressure() Luftdruck in Pa auslesen und anzeigen
 druck = bmp.readPressure();
 Serial.print(druck);
 Serial.print(" Pa =   ");
 druck = druck / 100;
 Serial.print(druck);
 Serial.println(" hektoPascal");

  druck=bmp.readPressure();
  dtostrf(druck, 4, 1, dataString);        //dtostrf(floatVar, minStringWidthIncDecimalPoint, numVarsAfterDecimal, charBuf); (standard avr-libc function)
  lcd.setCursor(0,1);
  lcd.write(dataString);
  lcd.write("      Pascal");
  druck=druck/100;
  dtostrf(druck, 4, 2, dataString);        //dtostrf(floatVar, minStringWidthIncDecimalPoint, numVarsAfterDecimal, charBuf); (standard avr-libc function)
  lcd.setCursor(0,2);
  lcd.write(dataString);
  lcd.write("  hektoPascal");

 Serial.print("Hoehe: ");
 // readAltitude() Hhe in meter auslesen und anzeigen
 high = bmp.readAltitude(101500);
 Serial.print(high);
 Serial.println(" Meter");

  dtostrf(high, 4, 2, dataString);        //dtostrf(floatVar, minStringWidthIncDecimalPoint, numVarsAfterDecimal, charBuf); (standard avr-libc function)
  lcd.setCursor(0,3);
  lcd.write(dataString);
  lcd.write("     m Altitude");
 
 Serial.println(); // Leerzeile anzeigen
 delay(200);      // 0,2 Sekunden warten
}
if (i=99) {
  lcd.clear();
}
}

#######################################################

Adafruit_BMP085.h:
/***************************************************
  This is a library for the Adafruit BMP085/BMP180 Barometric Pressure + Temp sensor

  Designed specifically to work with the Adafruit BMP085 or BMP180 Breakout
  ----> http://www.adafruit.com/products/391 <http://www.adafruit.com/products/391>
  ----> http://www.adafruit.com/products/1603 <http://www.adafruit.com/products/1603>

  These displays use I2C to communicate, 2 pins are required to 
  interface
  Adafruit invests time and resources providing this open source code,
  please support Adafruit and open-source hardware by purchasing
  products from Adafruit!

  Written by Limor Fried/Ladyada for Adafruit Industries. 
  BSD license, all text above must be included in any redistribution
 ****************************************************/

#ifndef ADAFRUIT_BMP085_H
#define ADAFRUIT_BMP085_H

#if (ARDUINO >= 100)
 #include "Arduino.h"
#else
 #include "WProgram.h"
#endif
#include "Wire.h"

#define BMP085_DEBUG 0

#define BMP085_I2CADDR 0x77

#define BMP085_ULTRALOWPOWER 0
#define BMP085_STANDARD      1
#define BMP085_HIGHRES       2
#define BMP085_ULTRAHIGHRES  3
#define BMP085_CAL_AC1           0xAA  // R   Calibration data (16 bits)
#define BMP085_CAL_AC2           0xAC  // R   Calibration data (16 bits)
#define BMP085_CAL_AC3           0xAE  // R   Calibration data (16 bits)   
#define BMP085_CAL_AC4           0xB0  // R   Calibration data (16 bits)
#define BMP085_CAL_AC5           0xB2  // R   Calibration data (16 bits)
#define BMP085_CAL_AC6           0xB4  // R   Calibration data (16 bits)
#define BMP085_CAL_B1            0xB6  // R   Calibration data (16 bits)
#define BMP085_CAL_B2            0xB8  // R   Calibration data (16 bits)
#define BMP085_CAL_MB            0xBA  // R   Calibration data (16 bits)
#define BMP085_CAL_MC            0xBC  // R   Calibration data (16 bits)
#define BMP085_CAL_MD            0xBE  // R   Calibration data (16 bits)

#define BMP085_CONTROL           0xF4
#define BMP085_TEMPDATA          0xF6
#define BMP085_PRESSUREDATA      0xF6
#define BMP085_READTEMPCMD          0x2E
#define BMP085_READPRESSURECMD            0x34


class Adafruit_BMP085 {
 public:
  Adafruit_BMP085();
  boolean begin(uint8_t mode = BMP085_ULTRAHIGHRES);  // by default go highres
  float readTemperature(void);
  int32_t readPressure(void);
  int32_t readSealevelPressure(float altitude_meters = 0);
  float readAltitude(float sealevelPressure = 101325); // std atmosphere
  uint16_t readRawTemperature(void);
  uint32_t readRawPressure(void);
 
 private:
  int32_t computeB5(int32_t UT);
  uint8_t read8(uint8_t addr);
  uint16_t read16(uint8_t addr);
  void write8(uint8_t addr, uint8_t data);

  uint8_t oversampling;

  int16_t ac1, ac2, ac3, b1, b2, mb, mc, md;
  uint16_t ac4, ac5, ac6;
};


#endif //  ADAFRUIT_BMP085_H

#######################################################

Adafruit_BMP085.cpp:
/***************************************************
  This is a library for the Adafruit BMP085/BMP180 Barometric Pressure + Temp sensor

  Designed specifically to work with the Adafruit BMP085 or BMP180 Breakout
  ----> http://www.adafruit.com/products/391 <http://www.adafruit.com/products/391>
  ----> http://www.adafruit.com/products/1603 <http://www.adafruit.com/products/1603>

  These displays use I2C to communicate, 2 pins are required to 
  interface
  Adafruit invests time and resources providing this open source code,
  please support Adafruit and open-source hardware by purchasing
  products from Adafruit!

  Written by Limor Fried/Ladyada for Adafruit Industries. 
  BSD license, all text above must be included in any redistribution
 ****************************************************/

#include "Adafruit_BMP085.h"

Adafruit_BMP085::Adafruit_BMP085() {
}


boolean Adafruit_BMP085::begin(uint8_t mode) {
  if (mode > BMP085_ULTRAHIGHRES)
    mode = BMP085_ULTRAHIGHRES;
  oversampling = mode;

  Wire.begin();

  if (read8(0xD0) != 0x55) return false;

  /* read calibration data */
  ac1 = read16(BMP085_CAL_AC1);
  ac2 = read16(BMP085_CAL_AC2);
  ac3 = read16(BMP085_CAL_AC3);
  ac4 = read16(BMP085_CAL_AC4);
  ac5 = read16(BMP085_CAL_AC5);
  ac6 = read16(BMP085_CAL_AC6);

  b1 = read16(BMP085_CAL_B1);
  b2 = read16(BMP085_CAL_B2);

  mb = read16(BMP085_CAL_MB);
  mc = read16(BMP085_CAL_MC);
  md = read16(BMP085_CAL_MD);
#if (BMP085_DEBUG == 1)
  Serial.print("ac1 = "); Serial.println(ac1, DEC);
  Serial.print("ac2 = "); Serial.println(ac2, DEC);
  Serial.print("ac3 = "); Serial.println(ac3, DEC);
  Serial.print("ac4 = "); Serial.println(ac4, DEC);
  Serial.print("ac5 = "); Serial.println(ac5, DEC);
  Serial.print("ac6 = "); Serial.println(ac6, DEC);

  Serial.print("b1 = "); Serial.println(b1, DEC);
  Serial.print("b2 = "); Serial.println(b2, DEC);

  Serial.print("mb = "); Serial.println(mb, DEC);
  Serial.print("mc = "); Serial.println(mc, DEC);
  Serial.print("md = "); Serial.println(md, DEC);
#endif

  return true;
}

int32_t Adafruit_BMP085::computeB5(int32_t UT) {
  int32_t X1 = (UT - (int32_t)ac6) * ((int32_t)ac5) >> 15;
  int32_t X2 = ((int32_t)mc << 11) / (X1+(int32_t)md);
  return X1 + X2;
}

uint16_t Adafruit_BMP085::readRawTemperature(void) {
  write8(BMP085_CONTROL, BMP085_READTEMPCMD);
  delay(5);
#if BMP085_DEBUG == 1
  Serial.print("Raw temp: "); Serial.println(read16(BMP085_TEMPDATA));
#endif
  return read16(BMP085_TEMPDATA);
}

uint32_t Adafruit_BMP085::readRawPressure(void) {
  uint32_t raw;

  write8(BMP085_CONTROL, BMP085_READPRESSURECMD + (oversampling << 6));

  if (oversampling == BMP085_ULTRALOWPOWER)
    delay(5);
  else if (oversampling == BMP085_STANDARD)
    delay(8);
  else if (oversampling == BMP085_HIGHRES)
    delay(14);
  else
    delay(26);

  raw = read16(BMP085_PRESSUREDATA);

  raw <<= 8;
  raw |= read8(BMP085_PRESSUREDATA+2);
  raw >>= (8 - oversampling);

 /* this pull broke stuff, look at it later?
  if (oversampling==0) {
    raw <<= 8;
    raw |= read8(BMP085_PRESSUREDATA+2);
    raw >>= (8 - oversampling);
  }
 */

#if BMP085_DEBUG == 1
  Serial.print("Raw pressure: "); Serial.println(raw);
#endif
  return raw;
}


int32_t Adafruit_BMP085::readPressure(void) {
  int32_t UT, UP, B3, B5, B6, X1, X2, X3, p;
  uint32_t B4, B7;

  UT = readRawTemperature();
  UP = readRawPressure();

#if BMP085_DEBUG == 1
  // use datasheet numbers!
  UT = 27898;
  UP = 23843;
  ac6 = 23153;
  ac5 = 32757;
  mc = -8711;
  md = 2868;
  b1 = 6190;
  b2 = 4;
  ac3 = -14383;
  ac2 = -72;
  ac1 = 408;
  ac4 = 32741;
  oversampling = 0;
#endif

  B5 = computeB5(UT);

#if BMP085_DEBUG == 1
  Serial.print("X1 = "); Serial.println(X1);
  Serial.print("X2 = "); Serial.println(X2);
  Serial.print("B5 = "); Serial.println(B5);
#endif

  // do pressure calcs
  B6 = B5 - 4000;
  X1 = ((int32_t)b2 * ( (B6 * B6)>>12 )) >> 11;
  X2 = ((int32_t)ac2 * B6) >> 11;
  X3 = X1 + X2;
  B3 = ((((int32_t)ac1*4 + X3) << oversampling) + 2) / 4;

#if BMP085_DEBUG == 1
  Serial.print("B6 = "); Serial.println(B6);
  Serial.print("X1 = "); Serial.println(X1);
  Serial.print("X2 = "); Serial.println(X2);
  Serial.print("B3 = "); Serial.println(B3);
#endif

  X1 = ((int32_t)ac3 * B6) >> 13;
  X2 = ((int32_t)b1 * ((B6 * B6) >> 12)) >> 16;
  X3 = ((X1 + X2) + 2) >> 2;
  B4 = ((uint32_t)ac4 * (uint32_t)(X3 + 32768)) >> 15;
  B7 = ((uint32_t)UP - B3) * (uint32_t)( 50000UL >> oversampling );

#if BMP085_DEBUG == 1
  Serial.print("X1 = "); Serial.println(X1);
  Serial.print("X2 = "); Serial.println(X2);
  Serial.print("B4 = "); Serial.println(B4);
  Serial.print("B7 = "); Serial.println(B7);
#endif

  if (B7 < 0x80000000) {
    p = (B7 * 2) / B4;
  } else {
    p = (B7 / B4) * 2;
  }
  X1 = (p >> 8) * (p >> 8);
  X1 = (X1 * 3038) >> 16;
  X2 = (-7357 * p) >> 16;

#if BMP085_DEBUG == 1
  Serial.print("p = "); Serial.println(p);
  Serial.print("X1 = "); Serial.println(X1);
  Serial.print("X2 = "); Serial.println(X2);
#endif

  p = p + ((X1 + X2 + (int32_t)3791)>>4);
#if BMP085_DEBUG == 1
  Serial.print("p = "); Serial.println(p);
#endif
  return p;
}

int32_t Adafruit_BMP085::readSealevelPressure(float altitude_meters) {
  float pressure = readPressure();
  return (int32_t)(pressure / pow(1.0-altitude_meters/44330, 5.255));
}

float Adafruit_BMP085::readTemperature(void) {
  int32_t UT, B5;     // following ds convention
  float temp;

  UT = readRawTemperature();

#if BMP085_DEBUG == 1
  // use datasheet numbers!
  UT = 27898;
  ac6 = 23153;
  ac5 = 32757;
  mc = -8711;
  md = 2868;
#endif

  B5 = computeB5(UT);
  temp = (B5+8) >> 4;
  temp /= 10;
 
  return temp;
}

float Adafruit_BMP085::readAltitude(float sealevelPressure) {
  float altitude;

  float pressure = readPressure();

  altitude = 44330 * (1.0 - pow(pressure /sealevelPressure,0.1903));

  return altitude;
}


/*********************************************************************/

uint8_t Adafruit_BMP085::read8(uint8_t a) {
  uint8_t ret;

  Wire.beginTransmission(BMP085_I2CADDR); // start transmission to device
#if (ARDUINO >= 100)
  Wire.write(a); // sends register address to read from
#else
  Wire.send(a); // sends register address to read from
#endif
  Wire.endTransmission(); // end transmission
 
  Wire.beginTransmission(BMP085_I2CADDR); // start transmission to device
  Wire.requestFrom(BMP085_I2CADDR, 1);// send data n-bytes read
#if (ARDUINO >= 100)
  ret = Wire.read(); // receive DATA
#else
  ret = Wire.receive(); // receive DATA
#endif
  Wire.endTransmission(); // end transmission

  return ret;
}

uint16_t Adafruit_BMP085::read16(uint8_t a) {
  uint16_t ret;

  Wire.beginTransmission(BMP085_I2CADDR); // start transmission to device
#if (ARDUINO >= 100)
  Wire.write(a); // sends register address to read from
#else
  Wire.send(a); // sends register address to read from
#endif
  Wire.endTransmission(); // end transmission
 
  Wire.beginTransmission(BMP085_I2CADDR); // start transmission to device
  Wire.requestFrom(BMP085_I2CADDR, 2);// send data n-bytes read
#if (ARDUINO >= 100)
  ret = Wire.read(); // receive DATA
  ret <<= 8;
  ret |= Wire.read(); // receive DATA
#else
  ret = Wire.receive(); // receive DATA
  ret <<= 8;
  ret |= Wire.receive(); // receive DATA
#endif
  Wire.endTransmission(); // end transmission

  return ret;
}

void Adafruit_BMP085::write8(uint8_t a, uint8_t d) {
  Wire.beginTransmission(BMP085_I2CADDR); // start transmission to device
#if (ARDUINO >= 100)
  Wire.write(a); // sends register address to read from
  Wire.write(d);  // write data
#else
  Wire.send(a); // sends register address to read from
  Wire.send(d);  // write data
#endif
  Wire.endTransmission(); // end transmission
}
Loading...