BMP085 Drucksensor auslesen (ProMini)

ApoC

Moderator
#1
Moin

Habe an meinem Copter (ProMini) einen BMP085 Drucksensor. Nur zeigt der mir immer komische Werte an.

Darum will ich den testen.

N neuen Ardu habe ich hier, auch den BMP, aber kein Plan, wie das gehen soll, da ich im Ardu Code (noch)nicht fit bin.

Habe folgenden Codeschnipsel, aber kein Plan, wie ich dem Ardu nun sage, das er die Pins als I²C nehmen soll, die wir auch beim Copter haben.

Also ich möchte meinen Test Arduino auf mein Breadboard packen, den BMP anschliessen und dann mit dem Code auf der Serial Konsole gucken, was da rauskommt. Nicht über die GUI der Multiwii.

Ich sehe im Code nix, wo ich dem Ardu sage, an welchen Pins der I²C Sensor hängt. (oder uebersehe ich das?)

Hier der Code:

Code:
#include <Wire.h>

#define I2C_ADDRESS 0x77 //77?

const unsigned char oversampling_setting = 3; //oversamplig for measurement
const unsigned char pressure_waittime[4] = { 5, 8, 14, 26 };

//just taken from the BMP085 datasheet
int ac1;
int ac2; 
int ac3; 
unsigned int ac4;
unsigned int ac5;
unsigned int ac6;
int b1; 
int b2;
int mb;
int mc;
int md;


void setup()
{  
  Serial.begin(9600);  // start serial for output
  Serial.println("Setting up BMP085");
  Wire.begin();
  bmp085_get_cal_data();
}
void bmp085_read_temperature_and_pressure(int& temperature, long& pressure);
void loop()
{
  int  temperature = 0;
  long pressure = 0;

  bmp085_read_temperature_and_pressure(&temperature,&pressure);
  Serial.print(temperature,DEC);
  Serial.print(" ");
  Serial.print(pressure,DEC);
  Serial.println();
  delay(100);
}

void bmp085_read_temperature_and_pressure(int* temperature, long* pressure) {
  int  ut= bmp085_read_ut();
  long up = bmp085_read_up();
   long x1, x2, x3, b3, b5, b6, p;
   unsigned long b4, b7;

   //calculate the temperature
   x1 = ((long)ut - ac6) * ac5 >> 15;
   x2 = ((long) mc << 11) / (x1 + md);
   b5 = x1 + x2;
   *temperature = (b5 + 8) >> 4;
   
   //calculate the pressure
   b6 = b5 - 4000;
   x1 = (b2 * (b6 * b6 >> 12)) >> 11; 
   x2 = ac2 * b6 >> 11;
   x3 = x1 + x2;
   b3 = (((int32_t) ac1 * 4 + x3)<<oversampling_setting + 2) >> 2;
   x1 = ac3 * b6 >> 13;
   x2 = (b1 * (b6 * b6 >> 12)) >> 16;
   x3 = ((x1 + x2) + 2) >> 2;
   b4 = (ac4 * (uint32_t) (x3 + 32768)) >> 15;
   b7 = ((uint32_t) up - b3) * (50000 >> oversampling_setting);
   p = b7 < 0x80000000 ? (b7 * 2) / b4 : (b7 / b4) * 2;
   
   x1 = (p >> 8) * (p >> 8);
   x1 = (x1 * 3038) >> 16;
   x2 = (-7357 * p) >> 16;
   *pressure = p + ((x1 + x2 + 3791) >> 4);

}


unsigned int bmp085_read_ut() {
  write_register(0xf4,0x2e);
  delay(5); //longer than 4.5 ms
  return read_int_register(0xf6);
}

void  bmp085_get_cal_data() {
  Serial.println("Reading Calibration Data");
  ac1 = read_int_register(0xAA);
  Serial.print("AC1: ");
  Serial.println(ac1,DEC);
  ac2 = read_int_register(0xAC);
  Serial.print("AC2: ");
  Serial.println(ac2,DEC);
  ac3 = read_int_register(0xAE);
  Serial.print("AC3: ");
  Serial.println(ac3,DEC);
  ac4 = read_int_register(0xB0);
  Serial.print("AC4: ");
  Serial.println(ac4,DEC);
  ac5 = read_int_register(0xB2);
  Serial.print("AC5: ");
  Serial.println(ac5,DEC);
  ac6 = read_int_register(0xB4);
  Serial.print("AC6: ");
  Serial.println(ac6,DEC);
  b1 = read_int_register(0xB6);
  Serial.print("B1: ");
  Serial.println(b1,DEC);
  b2 = read_int_register(0xB8);
  Serial.print("B2: ");
  Serial.println(b1,DEC);
  mb = read_int_register(0xBA);
  Serial.print("MB: ");
  Serial.println(mb,DEC);
  mc = read_int_register(0xBC);
  Serial.print("MC: ");
  Serial.println(mc,DEC);
  md = read_int_register(0xBE);
  Serial.print("MD: ");
  Serial.println(md,DEC);
}


long bmp085_read_up() {
  write_register(0xf4,0x34+(oversampling_setting<<6));
  delay(pressure_waittime[oversampling_setting]);
  
  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);
}

void write_register(unsigned char r, unsigned char v)
{
  Wire.beginTransmission(I2C_ADDRESS);
  Wire.send(r);
  Wire.send(v);
  Wire.endTransmission();
}

char read_register(unsigned char r)
{
  unsigned char v;
  Wire.beginTransmission(I2C_ADDRESS);
  Wire.send(r);  // register to read
  Wire.endTransmission();

  Wire.requestFrom(I2C_ADDRESS, 1); // read a byte
  while(!Wire.available()) {
    // waiting
  }
  v = Wire.receive();
  return v;
}

int read_int_register(unsigned char r)
{
  unsigned char msb, lsb;
  Wire.beginTransmission(I2C_ADDRESS);
  Wire.send(r);  // register to read
  Wire.endTransmission();

  Wire.requestFrom(I2C_ADDRESS, 2); // read a byte
  while(!Wire.available()) {
    // waiting
  }
  msb = Wire.receive();
  while(!Wire.available()) {
    // waiting
  }
  lsb = Wire.receive();
  return (((int)msb<<8) | ((int)lsb));
}
Was muss ich nun ändern, damit ich die BMP Daten auf der Konsole sehe?
 
#2
Zum lesen musst Du ein ((I2C_ADDRESS)+1) machen ;)

In TWI_common ist es bei Multiwii integriert.
Pinbelegung I2C ist duch den Compiller und das CPU-Layout auf die üblichen Verdächtigen bestimmt .

Was meinst Du mit komischen Werten ?
Treppensteigen, Zucken oder Kurven ?
 

ApoC

Moderator
#3
Hey Ben

Habe nochmal etwas mehr gelesen und festgestellt, das durch die wire.h die Pins festgelegt sind. Quelle: http://www.arduino.cc/en/Reference/Wire

Also SDA ist AnalogInput 4 und SCL ist AnalogInput 5. Da wir die wire.h auch beim Arducode benutzen, ist das gleich belegt. Kann also den Testardu sogar aufs Paris basteln, ohne was ändern zu müssen. Zum Testen reichts.

Nun, er macht Treppen (das ist ja der Filter). Das Originalsignal (Debug 1) sieht aus wie die Ausschläge eines Seismographen. Also dicke fette Spitzen mit grosser Amplitude. Mache nacher mal n Bild.

Weiterhin zeigt er mir immer negative Werte an. Nie Postitiv. Zb: -150,54 im Moment. Auch schwanken die Werte massiv, auch ohne das ich den Copter bewege.

Sensor ist eingepackt in Schaumstoff lichtdicht und windgeschuetzt.
 

JUERGEN_

Generation 60++
#5
.
mit weitaus geringerem rauschen, kommt der neue MS5611-01BA01 daher.
- > http://www.sander-electronic.de/be00067.html
 

ApoC

Moderator
#6
kalle123 hat gesagt.:
Bei mir sieht das so aus.

5 min, je Sekunde ein Wert.

Das Verhalten ist aber absolut normal für den BMP085.

Gruß KH
Wie hast du das aufgezeichnet?
 

JUERGEN_

Generation 60++
#8
.
ist die frage, hat der Sensor eine eigene Spannungsstabilisierung,

oder hängt er gar an D12[size=large] ?[/size]

:rot:
 

ApoC

Moderator
#9
Habn Parisboard, er hängt also an der LV (3,3V) Seite. Die 3,3V liegen auch an. Onboard Pullups sind aktiviert, im Sketch auskommentiert. (Also draussen)
 

kalle123

Jugend forscht ....
#10
Hab den sketch hier genommen.

http://www.ladyada.net/learn/sensors/bmp085.html

Alles auskommentiert bis auf Serial.print(bmp.readAltitude(101500));

Abtastung 1000 statt 500, aktuellen Luftdruck eingefügt und 5 min im terminal laufen gelassen.

Daten dann nach Excel (LibreOffice) kopiert. Feddig :)
 
#11
Wenn der BMP85 derartige Werte Anzeigt weis ich immer das ich nen Fehler auf dem I2c oder mit den I2C Komponenten hab bzw. irgend wo nen Fehler im Code hab.

Sieht irgendwie nach einem Pullup-Problem aus.
Viele Boards und Bauteile haben viel zu hohe F-Werte der Tantal zu den Sensoren.

Wir haben bei unseren Boards festgestellt das die von der Herstellern angegebenen Werte der Kondensatoren schlicht zu hoch sind und man für gute Werte auf teilweise unter ein µF muss.Bei selbstgestrickten i2c Bussen hab ich das mittlerweile auch schon festgestellt. - da brachten Veränderungen der Kabellängen schon Wunder (Was eigentlich nicht sein darf..). Ich denke nicht das der BMP defekt ist. Hast Du einen WMP mit in der Schleife bei denen kan man Pech haben und die nehmen sehr viel Leistung auf. Hab hier 3 Stück - einer ist so hops gegangen, einer funktioniert und der mit dem hohen Widerstand spinnt.Hab von anderen erfahren das die auch WMPs mit hohem innenwiderstand hatten und dann einen brauchbaren erhalten haben - da schinen große fluktuatione drin zu sein - da mach mit acc kein Problem sein - aber je mehr Sensoren man in die Schleife hängt um so ernster werden dieise Probleme - und ein Teilnehmer mit riesen Innenwiederstand wirkt mit den anderen zusammen wie eine kettenreaktion.

Ich würde hier einen LLC reinhängen..

Aus diesem Grund verwende ich bei mehr als ACC und Gyro grundsätzlich vollständige IMU-Boards.Bei aktueller Preisentwicklung rechnet es sich eh nicht mehr mit nem WMP oder Einzelsensoren zu arbeiten... ne IMU nach Gusto und Ruhe.Nur einmal Pqorto , keine Sauerei und kein Gefummel.Die IMU muss ja nicht gleich 100,-kosten...das gibt es auch günstiger - so ab 59,- mit allen 4 Sensoren was fair ist.

Wenn man auf ACC angewiesen ist kommt sowieso nur der ADXL 345 oder eine 3x ADXL 340 in Frage.Da könenn die BMAs nicht mithalten.Der 20er ist zu Grob und der 18er ist zu dumm bei starken Neigungen.

Nicht vergesen: Paralellschaltungen von Komponenten am I2C führt auch zur Parallelschalung von Widerständen der Komponenten!!!Je nach Betriebszustand sogar veränderlich.
 
#12
Hey Ben

Danke fuer deine ausfuehrliche Antwort. Darum möchte ich ja den BMP mal einzeln messen, ohne irgendwelche anderen I²C Slaves.

Ich nutze die Pullups vom Parisboard, weil die einfach bessere Werte liefern, als die im Sketch. Einen LLC habe ich schon aufm Paris, welcher ja auch benutzt wird, da ich ja 3,3V und 5V Sensoren habe.

Ich habe weiterhin einen HMC5843, einen BMA020 und das WMP original mit am I²C Bus hängen. Aber selbst wenn ich alles auskommentiere und ablöte, habe ich diese Werte.

Vielleicht hat er tatsaechlich das Zeitliche gesegnet....

Ich kann mich erinnern, das er aber mal entsprechende Plus Werte angezeigt hat, also um die 100m.
 
#13
Ach- der funktionierte schon mal .. oh!

Zu nah mit nem Magneten oder mit Vcc and das Gehäuse des Sensors gekommen ?

Hab hier noch nen 5843 und nen BMP085 rumfliegen die daran das Zeitliche gesegnet haben..Motor aus der Hand gerutscht...
 
#14
Soooo, dank Kalle konnte ich meinen BMP testen. Das Ergebnis kann sich sehen lassen, denn Magdeburg liegt hier so um die 40 - 60m ueber NN, jeh nach Lage eben.

Kommt also hin. Damit stimmt die -41m in der GUI, denn das ist der Wert ohne die Seehöhen Korrektur. Nun müsste man diese Korrektur nur in den Code mit einbauen, dann passen die Werte wieder.

Nur wie bringe ich dem Ardu das bei? Müsste doch auch mit der BMP Libary gehen, oder nicht?


 

Anhänge

#16
Hey

Hier der "Kalle Mitschnitt". ;)

9581
 

Anhänge

#17
Schon sehr interessant was da hinten raus kommt -freut mich das der allem anschein nach nicht hinüber ist .
 
#18
Jo Ben, mich freut das auch. Leider sind die Fähigkeiten des Copters in der Haltung der Höhe eher bescheiden, wenn nicht sogar fast garnicht möglich. Trotzdem, das der Sensor eigentlich richtig misst.
 
FPV1

Banggood

Oben Unten