Forum: Mikrocontroller und Digitale Elektronik ESP8266, von Durck/Temp-Sensor BMP180 ausgelesener Wert scheint falsch.


von Matthias (Gast)


Lesenswert?

Hallo zusammen,

ich habe ein paar kleine I2C-Funktionen geschrieben, welche mir die von 
einem BMP180 gewandelte Temperatur berechnen und zurückgeben sollten.

Hier ein Datenblatt dazu:
https://cdn-shop.adafruit.com/datasheets/BST-BMP180-DS000-09.pdf

Diese scheint jedoch falsch, hier ein Beispiel:
ac1=   6486

ac2= - 1021

ac3= -14569

ac4=  31668

ac5=  25184

ac6=  18674

b1 =   6515

b2 =     34

mb = -32768

mc = -11786

md =   2708

Daraus brechne ich nach dem Datenblatt:
X1 =  6696

X2 = -2566

B5 =  4130

T  =  258

Wobei:
1
  int32_t X1 = int32_t(int32_t(readtemp - int32_t(ac6)) * int32_t(ac5)) / int32_t(32768);
2
  int32_t X2 = int32_t(int32_t(mc) * int32_t(2048)) / int32_t(int32_t(X1) + int32_t (md));
3
  int32_t B5 = X1 + X2;
4
  int32_t T  =  (B5 + 8) / 16;


Dies sollte demnach für 25,8Grad° stehen.
Jedoch habe ich hier im Raum nach anderen Thermometern nur 20Grad°.

Weiteres Problem ist dass, wenn ich den Baustein anfasse, der Wert nur 
auf ca 300 steigt ich mir aber sehr sicher bin mehr als 4° wärmer als 
die Raumtemperatur zu sein.

Problem ist nun dass sich die Debug-Ausgabe exakt mit meinen händischen 
Berechnungen deckt und ich so keinen Berechnungsfehler sehen kann.

Wäre toll wenn jemand eine Idee hat, was hier im folgenden Code wohl 
nicht stimmen kann.
1
void loop() {
2
  server.handleClient();  
3
  delay(100);
4
  getParam();//&ac1, &ac2, &ac3, &ac4, &ac5, &ac6, &b1, &b2, &mb, &mc, &md);
5
  delay(100);
6
  Serial.println(get_temp());
7
}
8
9
void set_pointer_to_addr(uint8_t addr)
10
{
11
  Wire.beginTransmission(0x77);      //Addresse des Bausteins (ef)
12
  Wire.write(addr);                  //fülle Sendepuffer (f6)
13
  Wire.endTransmission();  
14
}
15
16
void getParam()//uint16_t *ac1, uint16_t *ac2, uint16_t *ac3, uint16_t *ac4, uint16_t *ac5, uint16_t *ac6, uint16_t *b1, uint16_t *b2, uint16_t *mb, uint16_t *mc, uint16_t *md)
17
{
18
  set_pointer_to_addr(0xaa);
19
  Wire.requestFrom(0x77,22);          //read the Byte 0xaa
20
  ac1 = get_one_param_16();
21
  ac2 = get_one_param_16();
22
  ac3 = get_one_param_16();
23
  ac4 = get_one_param_16u();
24
  ac5 = get_one_param_16u();
25
  ac6 = get_one_param_16u();
26
  b1 = get_one_param_16();
27
  b2 = get_one_param_16();
28
  mb = get_one_param_16();
29
  mc = get_one_param_16();
30
  md = get_one_param_16();
31
  Serial.print("AC1 : ");
32
  Serial.println(ac1);
33
  Serial.print("AC2 : ");
34
  Serial.println(ac2);
35
  Serial.print("AC3 : ");
36
  Serial.println(ac3);
37
  Serial.print("AC4 : ");
38
  Serial.println(ac4);
39
  Serial.print("AC5 : ");
40
  Serial.println(ac5);
41
  Serial.print("AC6 : ");
42
  Serial.println(ac6);
43
  Serial.print("B1 : ");
44
  Serial.println(b1);
45
  Serial.print("B2 : ");
46
  Serial.println(b2);
47
  Serial.print("mb : ");
48
  Serial.println(mb);
49
  Serial.print("mc : ");
50
  Serial.println(mc);
51
  Serial.print("md : ");
52
  Serial.println(md);
53
}
54
55
int16_t get_one_param_16()
56
{
57
  int16_t internal = 0x0000;
58
  int16_t temp     = 0x0000;
59
  internal = Wire.read();      //1
60
  internal = internal<<8;
61
  internal = internal + 0x00ff;
62
  temp = Wire.read() + 0xff00;
63
  internal = internal & temp;  //22
64
  return internal;
65
}
66
67
uint16_t get_one_param_16u()
68
{
69
  int16_t internal = 0x0000;
70
  int16_t temp     = 0x0000;
71
  internal = Wire.read();      //1
72
  internal = internal<<8;
73
  internal = internal + 0x00ff;
74
  temp = Wire.read() + 0xff00;
75
  internal = internal & temp;  //22
76
  return internal;
77
}
78
79
int32_t get_temp()
80
{
81
  int16_t temp = 0x0000;
82
  start_temp_conv();                  //start temp-conversion
83
  delay(10);
84
  set_pointer_to_addr(0xf6);         //set pointer to read data temperature reg MSB
85
  delay(10);
86
  Wire.requestFrom(0x77,2);          //read the Byte f6 and f7
87
  int32_t UT = get_one_param_32();
88
  Serial.print("UT : ");
89
  Serial.println(UT);
90
  return calc_temp(UT);
91
}
92
93
void start_temp_conv()
94
{
95
  Wire.beginTransmission(0x77);      //Addresse des Bausteins (ef)
96
  Wire.write(0xf4);                  //fülle Sendepuffer (f4)
97
  Wire.write(0x2e);                  //Wandlung starten
98
  Wire.endTransmission();            //sende Daten
99
}
100
int32_t get_one_param_32()
101
{
102
  int16_t internal = 0x0000;
103
  int16_t temp     = 0x0000;
104
  internal = Wire.read();      //1
105
  internal = internal<<8;
106
  internal = internal + 0x00ff;
107
  temp = Wire.read() + 0xff00;
108
  internal = internal & temp;  //22
109
  return internal;
110
}
111
112
int32_t calc_temp(int32_t readtemp)
113
{
114
  int32_t X1 = int32_t(int32_t(readtemp - int32_t(ac6)) * int32_t(ac5)) / int32_t(32768);
115
  int32_t X2 = int32_t(int32_t(mc) * int32_t(2048)) / int32_t(int32_t(X1) + int32_t (md));
116
  int32_t B5 = X1 + X2;
117
  int32_t T  =  (B5 + 8) / 16;
118
  Serial.print("X1 : ");
119
  Serial.println(X1);
120
  Serial.print("X2 : ");
121
  Serial.println(X2);
122
  Serial.print("B5 : ");
123
  Serial.println(B5);
124
  Serial.print("T : ");
125
  Serial.println(T);
126
  return T;
127
}

von Gerald K. (geku)


Lesenswert?

Vielleicht iiegt es an den "Calibration coefficients" ?

von Wolfgang (Gast)


Lesenswert?

Matthias schrieb:
> Wäre toll wenn jemand eine Idee hat, was hier im folgenden Code wohl
> nicht stimmen kann.

Bevor du Fehler in deinem Code suchst, prüfe doch erstmal deinen Sensor. 
Es gibt genug Code zu finden, der den BMP180 mit einem ESP8266 
auswertet.

Grund für einen überhöhten Temperaturwert könnte Erwärmung durch 
benachbarte Bauteile sein. Das hängt vor Aufbau ab, erklärt aber nicht 
deine Begrenzung bei 300. Nimm einen Warmluftgebläse um auf höhere 
Temperaturen zu kommen. Der BMP180 darf bis max. 85°C.

von Matthias (Gast)


Lesenswert?

Wolfgang schrieb:
> Grund für einen überhöhten Temperaturwert könnte Erwärmung durch
> benachbarte Bauteile sein. Das hängt vor Aufbau ab, erklärt aber nicht
> deine Begrenzung bei 300. Nimm einen Warmluftgebläse um auf höhere
> Temperaturen zu kommen. Der BMP180 darf bis max. 85°C.

Sehr gute Idee, habe nun mehrfach festgestellt dass er bei > 56,0° auf 
-242° Springt!

Ich dachte auch schon an irgendeinen Überlauf eines Wertebereichs...

von Matthias (Gast)


Lesenswert?

Nun funktioniert er doch so wir erhofft :)
Wurde tatsächlich etwas erwärmt duch den ESP, zudem kamm der Sprung da 
der Wert UT nicht in 32Bit zurückgegeben wurde!

Der Vollständigkeit hier der Komplette Code
1
!Fumifugium!
2
#include <Wire.h>
3
#include <ESP8266WiFi.h>
4
#include <ESP8266WebServer.h>
5
ESP8266WebServer server(80);
6
const char* ssid = "FRITZ!Box 7490";
7
const char* password = "53639365092847356658";
8
//Signal-Pin des Relais: D1
9
int relay_pin = 5;
10
11
const int sclPin = D1;
12
const int sdaPin = D2;
13
14
int16_t temp;
15
int16_t ac1;
16
int16_t ac2;
17
int16_t ac3;
18
uint16_t ac4;
19
uint16_t ac5;
20
uint16_t ac6;
21
int16_t b1;
22
int16_t b2;
23
int16_t mb;
24
int16_t mc;
25
int16_t md;
26
27
28
void setup()
29
{
30
  Wire.begin(sdaPin, sclPin);
31
32
  pinMode(LED_BUILTIN, OUTPUT);
33
  pinMode(relay_pin, OUTPUT);
34
  Serial.begin(9600);
35
  Serial.println("ESP Gestartet");
36
  WiFi.begin(ssid, password);
37
  Serial.print("Verbindung wird hergestellt ...");
38
  while (WiFi.status() != WL_CONNECTED)
39
  {
40
    delay(500);
41
    Serial.print(".");
42
  }
43
  Serial.println();
44
  Serial.print("Verbunden! IP-Adresse: ");
45
  Serial.println(WiFi.localIP()
46
);
47
  
48
  server.onNotFound([](){
49
    server.send(404, "text/plain", "Link wurde nicht gefunden!");  
50
  });
51
  server.on("/", []() {
52
    server.send(200, "text/plain", "Startseite");
53
  });
54
  server.on("/relay_on", []() {
55
    server.send(200, "text/plain", "Relais wurde angeschaltet.");
56
    relay_on();
57
  });
58
  server.on("/relay_off", []() {
59
    server.send(200, "text/plain", "Relais wurde ausgeschalten.");
60
    relay_off();
61
  });
62
  server.on("/state", []() {
63
    server.send(200, "text/plain", String(digitalRead(relay_pin)));
64
  });
65
  server.begin();
66
67
  Serial.println("Webserver gestartet.");
68
}
69
70
void set_pointer_to_addr(uint8_t addr)
71
{
72
  Wire.beginTransmission(0x77);      //Addresse des Bausteins (ef)
73
  Wire.write(addr);                  //fülle Sendepuffer (f6)
74
  Wire.endTransmission();  
75
}
76
77
void start_temp_conv()
78
{
79
  Wire.beginTransmission(0x77);      //Addresse des Bausteins (ef)
80
  Wire.write(0xf4);                  //fülle Sendepuffer (f4)
81
  Wire.write(0x2e);                  //Wandlung starten
82
  Wire.endTransmission();            //sende Daten
83
}
84
85
int32_t calc_temp(int32_t readtemp)
86
{
87
  
88
  int32_t X1 = int32_t(int32_t(readtemp - int32_t(ac6)) * int32_t(ac5)) / int32_t(32768);
89
  int32_t X2 = int32_t(int32_t(mc) * int32_t(2048)) / int32_t(int32_t(X1) + int32_t (md));
90
  int32_t B5 = X1 + X2;
91
  int32_t T  =  (B5 + 8) / 16;
92
  Serial.print("X1 : ");
93
  Serial.println(X1);
94
  Serial.print("X2 : ");
95
  Serial.println(X2);
96
  Serial.print("B5 : ");
97
  Serial.println(B5);
98
  Serial.print("T : ");
99
  Serial.println(T);
100
  return T;
101
}
102
103
int32_t get_temp()
104
{
105
  int16_t temp = 0x0000;
106
  start_temp_conv();                  //start temp-conversion
107
  delay(10);
108
  set_pointer_to_addr(0xf6);         //set pointer to read data temperature reg MSB
109
  delay(10);
110
  Wire.requestFrom(0x77,2);          //read the Byte f6 and f7
111
  int32_t UT = get_one_param_32();
112
  Serial.print("UT : ");
113
  Serial.println(UT);
114
  return calc_temp(UT);
115
}
116
117
int32_t get_one_param_32()
118
{
119
  int32_t internal = 0x00000000;
120
  int32_t temp     = 0x00000000;
121
  internal = Wire.read();      //1
122
  //Serial.println(ac1);
123
  internal = internal<<8;
124
  //Serial.println(ac1);
125
  internal = internal + 0x000000ff;
126
  //Serial.println(ac1);
127
  temp = Wire.read() +  0x0000ff00;
128
  //Serial.println(temp);
129
  internal = internal & temp;  //22
130
  //Serial.println(ac1);
131
  return internal;
132
}
133
134
uint16_t get_one_param_16u()
135
{
136
  int16_t internal = 0x0000;
137
  int16_t temp     = 0x0000;
138
  internal = Wire.read();      //1
139
  internal = internal<<8;
140
  internal = internal + 0x00ff;
141
  temp = Wire.read() + 0xff00;
142
  internal = internal & temp;  //22
143
  return internal;
144
}
145
146
int16_t get_one_param_16()
147
{
148
  int16_t internal = 0x0000;
149
  int16_t temp     = 0x0000;
150
  internal = Wire.read();      //1
151
  internal = internal<<8;
152
  internal = internal + 0x00ff;
153
  temp = Wire.read() + 0xff00;
154
  internal = internal & temp;  //22
155
  return internal;
156
}
157
158
void getParam()//uint16_t *ac1, uint16_t *ac2, uint16_t *ac3, uint16_t *ac4, uint16_t *ac5, uint16_t *ac6, uint16_t *b1, uint16_t *b2, uint16_t *mb, uint16_t *mc, uint16_t *md)
159
{
160
  set_pointer_to_addr(0xaa);
161
  Wire.requestFrom(0x77,22);          //read the Byte 0xaa
162
  ac1 = get_one_param_16();
163
  ac2 = get_one_param_16();
164
  ac3 = get_one_param_16();
165
  ac4 = get_one_param_16u();
166
  ac5 = get_one_param_16u();
167
  ac6 = get_one_param_16u();
168
  b1 = get_one_param_16();
169
  b2 = get_one_param_16();
170
  mb = get_one_param_16();
171
  mc = get_one_param_16();
172
  md = get_one_param_16();
173
  Serial.print("AC1 : ");
174
  Serial.println(ac1);
175
  Serial.print("AC2 : ");
176
  Serial.println(ac2);
177
  Serial.print("AC3 : ");
178
  Serial.println(ac3);
179
  Serial.print("AC4 : ");
180
  Serial.println(ac4);
181
  Serial.print("AC5 : ");
182
  Serial.println(ac5);
183
  Serial.print("AC6 : ");
184
  Serial.println(ac6);
185
  Serial.print("B1 : ");
186
  Serial.println(b1);
187
  Serial.print("B2 : ");
188
  Serial.println(b2);
189
  Serial.print("mb : ");
190
  Serial.println(mb);
191
  Serial.print("mc : ");
192
  Serial.println(mc);
193
  Serial.print("md : ");
194
  Serial.println(md);
195
}
196
197
void loop() {
198
  server.handleClient();  
199
  delay(100);
200
  getParam();//&ac1, &ac2, &ac3, &ac4, &ac5, &ac6, &b1, &b2, &mb, &mc, &md);
201
  delay(100);
202
  Serial.println(get_temp());
203
}
204
205
206
void relay_on()
207
{
208
  digitalWrite(LED_BUILTIN, HIGH);
209
  //digitalWrite(relay_pin, HIGH);  
210
}
211
void relay_off()
212
{
213
  digitalWrite(LED_BUILTIN, LOW);
214
  //digitalWrite(relay_pin, LOW);    
215
}

von Drago S. (mratix)


Lesenswert?

Matthias schrieb:
...

echo 'const char* password = 
"dasgleichehabeichauchundesfunktioniertsuper";' >> credentials.h
1
#include "credentials.h"

von Helmut -. (dc3yc)


Lesenswert?

Matthias schrieb:
> Der Vollständigkeit hier der Komplette Code

Aber lesen kannst du noch nicht, oder? Ungefähr 15cm höher, wo jetzt 
dieser Text auf meinem Bildschirm geschrieben wird, steht folgendes:

Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Bitte beachte das doch in Zukunft, so sind deine Beiträge besser lesbar!

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.