PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : BMP180 --> Druck oder I2C Problem ?



Janiiix3
19.05.2015, 09:23
Hallo liebe Gemeinde,

leider musste ich festellen, dass einige Sensoren nicht korrekt ausgelesen werden. 10 Stk. an der Zahl habe ich hier rum fliegen. Alle neu bestellt also vermutlich keine Lagerprobleme.

Was richtig auffällig ist, ist das der Luftdruck arg hoch ist (ca. 1504 hPa)... Bei einigen Sensoren ( 4 Stk.) bekomme ich die richtige Temperatur und den richtigen Luftdruck.

Kann es sein, dass es ein Problem meiner Routine ist ??? Ich bin wirklich sprachlos...

Würde mich sehr freuen, wenn sich jemand mal meine Routine anschauen könnte. Berechnung sollte stimmen, da ja einige Sensoren funktionieren und die "Muster Rechnung" laut Datenblatt passt auch. Also der Algorithmus stimmt.


Vielen Dank schonmal http://www.avr-praxis.de/forum/images/smilies/wink.png

sast
19.05.2015, 09:44
Nach meinen Erfahrungen liegt es an den Berechnungen.
Hab mir deine BMP180.c nur kurz angesehen und mir ist ein *0.01 aufgefallen. Mit solchen Werten bin ich immer sehr vorsichtig. Habe noch dunkle Erinnerungen vom Studium, das bei irgend so einem Wert die Maschine Berechnungsfehler erzeugen kann.
Hier mal meine Berechnung nach DB


char bmp180_get_cal_param(bmp180_calc_t *cal)
{
char ret = 1;
ret &= bmp180_readInt(0xAA, &(cal->AC1));
ret &= bmp180_readInt(0xAC, &(cal->AC2));
ret &= bmp180_readInt(0xAE, &(cal->AC3));
ret &= bmp180_readUInt(0xB0, &(cal->AC4));
ret &= bmp180_readUInt(0xB2, &(cal->AC5));
ret &= bmp180_readUInt(0xB4, &(cal->AC6));
ret &= bmp180_readInt(0xB6, &(cal->B1));
ret &= bmp180_readInt(0xB8, &(cal->B2));
ret &= bmp180_readInt(0xBA, &(cal->MB));
ret &= bmp180_readInt(0xBC, &(cal->MC));
ret &= bmp180_readInt(0xBE, &(cal->MD));
return ret;
}

char bmp180_online(char *id)
{
return bmp180_readByte(0xD0, id);
}

char bmp180_get_temp(bmp180_calc_t cal, long *temperatur)
{
char ret = 1;
int t;
long UT, X1, X2, B5, T;
long AC5, AC6, MC, MD;
AC5 = cal.AC5;
AC6 = cal.AC6;
MC = cal.MC;
MD = cal.MD;
ret &= bmp180_start_temp(&t);
UT = (unsigned int)t;
X1 = (((UT - AC6) * AC5)>>15);
X2 = (MC<<11) / (X1 + MD);
B5 = X1 + X2;
T = ((B5 + 8L)>>4);
*temperatur = T;
return ret;
}

char bmp180_get_druck(bmp180_calc_t cal, long *druck, unsigned char oss, long *temperatur, int *temp, long *press)
{
char ret = 1;
long p;
int t;
long UT, X1, X2, X3, B3, B5, B6, T;
long AC1, AC2, AC3, AC4, AC5, AC6, MB, MC, MD, B1, B2;
unsigned long B4, B7, UP;
AC1 = cal.AC1;
AC2 = cal.AC2;
AC3 = cal.AC3;
AC4 = cal.AC4;
AC5 = cal.AC5;
AC6 = cal.AC6;
MB = cal.MB;
MC = cal.MC;
MD = cal.MD;
B1 = cal.B1;
B2 = cal.B2;
ret &= bmp180_start_temp(&t);
UT = (long)t;
*temp = t;
ret &= bmp180_start_druck(&p, oss);
UP = (long)p;
*press = p;
X1 = (((UT - AC6) * AC5)>>15);
X2 = (MC<<11) / (X1 + MD);
B5 = X1 + X2;
T = ((B5 + 8L)>>4);
*temperatur = T;
B6 = B5 - 4000;
X1 = (B2 * ((B6 * B6) >> 12)) >> 11;
X2 = (AC2 * B6) >> 11;
X3 = X1 + X2;
B3 = (((AC1 * 4 + X3) << oss) + 2) >> 2;
X1 = (AC3 * B6) >> 13;
X2 = (B1 * ((B6 * B6) >> 12)) >> 16;
X3 = ((X1 + X2) + 2) >> 2;
B4 = (AC4 * (unsigned long)(X3 + 32768)) >> 15;
B7 = ((unsigned long)(UP - B3)) * (50000 >> oss);
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;
*druck= p + ((X1 + X2 + 3791) >> 4);
return ret;
}

char bmp180_start_messung(char address, char command, char statusbit)
{
char status = command;
unsigned int timeout = 65535;
if (bmp180_writeByte(address, command))
{
while((status & statusbit) && (timeout-- > 0))
{
if (!bmp180_readByte(address, &status)) return 0;
}
return 1;
}
return 0;
}

char bmp180_start_temp(int *value)
{
int hi;
if (bmp180_start_messung(0xF4, 0x2E, 0x00 | (1<<BMP180_SCO)))
{
bmp180_readInt(0xF6, &hi);
*value = (int)hi;
return 1;
}
return 0;
}

char bmp180_start_druck(long *value, unsigned char oss)
{
char hi, lo;
char xlsb;
if (bmp180_start_messung(0xF4, 0x34 + (oss<<6), 0x00 | (1<<BMP180_SCO)))
{
bmp180_readByte(0xF6, &hi);
bmp180_readByte(0xF7, &lo);
bmp180_readByte(0xF8, &xlsb);
*value = (long)((((long)hi)<<16) | (((long)lo)<<8) | ((long)xlsb)) >> (8-oss);
return 1;
}
return 0;
}

Habe da bisher noch keinen Fehler festgestellt.

Janiiix3
19.05.2015, 09:47
Hallo sast,

nur wieso klappt es dann mit den Musterwerten aus dem Dateblatt und mit einigen Sensoren ? Ist schon komisch...
Würdest du mir deine Library zur Verfügung stellen?

& was vill. noch wichtig ist, deine I2C Routine. Ist die Hardware basierend oder auf reiner Software ?

sast
19.05.2015, 12:02
Das I2C Zeug ist von hier

#ifndef _I2CMASTER_H
#define _I2CMASTER_H 1
/************************************************** ***********************
* Title: C include file for the I2C master interface
* (i2cmaster.S or twimaster.c)
* Author: Peter Fleury <pfleury@gmx.ch> http://jump.to/fleury
* File: $Id: i2cmaster.h,v 1.10 2005/03/06 22:39:57 Peter Exp $
* Software: AVR-GCC 3.4.3 / avr-libc 1.2.3
* Target: any AVR device
* Usage: see Doxygen manual
************************************************** ************************/

Lesen und schreiben sieht so aus:



char bmp180_readByte(char address, char *value)
{
unsigned char data[1];

data[0] = address;
if (bmp180_readBytes(data,1))
{
*value = data[0];
return 1;
}
value = 0;
return 0;
}

char bmp180_readUByte(char address, unsigned char *value)
{
unsigned char data[1];

data[0] = address;
if (bmp180_readBytes(data,1))
{
*value = data[0];
return 1;
}
value = 0;
return 0;
}

char bmp180_readInt(char address, int *value)
{
unsigned char data[2];

data[0] = address;
if (bmp180_readBytes(data,2))
{
*value = (((int)data[0]<<8)|(int)data[1]);
return 1;
}
value = 0;
return 0;
}

char bmp180_readUInt(char address, unsigned int *value)
{
unsigned char data[2];

data[0] = address;
if (bmp180_readBytes(data,2))
{
*value = (((unsigned int)data[0]<<8)|(unsigned int)data[1]);
return 0;
}
value = 0;
return 1;
}

char bmp180_writeByte(char address, char value)
{
unsigned char data[2];

data[0] = address;
data[1] = value;
if (bmp180_writeBytes(data,1))
{
return 1;
}
value = 0;
return 0;
}

char bmp180_readBytes(unsigned char *values, char length)
{
unsigned char ret, res = 0, zc = 0;
unsigned char addr = values[0];

while(zc < length)
{
ret = i2c_start(BMP180+I2C_WRITE); // ret=0 -> Ok, ret=1 -> no ACK
if (!ret)
{
ret = i2c_write(addr + zc); // write Instruction Byte
res = res + ret;
i2c_stop(); // set stop conditon = release bus
}
res = res + ret;
ret = i2c_rep_start(BMP180+I2C_READ); // ret=0 -> Ok, ret=1 -> no ACK
if (!ret)
{
values[zc] = i2c_readNak(); // read one byte
res = res + ret;
i2c_stop(); // set stop conditon = release bus
}
res = res + ret;
if(res) return 0;
zc++;
}
return 1;
}

char bmp180_writeBytes(unsigned char *values, char length)
{
unsigned char ret, res = 0, zc = 0;
unsigned char addr = values[0];

while(zc < length)
{
ret = i2c_start(BMP180+I2C_WRITE); // ret=0 -> Ok, ret=1 -> no ACK
if (!ret)
{
ret = i2c_write(addr + zc); // write Instruction Byte
res = res + ret;
ret = i2c_write(values[zc + 1]); // Date Byte
res = res + ret;
i2c_stop(); // set stop conditon = release bus
}
res = res + ret;
if(res) return 0;
zc++;
}
return 1;
}

Ich hab auch nur 3 Stück in Benutzung. Wenn damit die selben Fehler auftreten, dann liegts an den Sensoren oder irgend etwas anderem. Ist auch schon wieder eine Weile her. Ich sammle zwar die Werte noch, aber werte die zZ nicht aus.

Die cal Werte je Sensor muss man auch nur einmal auslesen. Laut Hersteller ändern die sich ja lebenslang nicht mehr. Wichtig ist nur, dass du auch die richtigen cal Werte zur Berechnung des jeweiligen Sensors verwendest. Die unterscheiden sich ja doch etwas. Aber das hast du sicher beachtet.

Janiiix3
19.05.2015, 12:09
Danke!

Und die ganzen Strukturen? Hast du keine BMP180.c ?

- - - Aktualisiert - - -



Die cal Werte je Sensor muss man auch nur einmal auslesen. Laut Hersteller ändern die sich ja lebenslang nicht mehr. Wichtig ist nur, dass du auch die richtigen cal Werte zur Berechnung des jeweiligen Sensors verwendest. Die unterscheiden sich ja doch etwas. Aber das hast du sicher beachtet.



Die Kalibrationswerte habe ich von jedem Sensor einzeln ausgelesen und mit den entsprechenden Sensoren verrechnen lassen. Das sollte wohl gestimmt haben.
Ich würde jetzt gerne mal deine Routine ausprobieren, ob die Sensoren wirklich einen weg haben. Sonst laufe ich die ganze Zeit auf dem selben Weg hin und her... Ohne Erfolg!

sast
19.05.2015, 12:12
#define BMP180 0xEE
#define BMP180_SCO 5

typedef struct bmp180_calc
{
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;
} bmp180_calc_t;


extern char bmp180_get_cal_param(bmp180_calc_t *cal);
extern char bmp180_readBytes(unsigned char *values, char length);
extern char bmp180_readInt(char address, int *value);
extern char bmp180_readUInt(char address, unsigned int *value);
extern char bmp180_readByte(char address, char *value);
extern char bmp180_readUByte(char address, unsigned char *value);
extern char bmp180_writeBytes(unsigned char *values, char length);

extern char bmp180_writeByte(char address, char value);
extern char bmp180_start_temp(int *value);
extern char bmp180_start_druck(long *value, unsigned char oss);
extern char bmp180_get_temp(bmp180_calc_t cal, long *temperatur);
extern char bmp180_get_druck(bmp180_calc_t cal, long *druck, unsigned char oss, long *temperatur, int *temp, long *press);
extern char bmp180_online(char *id);

Den Rest schaffst du jetzt allein.

Peter(TOO)
19.05.2015, 12:13
Hallo,

Stimmt die Übertragungsgeschwindigkeit des II2-Buses?

In BMP180.c werden 8MHz als Systemtakt angenommen.

MfG Peter(TOO)

Janiiix3
19.05.2015, 12:27
Hallo,

Stimmt die Übertragungsgeschwindigkeit des II2-Buses?

In BMP180.c werden 8MHz als Systemtakt angenommen.

MfG Peter(TOO)


Hallo Peter,

ich habe ja noch eine RTC mit an dem I²C Bus dass funktioniert klasse.

- - - Aktualisiert - - -



#define BMP180 0xEE
#define BMP180_SCO 5

typedef struct bmp180_calc
{
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;
} bmp180_calc_t;


extern char bmp180_get_cal_param(bmp180_calc_t *cal);
extern char bmp180_readBytes(unsigned char *values, char length);
extern char bmp180_readInt(char address, int *value);
extern char bmp180_readUInt(char address, unsigned int *value);
extern char bmp180_readByte(char address, char *value);
extern char bmp180_readUByte(char address, unsigned char *value);
extern char bmp180_writeBytes(unsigned char *values, char length);

extern char bmp180_writeByte(char address, char value);
extern char bmp180_start_temp(int *value);
extern char bmp180_start_druck(long *value, unsigned char oss);
extern char bmp180_get_temp(bmp180_calc_t cal, long *temperatur);
extern char bmp180_get_druck(bmp180_calc_t cal, long *druck, unsigned char oss, long *temperatur, int *temp, long *press);
extern char bmp180_online(char *id);

Den Rest schaffst du jetzt allein.


Um jetzt ein Ergebniss zu bekommen...

Welche Funktionen muss ich nacheinander aufrufen?
Bei deinen Funktionen gibt es "start_messung" | "start_temperatur"...

Was muss ich aufrufen um den Druck zu erhalten? (Sorry für die vielen Fragen!)

sast
19.05.2015, 13:03
Was muss ich aufrufen um den Druck zu erhalten? (Sorry für die vielen Fragen!)

Wie würdest du das denn auf englisch formulieren? Steht doch bereits in meinem ersten Post.
Du darfst auch gern in der Funktion den Quelltext lesen. Die Berechnung ist ans DB angelehnt und sollte für einen Eingelesenen verständlich sein.

Janiiix3
19.05.2015, 13:10
Ich fange gerade erst mit "C" richtig an.


char bmp180_get_cal_param(bmp180_calc_t *cal)

Was muss ich denn für einen Parameter in der Funktion eingeben? Ich habe bisher nichts so wirklich mit "Pointern" gemacht.

sast
19.05.2015, 13:24
bmp180_calc_t cal;
char id = 0;

if(bmp180_online(&id))
{
bmp180_get_cal_param(&cal);
...
}

// &cal liefert die Adresse vom Struct cal

Man lernt am Besten, wenn man seine Fehler selber macht.

Janiiix3
19.05.2015, 13:54
Muss erstmal mein ganzes Programm ausbauen.
Schade das du daraus keine fertige Library gemacht hast. Wenn ich es hin bekommen habe, melde ich mich zurück.

- - - Aktualisiert - - -

Ich bekomme es leider noch nicht so wirklich mit der Struktur auf die Kette, wollte aus deinen Routinen jetzt eine Library erstellen und die Variablen in der Header Datei für "extern" bekannt geben.

Was mache ich verkehrt ?



#define BMP180 0xEE
#define BMP180_SCO 5

typedef struct bmp180_calc
{
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;
}bmp180_calc_t;


extern bmp180_calc_t cal;

extern char bmp180_get_cal_param(bmp180_calc_t *cal);
extern char bmp180_readBytes(unsigned char *values, char length);
extern char bmp180_readInt(char address, int *value);
extern char bmp180_readUInt(char address, unsigned int *value);
extern char bmp180_readByte(char address, char *value);
extern char bmp180_readUByte(char address, unsigned char *value);
extern char bmp180_writeBytes(unsigned char *values, char length);

extern char bmp180_writeByte(char address, char value);
extern char bmp180_start_temp(int *value);
extern char bmp180_start_druck(long *value, unsigned char oss);
extern char bmp180_get_temp(bmp180_calc_t cal, long *temperatur);
extern char bmp180_get_druck(bmp180_calc_t cal, long *druck, unsigned char oss, long *temperatur, int *temp, long *press);
extern char bmp180_online(char *id);

Peter(TOO)
19.05.2015, 15:51
Hallo,

ich habe ja noch eine RTC mit an dem I²C Bus dass funktioniert klasse.

Es gibt verschiedene maximale Geschwindigkeiten für den I2C.
Zudem ist auch das Detail-Timing etwas unterschiedlich.

Aufschluss geben die Datenblätter!
Der RTC kann z.B. für eine höhere Bus-Geschwindigkeit ausgelegt sein, als deine Sensoren.

Ursprünglich wurde der I2C mit 100kBit/s spezifiziert. Dann kamen 400kBit/s, 3,4 MBit/s, 1 MBit/s und als Letztes 5 MBit/s dazu. Wobei dies alles "bis zu" Werte sind, langsamer geht immer!
Protokolle gibt es auch noch unterschiedliche.

MfG Peter(TOO)

sast
19.05.2015, 16:20
Sobald du die .h einbindest, hast du doch bereits das struct. Das ist die komplette .h nur ohne #ifdef. Da solltest du kein extern mehr benötigen für das struct. Und der Rest war in der .c was du auch nur noch zusammenkopieren musst. Dann includest du noch die .h und die i2c und twi Geschichten und ab geht er. Ich wollte jetzt hier eigentlich kein c Tutorial draus machen.
In deiner main.c brauchst du natürlich auch das bmp180.h als include.

Janiiix3
19.05.2015, 16:30
achso ;) besten dank

sast
19.05.2015, 16:47
Schon mal nicht verkehrt. Jetzt siehst du dir mal die i2cmaster.h an und überlegst, wozu da wohl die erste, zweite und letzte Zeile drin sind und wie du das eindeutig für dich anpassen kannst. Und dann kannst du die bmp180.h auch in die main includieren ohne das es gemeckertes gibt..

Janiiix3
19.05.2015, 17:29
So,

Also die Temperatur bekomme ich jetzt schon mal ordentlich.

Variablen "global"



bmp180_calc_t cal;
int temp_tmp;
long temp, press;

int temp_temp;
long press_tmp;




Temperatur lese ich nun so aus (Funktioniert auch... 187 im moment)


bmp180_get_temp(cal,&temp);



Der Druck wird mir falsch angezeigt (Modul funktioniert) Wert liegt bei -30915



bmp180_get_druck(cal,&press,0,&temp,&temp_temp,&press_tmp);



Binde ich die Musterwerte in die Routine ein, so komme ich auch nicht auf das Ergebniss laut Datenblatt (699).



/* Musterwerte laut Datenblatt */
oss = 0;
AC1 = (short)408;
AC2 = (short)-72;
AC3 = (short)-14383;
AC4 = (unsigned short) 32741;
AC5 = (unsigned short)32757;
AC6 = (unsigned short)23153;
B1 = (short)6190;
B2 = (short)4;
MB = (short)-32768;
MC = (short)-8711;
MD = (short)2868;

UP = 23843;
B5 = 2399;

B6 = B5 - 4000;
X1 = (B2 * ((B6 * B6) >> 12)) >> 11;
X2 = (AC2 * B6) >> 11;
X3 = X1 + X2;
B3 = (((AC1 * 4 + X3) << oss) + 2) >> 2;
X1 = (AC3 * B6) >> 13;
X2 = (B1 * ((B6 * B6) >> 12)) >> 16;
X3 = ((X1 + X2) + 2) >> 2;
B4 = (AC4 * (unsigned long)(X3 + 32768)) >> 15;
B7 = ((unsigned long)(UP - B3)) * (50000 >> oss);
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;
*druck= p + ((X1 + X2 + 3791) >> 4);
return ret;


Auswerten tue ich "&press".

sast
20.05.2015, 07:30
char bmp180_get_druck(bmp180_calc_t cal, long *druck, unsigned char oss, long *temperatur, int *temp, long *press)

temp und press sind die Rohdaten aus dem Auslesen der Sensoren.

druck und temperatur sollten dann die berechneten Werte liefern.

Kannst du mal deine main zeigen? Was hat den short für eine Größe? Ist das ein 16bit Integer? Die Temperatur von get_temp und get_druck sollte auf jeden Fall in beiden Fällen gleich sein. Was sind UP und B5 für Datentypen?

Schreibe mal genauer, was wann bei welchem Versuch rauskommt. Wann hast du mit Beispieldaten gerechnet und was kam dabei raus und wann hast du echt gemessen und was kam da bei druck und temperatur raus?

Janiiix3
20.05.2015, 07:46
Über der main...



bmp180_calc_t cal;
int temp_tmp;
long temp, press;

int temp_temp;
long press_tmp;




Meine Main (zum Teil...)



int main(void)
{
/* set DataDirectionRegister(s) as Output */
DDRD |= ((1<<PD1) | (1<<PD4) | (1<<PD5) | (1<<PD6) | (1<<PD7));
DDRC |= (1<<PC0);
DDRB |= ((1<<PB3) | (1<<PB4));

/* set PullUp´s */
PORTC |= ((1<<PC2) | (1<<PC3) | (1<<PC4) | (1<<PC5) | (1<<PC6));
PORTB |= (1<<PB2);
PORTD |= ((1<<PD5));

/* init the Graphic Chip */
ht1632c_init(0xAF);

/* init the i2c unit */
i2c_init();

/* init the pressure sensor */
// BMP180_init();

bmp180_get_cal_param(&cal);


Also hier erstmal die Rohdaten :

Druck :

-22634 // Darf der Rohwert MINUS sein?

Temp :

29232


Umgerechnete Werte :

Temp :

224

Druck :

-30418


Die Datentypen sind genau die, die du auch gepostet hast. Ich habe lediglich bei den Musterwerten "gecastet"... Auch ohne "cast" kommt das gleiche raus.
Kann es sein, dass die Kalibrationswerte falsch verrechnet werden?

sast
20.05.2015, 09:22
ich sehe immer noch keinen Aufruf der Funktionen. Welche Variable liefert welchen Wert? Komplette Deklaration der Variablen.
Wenn du immer nur Stückchen hinwirfst wirds schwer den Fehler einzugrenzen. Ich kanns nicht verifizieren, da ich aktuell nur bmp180_start_temp(&temp); und bmp180_start_druck(&press, oss); verwende.

Janiiix3
20.05.2015, 11:06
Ich rufe aktuell die Temperatur und den Druck so ab :


bmp180_get_druck(cal,&press,0,&temp,&temp_temp,&press_tmp);

Folgende Variablen liefern mir folgende Werte :



cal = habe ich mir noch nicht angeschaut. (Sollte ich dies besser tun?)
&press = -30418 (Vorzeichen MINUS)
&temp = 224 (Dieser Wert passt. Ca. 22,4 °C)
&temp_temp = 29232 (Rohdaten Temperatur)
&press_tmp = -22634 ( Rohdaten Druck, Vozeichen MINUS)


Mehr rufe ich aktuell nicht auf.


***UPDATE***

Die Kalibrationswerte scheinen zu stimmen.

- - - Aktualisiert - - -

Es scheint irgendwas mit den Zeigern zu sein.

Führe ich die Routine so aus :



char bmp180_get_druck(bmp180_calc_t cal, long *druck, unsigned char oss, long *temperatur, int *temp, long *press)
{
char ret = 1;
long p;
int t;
long UT, X1, X2, X3, B3, B5, B6, T;
long AC1, AC2, AC3, AC4, AC5, AC6, MB, MC, MD, B1, B2;
unsigned long B4, B7, UP;
AC1 = cal.AC1;
AC2 = cal.AC2;
AC3 = cal.AC3;
AC4 = cal.AC4;
AC5 = cal.AC5;
AC6 = cal.AC6;
MB = cal.MB;
MC = cal.MC;
MD = cal.MD;
B1 = cal.B1;
B2 = cal.B2;

ret &= bmp180_start_temp(&t);
UT = (long)t;
*temp = t;
ret &= bmp180_start_druck(&p, oss);
UP = (long)p;
*press = p;

X1 = (((UT - AC6) * AC5)>>15);
X2 = (MC<<11) / (X1 + MD);
B5 = X1 + X2;
T = ((B5 + 8L)>>4);
*temperatur = T;

/* Musterwerte laut Datenblatt */
oss = 0;
AC1 = 408;
AC2 = -72;
AC3 = -14383;
AC4 = 32741;
AC5 = 32757;
AC6 = 23153;
B1 = 6190;
B2 = 4;
MB = -32768;
MC = -8711;
MD = 2868;

UP = 23843;
B5 = 2399;

#define SCROLL_CAL_VALUE 20

char Buffer[20];

// strcpy(Buffer, "AC1 : ");
// sprintf(Buffer+strlen(Buffer), "%i", AC1);
// scroll_display(Buffer,SCROLL_CAL_VALUE);
//
// strcpy(Buffer, "AC2 : ");
// sprintf(Buffer+strlen(Buffer), "%i", AC2);
// scroll_display(Buffer,SCROLL_CAL_VALUE);
//
// strcpy(Buffer, "AC3 : ");
// sprintf(Buffer+strlen(Buffer), "%i", AC3);
// scroll_display(Buffer,SCROLL_CAL_VALUE);
//
// strcpy(Buffer, "AC4 : ");
// sprintf(Buffer+strlen(Buffer), "%i", AC4);
// scroll_display(Buffer,SCROLL_CAL_VALUE);
//
// strcpy(Buffer, "AC5 : ");
// sprintf(Buffer+strlen(Buffer), "%i", AC5);
// scroll_display(Buffer,SCROLL_CAL_VALUE);
//
// strcpy(Buffer, "AC6 : ");
// sprintf(Buffer+strlen(Buffer), "%i", AC6);
// scroll_display(Buffer,SCROLL_CAL_VALUE);
//
// strcpy(Buffer, "MB : ");
// sprintf(Buffer+strlen(Buffer), "%i", MB);
// scroll_display(Buffer,SCROLL_CAL_VALUE);
//
// strcpy(Buffer, "MC : ");
// sprintf(Buffer+strlen(Buffer), "%i", MC);
// scroll_display(Buffer,SCROLL_CAL_VALUE);
//
// strcpy(Buffer, "MD : ");
// sprintf(Buffer+strlen(Buffer), "%i", MD);
// scroll_display(Buffer,SCROLL_CAL_VALUE);
//
// strcpy(Buffer, "B1 : ");
// sprintf(Buffer+strlen(Buffer), "%i", B1);
// scroll_display(Buffer,SCROLL_CAL_VALUE);
//
// strcpy(Buffer, "B2 : ");
// sprintf(Buffer+strlen(Buffer), "%i", B2);
// scroll_display(Buffer,SCROLL_CAL_VALUE);

B6 = B5 - 4000;
X1 = (B2 * (B6 * B6 >> 12)) >> 11;
X2 = AC2 * B6 >> 11;
X3 = X1 + X2;
B3 = (((AC1 * 4 + X3) << oss) + 2) >> 2;
X1 = AC3 * B6 / 8192;
X2 = (B1 * (B6 * B6 >> 12)) >> 16;
X3 = ((X1 + X2) + 2) >> 2;
B4 = AC4 * (unsigned long)(X3 + 32768) >> 15;
B7 = ((unsigned long)UP - B3) * (50000 >> oss);

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;
long temp_1;

temp_1 = p + ((X1 + X2 + 3791) >> 4);

strcpy(Buffer, "Druck : ");
sprintf(Buffer+strlen(Buffer), "%ld", temp_1);
scroll_display(Buffer,SCROLL_CAL_VALUE);


return ret;
}

Bekomme ich den Wert laut Musterrechnung (Datenblatt)


Deklariere ich jedoch keine Variable



long temp_1;


und werte den Druck so aus :



char bmp180_get_druck(bmp180_calc_t cal, long *druck, unsigned char oss, long *temperatur, int *temp, long *press)
{
char ret = 1;
long p;
int t;
long UT, X1, X2, X3, B3, B5, B6, T;
long AC1, AC2, AC3, AC4, AC5, AC6, MB, MC, MD, B1, B2;
unsigned long B4, B7, UP;
AC1 = cal.AC1;
AC2 = cal.AC2;
AC3 = cal.AC3;
AC4 = cal.AC4;
AC5 = cal.AC5;
AC6 = cal.AC6;
MB = cal.MB;
MC = cal.MC;
MD = cal.MD;
B1 = cal.B1;
B2 = cal.B2;

ret &= bmp180_start_temp(&t);
UT = (long)t;
*temp = t;
ret &= bmp180_start_druck(&p, oss);
UP = (long)p;
*press = p;

X1 = (((UT - AC6) * AC5)>>15);
X2 = (MC<<11) / (X1 + MD);
B5 = X1 + X2;
T = ((B5 + 8L)>>4);
*temperatur = T;

/* Musterwerte laut Datenblatt */
oss = 0;
AC1 = 408;
AC2 = -72;
AC3 = -14383;
AC4 = 32741;
AC5 = 32757;
AC6 = 23153;
B1 = 6190;
B2 = 4;
MB = -32768;
MC = -8711;
MD = 2868;

UP = 23843;
B5 = 2399;

#define SCROLL_CAL_VALUE 20

char Buffer[20];

// strcpy(Buffer, "AC1 : ");
// sprintf(Buffer+strlen(Buffer), "%i", AC1);
// scroll_display(Buffer,SCROLL_CAL_VALUE);
//
// strcpy(Buffer, "AC2 : ");
// sprintf(Buffer+strlen(Buffer), "%i", AC2);
// scroll_display(Buffer,SCROLL_CAL_VALUE);
//
// strcpy(Buffer, "AC3 : ");
// sprintf(Buffer+strlen(Buffer), "%i", AC3);
// scroll_display(Buffer,SCROLL_CAL_VALUE);
//
// strcpy(Buffer, "AC4 : ");
// sprintf(Buffer+strlen(Buffer), "%i", AC4);
// scroll_display(Buffer,SCROLL_CAL_VALUE);
//
// strcpy(Buffer, "AC5 : ");
// sprintf(Buffer+strlen(Buffer), "%i", AC5);
// scroll_display(Buffer,SCROLL_CAL_VALUE);
//
// strcpy(Buffer, "AC6 : ");
// sprintf(Buffer+strlen(Buffer), "%i", AC6);
// scroll_display(Buffer,SCROLL_CAL_VALUE);
//
// strcpy(Buffer, "MB : ");
// sprintf(Buffer+strlen(Buffer), "%i", MB);
// scroll_display(Buffer,SCROLL_CAL_VALUE);
//
// strcpy(Buffer, "MC : ");
// sprintf(Buffer+strlen(Buffer), "%i", MC);
// scroll_display(Buffer,SCROLL_CAL_VALUE);
//
// strcpy(Buffer, "MD : ");
// sprintf(Buffer+strlen(Buffer), "%i", MD);
// scroll_display(Buffer,SCROLL_CAL_VALUE);
//
// strcpy(Buffer, "B1 : ");
// sprintf(Buffer+strlen(Buffer), "%i", B1);
// scroll_display(Buffer,SCROLL_CAL_VALUE);
//
// strcpy(Buffer, "B2 : ");
// sprintf(Buffer+strlen(Buffer), "%i", B2);
// scroll_display(Buffer,SCROLL_CAL_VALUE);

B6 = B5 - 4000;
X1 = (B2 * (B6 * B6 >> 12)) >> 11;
X2 = AC2 * B6 >> 11;
X3 = X1 + X2;
B3 = (((AC1 * 4 + X3) << oss) + 2) >> 2;
X1 = AC3 * B6 / 8192;
X2 = (B1 * (B6 * B6 >> 12)) >> 16;
X3 = ((X1 + X2) + 2) >> 2;
B4 = AC4 * (unsigned long)(X3 + 32768) >> 15;
B7 = ((unsigned long)UP - B3) * (50000 >> oss);

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;
long temp_1;

*druck = p + ((X1 + X2 + 3791) >> 4);

strcpy(Buffer, "Druck : ");
sprintf(Buffer+strlen(Buffer), "%ld", *druck);
scroll_display(Buffer,SCROLL_CAL_VALUE);


return ret;
}


Kommt irgendein anderer Wert raus...

Scheint als würde mit den Zeigern irgendwas nicht richtig laufen?

sast
20.05.2015, 13:10
Mal rein interessehalber, was kommt denn bei

p = p + ((X1 + X2 + 3791) >> 4);
*druck = p;

strcpy(Buffer, "Druck : ");
sprintf(Buffer+strlen(Buffer), "%ld", *druck);
scroll_display(Buffer,SCROLL_CAL_VALUE);

bzw

*druck = p + ((X1 + X2 + 3791) >> 4);
p = *druck;

strcpy(Buffer, "Druck : ");
sprintf(Buffer+strlen(Buffer), "%ld", p);
scroll_display(Buffer,SCROLL_CAL_VALUE);

heraus? :)

Janiiix3
20.05.2015, 15:13
Ich habe es hin bekommen.

Mit "sprintf" klappt es. Wieso aber nicht mit itoa?


sprintf(pressure+strlen(pressure), "%ld", press_result);

sast
20.05.2015, 15:52
lag also nur an deiner Ausgabe?

Klebwax
20.05.2015, 18:27
Ich habe es hin bekommen.

Mit "sprintf" klappt es. Wieso aber nicht mit itoa?

Möglicherweise, weil:

sprintf(Buffer, "Druck: %ld", p);

ein long anzeigt, itoa() aber, wie der Name "integer to ascii" andeudet, ein int erwartet?

MfG Klebwax

Janiiix3
20.05.2015, 19:10
@sast

nicht gut, habe auch gesehen das du beim auslesen der bytes "i2c_rep_start" nutzt. Das habe ich nicht getan. Vermutlich lag dort auch ein schwerwiegender Fehler.

@Klebwax

Ein "long" ist doch mehr oder weniger auch ein "Integer" halt nur etwas größer.

sast
21.05.2015, 07:41
Ein "long" ist doch mehr oder weniger auch ein "Integer" halt nur etwas größer.

Das hast du hoffentlich nur spaßig gemeint.

Oder schaffst du es einen vollen 10 Liter Eimer komplett in eine 1/4 Liter Kaffetasse zu füllen, ohne das dabei etwas verloren geht.
Wenn du einen long Wert von 40000 hast und in eine int16 Variable schreibst, dann wird das Ergebnis vermutlich ein negativer int Wert sein. Sieh dir mal die Ranges der Datentypen an.

Und noch was. Da du nie von itoa geschrieben hattest bzw das auch nicht so in der main stand, die du hier reingestellt hattest, hätte ich mich noch dumm und dämlich raten können, wo der Fehler liegt.
Es ist wichtig, auch wenn es dir vielleicht nichtig erscheint, möglichst alle Eigenkreationen im Code mit zu zeigen.

Janiiix3
21.05.2015, 08:01
@sast


es hatte ja bei einigen Sensoren geklappt, daraum habe ich auch nicht an der Umwandlaung gezweifelt.
Beim nächsten mal, werde ich dies so tun.