Guten Tag
Bevor mir die grauen Haare ausgehen, frag ich hier mal in die Runde, ob mit dem Bosch-Sensor schon jemand was gemacht hat und mir dabei ein paar Sourceschnipsel zur Verfügung stellen kann. Ich habe Probleme mit dem Feuchteanteil, wenn ich den Teil ausschalte bekomme ich fein $8000 zurück geliefert (also deaktiviert), wenn ich ihn einschalte immer nur $0000.
Beim Rest also dem Umsetzen des C_Source in Pascal bin ich mir auch nicht sicher, ob das so korrekt ist. Wobei die Werte schlüssig sind.
const
BMx280a : Byte = %1110110;
BMx280b : Byte = %1110111;
BMP280_REG_DIG_T1 : Byte = $88;
BMP280_REG_DIG_T2 : Byte = $8A;
BMP280_REG_DIG_T3 : Byte = $8C;
BMP280_REG_DIG_P1 : Byte = $8E;
BMP280_REG_DIG_P2 : Byte = $90;
BMP280_REG_DIG_P3 : Byte = $92;
BMP280_REG_DIG_P4 : Byte = $94;
BMP280_REG_DIG_P5 : Byte = $96;
BMP280_REG_DIG_P6 : Byte = $98;
BMP280_REG_DIG_P7 : Byte = $9A;
BMP280_REG_DIG_P8 : Byte = $9C;
BMP280_REG_DIG_P9 : Byte = $9E;
BMP280_REG_DIG_H1 : Byte = $A1;
BMP280_REG_DIG_H2 : Byte = $E1;
BMP280_REG_DIG_H3 : Byte = $E3;
BMP280_REG_DIG_H4 : Byte = $E4;
BMP280_REG_DIG_H5 : Byte = $E5;
BMP280_REG_DIG_H6 : Byte = $E7;
BMP280_REG_CHIPID : Byte = $D0;
BMP280_REG_VERSION : Byte = $D1;
BMP280_REG_SOFTRESET : Byte = $E0;
BMP280_REG_CAL26 : Byte = $E1; // R calibration stored in 0xE1-0xF0
BME280_REG_CONTROLHUMID: Byte = $F2;
BME280_REG_STATUS : Byte = $F3;
BMP280_REG_CONTROLMEAS : Byte = $F4;
BMP280_REG_CONFIG : Byte = $F5;
BMP280_REG_PRESSUREDATA: Byte = $F7;
BMP280_REG_TEMPDATA : Byte = $FA;
BME280_REG_HUMIDDATA : Byte = $FD;
type
TBMP280CalibData=Record
dig_T1 : LongInt;
dig_T2 : LongInt;
dig_T3 : LongInt;
dig_P1 : LongInt;
dig_P2 : LongInt;
dig_P3 : LongInt;
dig_P4 : LongInt;
dig_P5 : LongInt;
dig_P6 : LongInt;
dig_P7 : LongInt;
dig_P8 : LongInt;
dig_P9 : LongInt;
dig_H1 : LongInt;
dig_H2 : LongInt;
dig_H3 : LongInt;
dig_H4 : LongInt;
dig_H5 : LongInt;
dig_H6 : LongInt;
end;//bmp280_calib_data;
var
t_fine : LongInt;
BMx280Flag : Byte;
BMx280AOK [@BMx280Flag,0]: Bit;
BME280AOK [@BMx280Flag,1]: Bit;
BME280ACalibOK[@BMx280Flag,2]: Bit;
BMx280BOK [@BMx280Flag,4]: Bit;
BMP280CalibData:TBMP280CalibData;
Function ReadBMPRegister(I2CAdr:Byte;Reg:Byte):Word;
var Res1,Res2:Byte;
var Res:Word;
Begin
I2C_Out(I2CAdr, Reg); //Adress auf Register 0
I2C_Inp(I2CAdr, Res1); //Register lesen
I2C_Inp(I2CAdr, Res2); //Register lesen
Res:=(Word(Res2) shl 8)+Word(Res1);
Return(Res);
end;
Function ReadBMPRegisterS(I2CAdr:Byte;Reg:Byte):Integer;
var Res1,Res2:Byte;
var Res:Integer;
Begin
I2C_Out(I2CAdr, Reg); //Adress auf Register 0
//I2C_Inp(I2CAdr, Res); //Register lesen
I2C_Inp(I2CAdr, Res1); //Register lesen
I2C_Inp(I2CAdr, Res2); //Register lesen
//Swap(Res);
Res:=(Integer(Res2) shl 8)+Integer(Res1);
Return(Res);
end;
{var Res:Integer;
Begin
I2C_Out(I2CAdr, Reg); //Adress auf Register 0
I2C_Inp(I2CAdr, Res); //Register lesen
Return(Res);
end;}
Function ReadBMPRegisterByte(I2CAdr:Byte;Reg:Byte):Byte;
var Res:Byte;
Begin
I2C_Out(I2CAdr, Reg); //Adress auf Register 0
I2C_Inp(I2CAdr, Res); //Register lesen
Return(Res);
end;
Function ReadBMPRegisterH5(I2CAdr:Byte;Reg:Byte):Word;
var Res1,Res2:Byte;
var Res:Word;
Begin
I2C_Out(I2CAdr, Reg); //Adress auf Register 0
I2C_Inp(I2CAdr, Res1); //Register lesen
I2C_Inp(I2CAdr, Res2); //Register lesen
Res1:=(Res1 shr 4) and $0F;
Res:=(Word(Res2) shl 4) or Word(Res1);
Return(Res);
end;
Function ReadBMPRegisterH4(I2CAdr:Byte;Reg:Byte):Word;
var Res1,Res2:Byte;
var Res:Word;
Begin
I2C_Out(I2CAdr, Reg); //Adress auf Register 0
I2C_Inp(I2CAdr, Res1); //Register lesen
I2C_Inp(I2CAdr, Res2); //Register lesen
Res2:=Res2 and $0F;
Res:=(Word(Res1) shl 4) or Word(Res2);
Return(Res);
end;
Procedure ReadBMPConfig(I2CAdr:Byte);
var Res:Integer;
Begin
BMP280CalibData.dig_T1 := LongInt(ReadBMPRegister(I2CAdr,BMP280_REG_DIG_T1));
BMP280CalibData.dig_T2 := LongInt(ReadBMPRegisterS(I2CAdr,BMP280_REG_DIG_T2));
BMP280CalibData.dig_T3 := LongInt(ReadBMPRegisterS(I2CAdr,BMP280_REG_DIG_T3));
BMP280CalibData.dig_P1 := LongInt(ReadBMPRegister(I2CAdr,BMP280_REG_DIG_P1));
BMP280CalibData.dig_P2 := LongInt(ReadBMPRegisterS(I2CAdr,BMP280_REG_DIG_P2));
BMP280CalibData.dig_P3 := LongInt(ReadBMPRegisterS(I2CAdr,BMP280_REG_DIG_P3));
BMP280CalibData.dig_P4 := LongInt(ReadBMPRegisterS(I2CAdr,BMP280_REG_DIG_P4));
BMP280CalibData.dig_P5 := LongInt(ReadBMPRegisterS(I2CAdr,BMP280_REG_DIG_P5));
BMP280CalibData.dig_P6 := LongInt(ReadBMPRegisterS(I2CAdr,BMP280_REG_DIG_P6));
BMP280CalibData.dig_P7 := LongInt(ReadBMPRegisterS(I2CAdr,BMP280_REG_DIG_P7));
BMP280CalibData.dig_P8 := LongInt(ReadBMPRegisterS(I2CAdr,BMP280_REG_DIG_P8));
BMP280CalibData.dig_P9 := LongInt(ReadBMPRegisterS(I2CAdr,BMP280_REG_DIG_P9));
BMP280CalibData.dig_H1 := LongInt(ReadBMPRegisterByte(I2CAdr,BMP280_REG_DIG_H1));
BMP280CalibData.dig_H2 := LongInt(ReadBMPRegisterS (I2CAdr,BMP280_REG_DIG_H2));
BMP280CalibData.dig_H3 := LongInt(ReadBMPRegisterByte(I2CAdr,BMP280_REG_DIG_H3));
BMP280CalibData.dig_H4 := LongInt(ReadBMPRegisterH4 (I2CAdr,BMP280_REG_DIG_H4));
BMP280CalibData.dig_H5 := LongInt(ReadBMPRegisterH5 (I2CAdr,BMP280_REG_DIG_H5));
BMP280CalibData.dig_H6 := LongInt(ReadBMPRegisterByte(I2CAdr,BMP280_REG_DIG_H6));
end;
Function Read24(I2CAdr:Byte;Reg:Byte):LongInt;
var Res:Byte;
Temp,Temp1,Temp2,Temp3:LongInt;
Begin
I2C_Out(I2CAdr, Reg); //Adress auf Register 0
I2C_Inp(I2CAdr, Res); //Register lesen
Temp1:=LongInt(Res);
I2C_Inp(I2CAdr, Res); //Register lesen
Temp2:=LongInt(Res);
I2C_Inp(I2CAdr, Res); //Register lesen
Temp3:=LongInt(Res);
Temp:=(Temp1 shl 16) or (Temp2 shl 8) or Temp3;
Return(Temp);
end;
Procedure ReadBMP280Temperature(I2CAdr:Byte);
Var adc_t,var1,var2 : LongInt;
dig_T1,dig_T2,dig_T3:LongInt;
Begin
adc_t:= Read24(I2CAdr,BMP280_REG_TEMPDATA);
if adc_t=$800000 then
SensorTemperatur:=-300.0;
else
adc_t:=adc_t shr 4;
var1 := ((((adc_T shr 3) - (BMP280CalibData.dig_T1 shl 1))) * (BMP280CalibData.dig_T2)) shr 11;
var2 := (((((adc_T shr 4) - (BMP280CalibData.dig_T1)) * ((adc_T shr 4) - (BMP280CalibData.dig_T1))) shr 12) * (BMP280CalibData.dig_T3)) shr 14;
t_fine := var1 + var2;
SensorTemperatur := Float((t_fine * 5 + 128) shr 8);
SensorTemperatur := SensorTemperatur / 100;
var1 := ((adc_T div 16384) - (BMP280CalibData.dig_T1 div 1024)) * BMP280CalibData.dig_T2;
var2 := ((adc_T div 131072) - (BMP280CalibData.dig_T1 div 8192)) * ((adc_T div 131072) - (BMP280CalibData.dig_T1 div 8192)) * BMP280CalibData.dig_T3;
t_fine := var1 + var2;
//SensorTemperatur := Float(t_fine div 5120);
var1 := ((((adc_T shr 3) - (BMP280CalibData.dig_T1 shl 1))) * (BMP280CalibData.dig_T2)) shr 11;
var2 := (((((adc_T shr 4) - (BMP280CalibData.dig_T1)) * ((adc_T shr 4) - (BMP280CalibData.dig_T1))) shr 12) * (BMP280CalibData.dig_T3)) shr 14;
t_fine := var1 + var2;
SensorTemperatur := Float((t_fine * 5 + 128) shr 8);
endif;
end;
Procedure ReadBMP280PressureEx(I2CAdr:Byte);
var adc_p,temp1,temp2:LongInt;
p1:Fix64;
p:Int64;
var1,var2:Int64;
temp64:int64;
Result:Float;
begin
adc_p:= Read24(I2CAdr,BMP280_REG_PRESSUREDATA);
if adc_p=$800000 then
SensorLuftDruck:=-300.0;
else
adc_p:= adc_p shr 4;
var1 := Int64(t_fine) - 128000;
var2 := var1 * var1 * int64(BMP280CalibData.dig_P6);
var2 := var2 + ((var1*Int64(BMP280CalibData.dig_P5)) shl 17);
var2 := var2 + (Int64(BMP280CalibData.dig_P4) shl 35);
var1 := ((var1 * var1 * Int64(BMP280CalibData.dig_P3) shr 8) + (var1 * Int64(BMP280CalibData.dig_P2)) shl 12);
var1 := (((1 shl 47)+var1) * (Int64(BMP280CalibData.dig_P1)) shr 33);
if var1=0 then
SensorLuftDruck:=0;
else
p := 1048576 - Int64(adc_P);
p := (((p shl 31) - var2)*3125) div var1;
var1:= (Int64(BMP280CalibData.dig_P9) * (p shr 13) * (p shr 13)) shr 25;
var2:= (Int64(BMP280CalibData.dig_P8) * p) shr 19;
p := ((p + var1 + var2) shr 8) + (Int64(BMP280CalibData.dig_P7) shl 4);
p := p div 256;
endif;
endif;
end;
Procedure ReadBMP280Pressure(I2CAdr:Byte);
var adc_p,press1, press2,v1,v2:LongInt;
P:LongInt;
begin
adc_p:= Read24(I2CAdr,BMP280_REG_PRESSUREDATA);
if adc_p=$800000 then
SensorLuftDruck:=-300.0;
else
adc_p:= adc_p shr 4;
v1 := (t_fine div 2) - 64000;
v2 := (((v1 div 4) * (v1 div 4)) div 2048) * BMP280CalibData.dig_P6;
v2 := v2 + ((v1 * BMP280CalibData.dig_P5) * 2);
v2 := (v2 div 4) + (BMP280CalibData.dig_P4 * 65536);
v1 := (((BMP280CalibData.dig_P3 * (((v1 div 4) * (v1 div 4)) div 8192)) div 8) + ((BMP280CalibData.dig_P2 * v1) div 2)) div 262144;
v1 := ((32768 + v1) * BMP280CalibData.dig_P1) div 32768;
if v1 = 0 then
SensorLuftDruck:=0;
else
p:= ((1048576 - adc_P) - (v2 div 4096)) * 3125;
if p < $80000000 then
p := (p * 2) div v1;
else
p := (p div v1) * 2;
endif;
v1 := (BMP280CalibData.dig_P9 * (((p div 8) * (p div 8)) div 81920)) div 4096;
v2 := ((p div 4) * BMP280CalibData.dig_P8) div 8192;
p := p + ((v1 + v2 + BMP280CalibData.dig_P7) div 16);
SensorLuftDruck:=Float(p) / 100;
endif;
endif;
end;
Procedure Read280Humidity(I2CAdr:Byte);
var adc_H,varh:Longint;
Begin
adc_H := LongInt(ReadBMPRegister(I2CAdr,BME280_REG_HUMIDDATA));
if adc_h=$8000 then
SensorLuftFeuchte:=-200.0;
else
varh := t_fine - 76800;
if varh = 0 then
SensorLuftFeuchte:=0;
else
varh := (adc_H - (BMP280CalibData.dig_H4 * 64 + BMP280CalibData.dig_H5 div 16384 * varh)) * (BMP280CalibData.dig_H2 div 65536 * (1 + BMP280CalibData.dig_H6 div 67108864 * varh * (1 + BMP280CalibData.dig_H3 div 67108864 * varh)));
varh := varh * (1 - BMP280CalibData.dig_H1 * varh div 524288);
if varh > 100 then
varh := 100;
elsif varh < 0 then
varh := 0;
endif;
SensorLuftFeuchte:=Float(varh) / 100;
endif;
endif;
end;
(**************************************************************************)
(*!
@brief Result:= true if chip is busy reading cal data
*)
(**************************************************************************)
Function BMP280isReadingCalibration(I2CAdr:Byte):Boolean;
var rStatus:Byte;
res:Boolean;
Begin
Res:=False;
if I2C_Out(I2CAdr,BME280_REG_STATUS) then
if I2C_Inp(I2CAdr,rStatus) then //Register lesen
Res:=(rStatus and 1) <> 0;
endif;
endif;
Return(Res);
end;
Function BMP280isReady(I2CAdr:Byte):Boolean;
var rStatus:Byte;
res:Boolean;
Begin
Res:=False;
if I2C_Out(I2CAdr,BME280_REG_STATUS) then
if I2C_Inp(I2CAdr,rStatus) then //Register lesen
Res:=rStatus = 0;
endif;
endif;
Return(Res);
end;
Function CheckBMx280:Boolean;
var ID:Byte;
Begin
BMx280Flag:=0;
BMx280AOK :=I2C_Stat(BMx280a); //Test ob BMx280 vorhanden
if not BMx280AOK then
BMx280BOK :=I2C_Stat(BMx280b); //Test ob BMx280 vorhanden
endif;
if BMx280AOK then
if I2C_Out(BMx280a, BMP280_REG_CHIPID) then //Adress auf Register 0
if I2C_Inp(BMx280a, ID) then //Register lesen
BME280AOK:=ID=$60;
if BME280AOK then
I2C_Out(BMx280a,BMP280_REG_SOFTRESET, $B6);
mDelay(300); // 300 ms warten
ID:=0;
while BMP280isReadingCalibration(BMx280a) and (ID<10) do
Inc(ID);
mDelay(100);
endwhile;
if ID<10 then
BME280ACalibOK:=True;
ReadBMPConfig(BMx280a); // Config lesen
I2C_Out(BMx280a,BME280_REG_CONTROLHUMID, %00000001); //
I2C_Out(BMx280a,BMP280_REG_CONFIG , %01000000);
I2C_Out(BMx280a,BMP280_REG_CONTROLMEAS , %00111111);
endif;
endif;
endif;
endif;
endif;
Return(BMx280AOK or BMx280BOK);
end;
Procedure ReadBMx280;
var OutAdr:Byte;
Begin
if BMx280AOK or BMx280BOK then
OutAdr:=BMx280a;
if BMx280BOK then
OutAdr:=BMx280b;
endif;
//if BMP280isReady(OutAdr) then
ReadBMP280Temperature(OutAdr);
ReadBMP280Pressure(OutAdr);
Read280Humidity(OutAdr);
//endif;
endif;
end;
Bevor mir die grauen Haare ausgehen, frag ich hier mal in die Runde, ob mit dem Bosch-Sensor schon jemand was gemacht hat und mir dabei ein paar Sourceschnipsel zur Verfügung stellen kann. Ich habe Probleme mit dem Feuchteanteil, wenn ich den Teil ausschalte bekomme ich fein $8000 zurück geliefert (also deaktiviert), wenn ich ihn einschalte immer nur $0000.
Beim Rest also dem Umsetzen des C_Source in Pascal bin ich mir auch nicht sicher, ob das so korrekt ist. Wobei die Werte schlüssig sind.
Code
const
BMx280a : Byte = %1110110;
BMx280b : Byte = %1110111;
BMP280_REG_DIG_T1 : Byte = $88;
BMP280_REG_DIG_T2 : Byte = $8A;
BMP280_REG_DIG_T3 : Byte = $8C;
BMP280_REG_DIG_P1 : Byte = $8E;
BMP280_REG_DIG_P2 : Byte = $90;
BMP280_REG_DIG_P3 : Byte = $92;
BMP280_REG_DIG_P4 : Byte = $94;
BMP280_REG_DIG_P5 : Byte = $96;
BMP280_REG_DIG_P6 : Byte = $98;
BMP280_REG_DIG_P7 : Byte = $9A;
BMP280_REG_DIG_P8 : Byte = $9C;
BMP280_REG_DIG_P9 : Byte = $9E;
BMP280_REG_DIG_H1 : Byte = $A1;
BMP280_REG_DIG_H2 : Byte = $E1;
BMP280_REG_DIG_H3 : Byte = $E3;
BMP280_REG_DIG_H4 : Byte = $E4;
BMP280_REG_DIG_H5 : Byte = $E5;
BMP280_REG_DIG_H6 : Byte = $E7;
BMP280_REG_CHIPID : Byte = $D0;
BMP280_REG_VERSION : Byte = $D1;
BMP280_REG_SOFTRESET : Byte = $E0;
BMP280_REG_CAL26 : Byte = $E1; // R calibration stored in 0xE1-0xF0
BME280_REG_CONTROLHUMID: Byte = $F2;
BME280_REG_STATUS : Byte = $F3;
BMP280_REG_CONTROLMEAS : Byte = $F4;
BMP280_REG_CONFIG : Byte = $F5;
BMP280_REG_PRESSUREDATA: Byte = $F7;
BMP280_REG_TEMPDATA : Byte = $FA;
BME280_REG_HUMIDDATA : Byte = $FD;
type
TBMP280CalibData=Record
dig_T1 : LongInt;
dig_T2 : LongInt;
dig_T3 : LongInt;
dig_P1 : LongInt;
dig_P2 : LongInt;
dig_P3 : LongInt;
dig_P4 : LongInt;
dig_P5 : LongInt;
dig_P6 : LongInt;
dig_P7 : LongInt;
dig_P8 : LongInt;
dig_P9 : LongInt;
dig_H1 : LongInt;
dig_H2 : LongInt;
dig_H3 : LongInt;
dig_H4 : LongInt;
dig_H5 : LongInt;
dig_H6 : LongInt;
end;//bmp280_calib_data;
var
t_fine : LongInt;
BMx280Flag : Byte;
BMx280AOK [@BMx280Flag,0]: Bit;
BME280AOK [@BMx280Flag,1]: Bit;
BME280ACalibOK[@BMx280Flag,2]: Bit;
BMx280BOK [@BMx280Flag,4]: Bit;
BMP280CalibData:TBMP280CalibData;
Function ReadBMPRegister(I2CAdr:Byte;Reg:Byte):Word;
var Res1,Res2:Byte;
var Res:Word;
Begin
I2C_Out(I2CAdr, Reg); //Adress auf Register 0
I2C_Inp(I2CAdr, Res1); //Register lesen
I2C_Inp(I2CAdr, Res2); //Register lesen
Res:=(Word(Res2) shl 8)+Word(Res1);
Return(Res);
end;
Function ReadBMPRegisterS(I2CAdr:Byte;Reg:Byte):Integer;
var Res1,Res2:Byte;
var Res:Integer;
Begin
I2C_Out(I2CAdr, Reg); //Adress auf Register 0
//I2C_Inp(I2CAdr, Res); //Register lesen
I2C_Inp(I2CAdr, Res1); //Register lesen
I2C_Inp(I2CAdr, Res2); //Register lesen
//Swap(Res);
Res:=(Integer(Res2) shl 8)+Integer(Res1);
Return(Res);
end;
{var Res:Integer;
Begin
I2C_Out(I2CAdr, Reg); //Adress auf Register 0
I2C_Inp(I2CAdr, Res); //Register lesen
Return(Res);
end;}
Function ReadBMPRegisterByte(I2CAdr:Byte;Reg:Byte):Byte;
var Res:Byte;
Begin
I2C_Out(I2CAdr, Reg); //Adress auf Register 0
I2C_Inp(I2CAdr, Res); //Register lesen
Return(Res);
end;
Function ReadBMPRegisterH5(I2CAdr:Byte;Reg:Byte):Word;
var Res1,Res2:Byte;
var Res:Word;
Begin
I2C_Out(I2CAdr, Reg); //Adress auf Register 0
I2C_Inp(I2CAdr, Res1); //Register lesen
I2C_Inp(I2CAdr, Res2); //Register lesen
Res1:=(Res1 shr 4) and $0F;
Res:=(Word(Res2) shl 4) or Word(Res1);
Return(Res);
end;
Function ReadBMPRegisterH4(I2CAdr:Byte;Reg:Byte):Word;
var Res1,Res2:Byte;
var Res:Word;
Begin
I2C_Out(I2CAdr, Reg); //Adress auf Register 0
I2C_Inp(I2CAdr, Res1); //Register lesen
I2C_Inp(I2CAdr, Res2); //Register lesen
Res2:=Res2 and $0F;
Res:=(Word(Res1) shl 4) or Word(Res2);
Return(Res);
end;
Procedure ReadBMPConfig(I2CAdr:Byte);
var Res:Integer;
Begin
BMP280CalibData.dig_T1 := LongInt(ReadBMPRegister(I2CAdr,BMP280_REG_DIG_T1));
BMP280CalibData.dig_T2 := LongInt(ReadBMPRegisterS(I2CAdr,BMP280_REG_DIG_T2));
BMP280CalibData.dig_T3 := LongInt(ReadBMPRegisterS(I2CAdr,BMP280_REG_DIG_T3));
BMP280CalibData.dig_P1 := LongInt(ReadBMPRegister(I2CAdr,BMP280_REG_DIG_P1));
BMP280CalibData.dig_P2 := LongInt(ReadBMPRegisterS(I2CAdr,BMP280_REG_DIG_P2));
BMP280CalibData.dig_P3 := LongInt(ReadBMPRegisterS(I2CAdr,BMP280_REG_DIG_P3));
BMP280CalibData.dig_P4 := LongInt(ReadBMPRegisterS(I2CAdr,BMP280_REG_DIG_P4));
BMP280CalibData.dig_P5 := LongInt(ReadBMPRegisterS(I2CAdr,BMP280_REG_DIG_P5));
BMP280CalibData.dig_P6 := LongInt(ReadBMPRegisterS(I2CAdr,BMP280_REG_DIG_P6));
BMP280CalibData.dig_P7 := LongInt(ReadBMPRegisterS(I2CAdr,BMP280_REG_DIG_P7));
BMP280CalibData.dig_P8 := LongInt(ReadBMPRegisterS(I2CAdr,BMP280_REG_DIG_P8));
BMP280CalibData.dig_P9 := LongInt(ReadBMPRegisterS(I2CAdr,BMP280_REG_DIG_P9));
BMP280CalibData.dig_H1 := LongInt(ReadBMPRegisterByte(I2CAdr,BMP280_REG_DIG_H1));
BMP280CalibData.dig_H2 := LongInt(ReadBMPRegisterS (I2CAdr,BMP280_REG_DIG_H2));
BMP280CalibData.dig_H3 := LongInt(ReadBMPRegisterByte(I2CAdr,BMP280_REG_DIG_H3));
BMP280CalibData.dig_H4 := LongInt(ReadBMPRegisterH4 (I2CAdr,BMP280_REG_DIG_H4));
BMP280CalibData.dig_H5 := LongInt(ReadBMPRegisterH5 (I2CAdr,BMP280_REG_DIG_H5));
BMP280CalibData.dig_H6 := LongInt(ReadBMPRegisterByte(I2CAdr,BMP280_REG_DIG_H6));
end;
Function Read24(I2CAdr:Byte;Reg:Byte):LongInt;
var Res:Byte;
Temp,Temp1,Temp2,Temp3:LongInt;
Begin
I2C_Out(I2CAdr, Reg); //Adress auf Register 0
I2C_Inp(I2CAdr, Res); //Register lesen
Temp1:=LongInt(Res);
I2C_Inp(I2CAdr, Res); //Register lesen
Temp2:=LongInt(Res);
I2C_Inp(I2CAdr, Res); //Register lesen
Temp3:=LongInt(Res);
Temp:=(Temp1 shl 16) or (Temp2 shl 8) or Temp3;
Return(Temp);
end;
Procedure ReadBMP280Temperature(I2CAdr:Byte);
Var adc_t,var1,var2 : LongInt;
dig_T1,dig_T2,dig_T3:LongInt;
Begin
adc_t:= Read24(I2CAdr,BMP280_REG_TEMPDATA);
if adc_t=$800000 then
SensorTemperatur:=-300.0;
else
adc_t:=adc_t shr 4;
var1 := ((((adc_T shr 3) - (BMP280CalibData.dig_T1 shl 1))) * (BMP280CalibData.dig_T2)) shr 11;
var2 := (((((adc_T shr 4) - (BMP280CalibData.dig_T1)) * ((adc_T shr 4) - (BMP280CalibData.dig_T1))) shr 12) * (BMP280CalibData.dig_T3)) shr 14;
t_fine := var1 + var2;
SensorTemperatur := Float((t_fine * 5 + 128) shr 8);
SensorTemperatur := SensorTemperatur / 100;
var1 := ((adc_T div 16384) - (BMP280CalibData.dig_T1 div 1024)) * BMP280CalibData.dig_T2;
var2 := ((adc_T div 131072) - (BMP280CalibData.dig_T1 div 8192)) * ((adc_T div 131072) - (BMP280CalibData.dig_T1 div 8192)) * BMP280CalibData.dig_T3;
t_fine := var1 + var2;
//SensorTemperatur := Float(t_fine div 5120);
var1 := ((((adc_T shr 3) - (BMP280CalibData.dig_T1 shl 1))) * (BMP280CalibData.dig_T2)) shr 11;
var2 := (((((adc_T shr 4) - (BMP280CalibData.dig_T1)) * ((adc_T shr 4) - (BMP280CalibData.dig_T1))) shr 12) * (BMP280CalibData.dig_T3)) shr 14;
t_fine := var1 + var2;
SensorTemperatur := Float((t_fine * 5 + 128) shr 8);
endif;
end;
Procedure ReadBMP280PressureEx(I2CAdr:Byte);
var adc_p,temp1,temp2:LongInt;
p1:Fix64;
p:Int64;
var1,var2:Int64;
temp64:int64;
Result:Float;
begin
adc_p:= Read24(I2CAdr,BMP280_REG_PRESSUREDATA);
if adc_p=$800000 then
SensorLuftDruck:=-300.0;
else
adc_p:= adc_p shr 4;
var1 := Int64(t_fine) - 128000;
var2 := var1 * var1 * int64(BMP280CalibData.dig_P6);
var2 := var2 + ((var1*Int64(BMP280CalibData.dig_P5)) shl 17);
var2 := var2 + (Int64(BMP280CalibData.dig_P4) shl 35);
var1 := ((var1 * var1 * Int64(BMP280CalibData.dig_P3) shr 8) + (var1 * Int64(BMP280CalibData.dig_P2)) shl 12);
var1 := (((1 shl 47)+var1) * (Int64(BMP280CalibData.dig_P1)) shr 33);
if var1=0 then
SensorLuftDruck:=0;
else
p := 1048576 - Int64(adc_P);
p := (((p shl 31) - var2)*3125) div var1;
var1:= (Int64(BMP280CalibData.dig_P9) * (p shr 13) * (p shr 13)) shr 25;
var2:= (Int64(BMP280CalibData.dig_P8) * p) shr 19;
p := ((p + var1 + var2) shr 8) + (Int64(BMP280CalibData.dig_P7) shl 4);
p := p div 256;
endif;
endif;
end;
Procedure ReadBMP280Pressure(I2CAdr:Byte);
var adc_p,press1, press2,v1,v2:LongInt;
P:LongInt;
begin
adc_p:= Read24(I2CAdr,BMP280_REG_PRESSUREDATA);
if adc_p=$800000 then
SensorLuftDruck:=-300.0;
else
adc_p:= adc_p shr 4;
v1 := (t_fine div 2) - 64000;
v2 := (((v1 div 4) * (v1 div 4)) div 2048) * BMP280CalibData.dig_P6;
v2 := v2 + ((v1 * BMP280CalibData.dig_P5) * 2);
v2 := (v2 div 4) + (BMP280CalibData.dig_P4 * 65536);
v1 := (((BMP280CalibData.dig_P3 * (((v1 div 4) * (v1 div 4)) div 8192)) div 8) + ((BMP280CalibData.dig_P2 * v1) div 2)) div 262144;
v1 := ((32768 + v1) * BMP280CalibData.dig_P1) div 32768;
if v1 = 0 then
SensorLuftDruck:=0;
else
p:= ((1048576 - adc_P) - (v2 div 4096)) * 3125;
if p < $80000000 then
p := (p * 2) div v1;
else
p := (p div v1) * 2;
endif;
v1 := (BMP280CalibData.dig_P9 * (((p div 8) * (p div 8)) div 81920)) div 4096;
v2 := ((p div 4) * BMP280CalibData.dig_P8) div 8192;
p := p + ((v1 + v2 + BMP280CalibData.dig_P7) div 16);
SensorLuftDruck:=Float(p) / 100;
endif;
endif;
end;
Procedure Read280Humidity(I2CAdr:Byte);
var adc_H,varh:Longint;
Begin
adc_H := LongInt(ReadBMPRegister(I2CAdr,BME280_REG_HUMIDDATA));
if adc_h=$8000 then
SensorLuftFeuchte:=-200.0;
else
varh := t_fine - 76800;
if varh = 0 then
SensorLuftFeuchte:=0;
else
varh := (adc_H - (BMP280CalibData.dig_H4 * 64 + BMP280CalibData.dig_H5 div 16384 * varh)) * (BMP280CalibData.dig_H2 div 65536 * (1 + BMP280CalibData.dig_H6 div 67108864 * varh * (1 + BMP280CalibData.dig_H3 div 67108864 * varh)));
varh := varh * (1 - BMP280CalibData.dig_H1 * varh div 524288);
if varh > 100 then
varh := 100;
elsif varh < 0 then
varh := 0;
endif;
SensorLuftFeuchte:=Float(varh) / 100;
endif;
endif;
end;
(**************************************************************************)
(*!
@brief Result:= true if chip is busy reading cal data
*)
(**************************************************************************)
Function BMP280isReadingCalibration(I2CAdr:Byte):Boolean;
var rStatus:Byte;
res:Boolean;
Begin
Res:=False;
if I2C_Out(I2CAdr,BME280_REG_STATUS) then
if I2C_Inp(I2CAdr,rStatus) then //Register lesen
Res:=(rStatus and 1) <> 0;
endif;
endif;
Return(Res);
end;
Function BMP280isReady(I2CAdr:Byte):Boolean;
var rStatus:Byte;
res:Boolean;
Begin
Res:=False;
if I2C_Out(I2CAdr,BME280_REG_STATUS) then
if I2C_Inp(I2CAdr,rStatus) then //Register lesen
Res:=rStatus = 0;
endif;
endif;
Return(Res);
end;
Function CheckBMx280:Boolean;
var ID:Byte;
Begin
BMx280Flag:=0;
BMx280AOK :=I2C_Stat(BMx280a); //Test ob BMx280 vorhanden
if not BMx280AOK then
BMx280BOK :=I2C_Stat(BMx280b); //Test ob BMx280 vorhanden
endif;
if BMx280AOK then
if I2C_Out(BMx280a, BMP280_REG_CHIPID) then //Adress auf Register 0
if I2C_Inp(BMx280a, ID) then //Register lesen
BME280AOK:=ID=$60;
if BME280AOK then
I2C_Out(BMx280a,BMP280_REG_SOFTRESET, $B6);
mDelay(300); // 300 ms warten
ID:=0;
while BMP280isReadingCalibration(BMx280a) and (ID<10) do
Inc(ID);
mDelay(100);
endwhile;
if ID<10 then
BME280ACalibOK:=True;
ReadBMPConfig(BMx280a); // Config lesen
I2C_Out(BMx280a,BME280_REG_CONTROLHUMID, %00000001); //
I2C_Out(BMx280a,BMP280_REG_CONFIG , %01000000);
I2C_Out(BMx280a,BMP280_REG_CONTROLMEAS , %00111111);
endif;
endif;
endif;
endif;
endif;
Return(BMx280AOK or BMx280BOK);
end;
Procedure ReadBMx280;
var OutAdr:Byte;
Begin
if BMx280AOK or BMx280BOK then
OutAdr:=BMx280a;
if BMx280BOK then
OutAdr:=BMx280b;
endif;
//if BMP280isReady(OutAdr) then
ReadBMP280Temperature(OutAdr);
ReadBMP280Pressure(OutAdr);
Read280Humidity(OutAdr);
//endif;
endif;
end;