Forum: Mikrocontroller und Digitale Elektronik BMP085 Problem mit Codevision


von Wolfgang S. (Gast)


Lesenswert?

Hallo,
ich wende mich an alle, die wie ich mit Codevision programmieren.
Ich habe das Problem, dass ich schon zu Beginn nicht mal die Calibration
Werte des BMP085 über I2C auslesen kann.
Die Read-Routine habe ich aus der Hilfe Datei von Codevision (Beispiel 
Lesen EEPROM-Daten) übernomen.
Resultat: Ich habe u.a. mit dieser Routine die Werte aus einem Pollin 
Kompassmodul (HDMM01) problemlos lesen können. Nach den 
Berechnungsvorgaben wird dann tatsächlich aus den ausgelesenen Daten der 
richtige Winkelwert ausgegeben.
Das Problem ist die I2c-Übertragung: Auf den Oszilloskop ist deutlich zu 
sehen, dass die Geräteadresse (0xEE), die (BMP085-EEPROM-) Adresse 
(0xAA) und dann die Geräteadresse mit gesetztem Read-Bit (0xEF) 
übertragen wird. Dann ist die Datenleitung aber bis zum Ende auf H- 
(3,3V) Signal.
Die Anschlüsse sind richtig, als Spannung verwende ich 3,3V, Pull-up 
Widerstände sind natürlich vorhanden.
Ist das I2C-Protokoll anders auszulegen ?

Für einen Tipp wäre ich echt dankbar!

von Peter Z. (hangloose)


Lesenswert?

code zeigen...

von Davis (Gast)


Lesenswert?

Schaltplan & Programm posten ...

von Wolfgang S. (Gast)


Lesenswert?

#define BMP085_ADDRESS 0xEE     // Device Address

// Declare your global variables here

//****************************************************
//**** Write one byte to BMP085 **********************
//****************************************************
void m_write(char address, char data)
 {
 i2c_start();                   // start xmission
 i2c_write (0xEE);              // send module address
 i2c_write (address);           // send address
 i2c_write (data);              // send data
 i2c_stop();                    // stop xmission
 }

//****************************************************
//**** Read one byte from BMP085 *********************
//****************************************************
char  m_read(char address)
 {
 char data;
 i2c_start();                   // start xmission
 i2c_write (0xEE);              // send module address
 i2c_write (address);           // send address
 i2c_start();
 i2c_write (0xEF);              // send bit0 set to one,
                                // that means a read cycle
                                // from BMP085 should be
                                // initiated
 //*******************************************************
 //** Note: the 0 in i2c_read (0) means, that the master
 // ends communication by not sending "Acknowledge" !!!!
 //*******************************************************
 data=i2c_read(0);              // read data from BMP085
 i2c_stop();                    // stop xmission
 return data;
 }
// Declare your global variables here

void main(void)
{
// Declare your local variables here

// Port A initialization
PORTA=0x00;
DDRA=0xFF;
// Port B initialization
// PB0: SCL
// PB1: SDA
PORTB=0x00;
DDRB=0xFD;
// Port C initialization
PORTC=0x00;
DDRC=0xFF;
// Port D initialization
PORTD=0x00;
DDRD=0xFF;
// I2C Bus initialization
// I2C Port: PORTB
// I2C SDA bit: 1
// I2C SCL bit: 0
// Bit Rate: 100 kHz
i2c_init();
  delay_ms(2000);
while (1)
  {
  // Place your code here
  // Read calibration values
  msb=m_read(0xAA);     // read AC1-HB value from BMP085
  PORTD=msb;


  delay_ms(50);
  } // end of while(1)

}

Hallo,

ich habe hier den markanten Teil aufgeführt.
Zuerst habe ich versucht, alle Bytes von Adresse 0xAA bis 0xBF in einem 
Rutsch auszulesen.
Hier wird nur noch die Adresse 0xAA ausgelesen und an PortD sichtbar 
gemacht. Bei PortD leuchten alle Bits, weil die SDA-Leitung in der 
entsprechenden Zeit H-Signal führt. Die delays sind neu dazu, damit man 
auf dem Oszilloskop die beiden Signal gut verfolgen kann.
Schaltplan habe ich nicht. Ich kann nur sagen, dass ich die 
BMP085-Platine vorschriftsmässig nach Bosch angeschlossen habe. Sauberer 
Aufbau, wie es sich für einen Elektroniker mit fast 40 Jahren 
Berufserfahrung auch gehört. Will damit sagen, dass Lötstellen usw. 
schon ok sind, ich glaube nicht an ein Hardwareproblem.
Auch so, wie oben angegeben: SDA an PortB-Bit1, SCL an PortB-Bit0, GND 
und VDDD=3,3V. Die Signale sind 3,3V hoch, dies sollte als H-Signal für 
den ATMEGA32 ausreichen (schon probiert).
Das Ding ist neu, an einem ESD-Arbeitsplatz wird der Sensor verwendet.

Irgendeinen guten Gedanken, oder ist, was ich langsam glaube, der Sensor 
defekt geliefert worden?

Wolfgang

von Peter Z. (hangloose)


Lesenswert?

Externe Pull Up Widerstände 4k7 verwendet?

von Wolfgang S. (Gast)


Lesenswert?

Hallo,
ja, externe Pull-up Widerstände (4.7k, je einen für SDA und SCL) nach 
VDDD (3,3V) sind natürlich vorhanden. Die internen ATMEGA32-Widerstände 
sind abgeschaltet.

Wolfgang

von Peter Z. (hangloose)


Lesenswert?

Reset xclr Pin vielleicht auf GND?

von Wolfgang S. (Gast)


Lesenswert?

Hallo,
dieser Pin liegt auf dem Board über einen Widerstand an VDDD (+3,3V).

Was mich noch ein wenig irritiert ist, dass bei anderen Programmen auch 
andere Geräteadressen vorkommen, so z.B. taucht häufig 0x77 als 
Geräteadresse auf. Hab ich natürlich auch probiert: 0x77 bzw. 0x76.

Wolfgang

von Peter Z. (hangloose)


Lesenswert?

Schickt der Sensor nur ein Byte als Antwort zurück?

Habe bei Sparkfun folgende Funktion gefunden...
Da kriegt er MSB und LSB... Aber ich weiß es nicht.
Kenne den Sensor nicht
1
// bmp085ReadShort will read two sequential 8-bit registers, and return a 16-bit value
2
// the MSB register is read first
3
// Input: First register to read
4
// Output: 16-bit value of (first register value << 8) | (sequential register value)
5
short bmp085ReadShort(unsigned char address)
6
{
7
  char msb, lsb;
8
  short data;
9
  
10
  i2cSendStart();
11
  i2cWaitForComplete();
12
  
13
  i2cSendByte(BMP085_W);  // write 0xEE
14
  i2cWaitForComplete();
15
  
16
  i2cSendByte(address);  // write register address
17
  i2cWaitForComplete();
18
  
19
  i2cSendStart();
20
  
21
  i2cSendByte(BMP085_R);  // write 0xEF
22
  i2cWaitForComplete();
23
  
24
  i2cReceiveByte(TRUE);
25
  i2cWaitForComplete();
26
  msb = i2cGetReceivedByte();  // Get MSB result
27
  i2cWaitForComplete();
28
  
29
  i2cReceiveByte(FALSE);
30
  i2cWaitForComplete();
31
  lsb = i2cGetReceivedByte();  // Get LSB result
32
  i2cWaitForComplete();
33
  
34
  i2cSendStop();
35
  
36
  data = msb << 8;
37
  data |= lsb;
38
  
39
  return data;
40
}

von Peter Z. (hangloose)


Lesenswert?

Müsste bei dir dann ungefähr so sein...
1
data=i2c_read(1);              // read data from BMP085 MSB
2
data=i2c_read(0);              // read data from BMP085 LSB
3
i2c_stop();                    // stop xmission

von Wolfgang S. (Gast)


Lesenswert?

Hallo,

ja, ich kenne auch dieses Programm.

Das Datenblatt von Bosch sagt, dass keines der 11 16bit-Wörter den 
Zustand 0x0000 oder 0xFFFF hat. Wenn ich beide Bytes (0xAA=HighByte und 
0xAB das dazugehörige LowByte) auslese, sind beide zusammen 0xFFFF. Und 
das soll es nie geben.
Ich habe jetzt soviel versucht, dass ich fest davon ausgehe, dass der 
Sensor nicht antwortet.
Hardware ist ok (zum 1000. mal untersucht, auf alles mögliche).
Meiner Meinung nach kann es nur an der Software liegen. Wenn mein 
Programm stimmt und niemand daran etwas findet, muss der Sensor defekt 
sein.
Nur, der ist neu!

Wolfgang

von Wolfgang S. (Gast)


Lesenswert?

Hallo,

ja, genau ! Dies mit

data=i2c_read(1);              // read data from BMP085 MSB

habe ich auch versucht, kein Erfolg !

Wolfgang

von Peter Z. (hangloose)


Lesenswert?

Na dann teste halt mal den Demo Code von Sparkfun wenn du ihn eh schon 
hast,
 dann weißt du ob der Sensor defekt ist oder nicht.
Glaub ich aber nicht.

von Wolfgang S. (Gast)


Lesenswert?

Hallo,

ja, der Sensor ist neu !

Die Hoffnung stirbt zuletzt!

Deshalb versuche ich alles, um dem Fehler auf die Spur zu kommen, und in 
diesem Forum habe ich schon gute Hinweise bei anderen Problemen 
bekommen.

Wolfgang

von Wolfgang S. (Gast)


Lesenswert?

Hallo,

das Programm von Sparkfun läuft ja so nicht auf dem ATMEGA mit 
Codevision.

Aber wenn man das Programm genau unter die Lupe nimmt und dann Zeile für 
Zeile umschreibt, dann kommt das Gleiche heraus wie in meinem Beispiel.
Ich habe dieses Beispiel (sparkfun) heute morgen schon versucht, ohne 
Erfolg !

Es gibt ja auch noch andere Beispiele. Aber auch die sind im Prinzip 
gleich.

Wolfgang

von Peter Z. (hangloose)


Lesenswert?

Hast Du mal kleine delays zwischen den gesendeten Bytes versucht.

von Peter Z. (hangloose)


Lesenswert?

Jetzt ist mir noch etwas aufgefallen.

Bevor Du das Ergebnis auslesen kannst musst Du doch
die maximale conversion time abwarten oder den EOC Pin
abfragen. Das machst Du ja nicht bei deinem Code??

Oder hab ich da was übersehen?

von Wolfgang S. (Gast)


Lesenswert?

Hallo,

ja, ich habe es auch mit delays versucht, obwohl die Geschwindigkeit ja 
nicht hoch ist.
Ich hatte schon deshalb viele delays verwendet, um auf dem Oszilloskop 
die
verschiedenen Bytes ausfindig zu machen.

Diese conversion time ist m.E. nicht relevant, da hier feste 
(Konstanten) Werte aus dem internen EEPROM ausgelesen werden. Die sind 
bauteilspezifisch und werden später für die Berechnung benötigt. Diese 
Werte werden nie verändert.

Wolfgang

von Wolfgang S. (Gast)


Lesenswert?

Hallo,

ich bin bis Donnerstagmorgen nicht mehr im Internet und kann auf 
mögliche neue Fragen nicht antworten.

Ich bitte aber jeden, der noch eine Idee hat, sich zu melden.

Gruss, Wolfgang

von Navid (Gast)


Lesenswert?

Hi
Just today I started using codevision for reading calibration values of 
BMP085 and I had similar problem.(only zero as output)

I tried your code.
After programing i disconnected the programer and also the main power of 
the mainbord (this will reset the BMP085 module)and I've got following 
calibration coeficient:
0xAA, 0xAB, 0xAC, oxAD : 36, 95, 250, 123

I will continue the project and will see are they correct.

Navid

von Navid (Gast)


Lesenswert?

Hi

I read temperature successfully.
Please note that PB1 is using for on-board programming.
You should disconnect programmer during operation, or use PB2 instead.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.