Code
program BME280_Test_3;
{
*************** Firmware für Klimsensor BME280 von Bosch *********************************
Compiler - Version: 5.11.15
Version 1.0
Datum 20.08.2022
Sensormodul: PIM472 von Pimoroni
gibt auch andere.
}
//----------------------------------------------------------------------------------------------------------------------
{$NOSHADOW}
{ $WG} {global Warnings off}
Device = mega644p, VCC = 5;
define_fuses
Override_Fuses;
COMport = USB;
SPIclk = 2000000; // optional SPI programming speed
LockBits0 = [];
FuseBits0 = [SUT1, CKSEL0];
FuseBits1 = [EESave, SPIEN]; // seriell programming
FuseBits2 = [BODLEVEL0, BODLEVEL1];
ProgMode = SPI;
ProgFuses = true;
ProgLock = false;
ProgFlash = true;
ProgEEprom = true;
// ProgEEprom = false;
import SysTick, SerPort1, I2Cport; //
from System import float, Int64;
define
ProcClock = 14745600; // Hertz
SysTick = 1; {msec}
StackSize = 100, iData;
FrameSize = 100, iData;
SerPort1 = 19200, Stop1, parEven; // Baud, StopBits|Parity USB
RxBuffer1 = 130, iData;
TxBuffer1 = 255, iData;
I2Cport = PortC;
I2Cdat = 1;
I2Cclk = 0;
implementation
//--------------------------------------------------------------;
{$IDATA}
{--------------------------------------------------------------}
{ Type Declarations }
type
// structure to hold the calibration data that is programmed into the sensor in the factory
// during manufacture
TBME280_Calibration_Data = record
dig_T1: word;
dig_T2: integer;
dig_T3: integer;
dig_P1: word;
dig_P2: integer;
dig_P3: integer;
dig_P4: integer;
dig_P5: integer;
dig_P6: integer;
dig_P7: integer;
dig_P8: integer;
dig_P9: integer;
dig_H1: byte;
dig_H2: integer;
dig_H3: word;
dig_H4: integer;
dig_H5: integer;
dig_H6: int8;
end;
{--------------------------------------------------------------}
{ Const Declarations }
const
BME280_I2C_Adress : byte = $76;
BME280_REGISTER_CHIPID : byte = $D0;
BME280_REGISTER_VERSION : byte = $D1;
BME280_REGISTER_SOFTRESET : byte = $E0;
BME280_REGISTER_CAL26 : byte = $E1;
BME280_REGISTER_CONTROLHUMID: byte = $F2;
BME280_REGISTER_STATUS : byte = $F3;
BME280_REGISTER_CONTROL : byte = $F4;
BME280_REGISTER_CONFIG : byte = $F5;
BME280_REGISTER_PRESSUREDATA: byte = $F7;
BME280_REGISTER_TEMPDATA : byte = $FA;
BME280_REGISTER_HUMIDDATA : byte = $FD;
// Name of Registers used in the BME280
BME280_DIG_T1_REG : byte = $88;
BME280_DIG_T2_REG : byte = $8A;
BME280_DIG_T3_REG : byte = $8C;
BME280_DIG_P1_REG : byte = $8E;
BME280_DIG_P2_REG : byte = $90;
BME280_DIG_P3_REG : byte = $92;
BME280_DIG_P4_REG : byte = $94;
BME280_DIG_P5_REG : byte = $96;
BME280_DIG_P6_REG : byte = $98;
BME280_DIG_P7_REG : byte = $9A;
BME280_DIG_P8_REG : byte = $9C;
BME280_DIG_P9_REG : byte = $9E;
BME280_DIG_H1_REG : byte = $A1;
BME280_DIG_H2_REG : byte = $E1;
BME280_DIG_H3_REG : byte = $E3;
BME280_DIG_H4_REG : byte = $E4;
BME280_DIG_H5_REG : byte = $E5;
BME280_DIG_H6_REG : byte = $E7;
MODE_SLEEP : byte = 0;
MODE_FORCED : byte = %01;
MODE_NORMAL : byte = %11;
SEALEVELPRESSURE_HPA : float = 1013.25;
{--------------------------------------------------------------}
{ Const Declarations }
const
ja : byte = 255;
nein : byte = 0;
{ Var Declarations }
{$IDATA}
var
b : byte;
BME280_ADDR : byte;
cal_data : TBME280_Calibration_Data;
t_fine : longint;
TempCal : float; // stores the temp offset calibration
Temperature, // stores temperature value
Humidity, // stores humidity value
Pressure : float;
CASE_BME280readTDF : byte;
TmIntervall : SysTimer;
BME_280 : byte;
Id : byte;
// BME280readTemperature;
var1, var2 : longint;
adc_T : longint;
// BME280readPressure;
var3, var4, p : int64;
adc_P : longint;
xStrg : string[12];
// BME280readHumidity;
adc_H,
v_x1_u32r : longint;
h : float;
{--------------------------------------------------------------}
{ functions }
procedure BME280write8(reg, data: byte);
begin
I2Cout(BME280_Addr, reg, data);
end;
function BME280read8(reg: byte): byte;
var
res : byte;
begin
I2Cout(BME280_ADDR, reg);
I2Cinp(BME280_ADDR, res);
return(res);
end;
function BME280read16(reg: byte): word;
var
buff: array[0..1] of byte;
begin
I2Cout(BME280_ADDR, reg);
I2Cinp(BME280_ADDR, buff);
return((word(buff[0]) shl 8) or word(buff[1]));
end;
function BME280read16_LE(reg: byte): word;
var
tmp: word;
begin
tmp:= BME280read16(reg);
return((tmp shr 8) or (tmp shl 8));
end;
function BME280readS16_LE(reg: byte): integer;
begin
return((integer(BME280read16_LE(reg))));
end;
{
function BME280readS16(reg: byte): integer;
begin
return(integer(BME280read16(reg)));
end;
}
// Reads a signed 24 bit value over the I2C bus_REG
function BME280read24(reg: byte): longword;
var
buff: array[0..2] of byte;
begin
I2Cout(BME280_ADDR, reg);
I2Cinp(BME280_ADDR, buff); // only read 3 bytes 24-bit
return((longword(buff[0]) shl 16) or (longword(buff[1]) shl 8) or longword(buff[2]));
end;
procedure BME280_ReadSensorCoefficients;
begin
cal_data.dig_T1:= BME280read16_LE(BME280_DIG_T1_REG);
cal_data.dig_T2:= BME280readS16_LE(BME280_DIG_T2_REG);
cal_data.dig_T3:= BME280readS16_LE(BME280_DIG_T3_REG);
cal_data.dig_P1:= BME280read16_LE(BME280_DIG_P1_REG);
cal_data.dig_P2:= BME280readS16_LE(BME280_DIG_P2_REG);
cal_data.dig_P3:= BME280readS16_LE(BME280_DIG_P3_REG);
cal_data.dig_P4:= BME280readS16_LE(BME280_DIG_P4_REG);
cal_data.dig_P5:= BME280readS16_LE(BME280_DIG_P5_REG);
cal_data.dig_P6:= BME280readS16_LE(BME280_DIG_P6_REG);
cal_data.dig_P7:= BME280readS16_LE(BME280_DIG_P7_REG);
cal_data.dig_P8:= BME280readS16_LE(BME280_DIG_P8_REG);
cal_data.dig_P9:= BME280readS16_LE(BME280_DIG_P9_REG);
cal_data.dig_H1:= BME280read8(BME280_DIG_H1_REG);
cal_data.dig_H2:= BME280readS16_LE(BME280_DIG_H2_REG);
cal_data.dig_H3:= word(BME280read8(BME280_DIG_H3_REG));
cal_data.dig_H4:= integer(integer(BME280read8(BME280_DIG_H4_REG)) shl 4) or (integer(BME280read8(BME280_DIG_H4_REG + 1)) and $F);
cal_data.dig_H5:= integer(integer(BME280read8(BME280_DIG_H5_REG + 1)) shl 4) or (integer(BME280read8(BME280_DIG_H5_REG)) shr 4);
cal_data.dig_H6:= int8(BME280read8(BME280_DIG_H6_REG));
end;
{
// return true if chip is busy reading cal data
// true if reading calibration, false otherwise
function BME280isReadingCalibration: boolean;
var
Status : byte;
begin
Status:= BME280read8(BME280_REGISTER_STATUS);
return((Status and 1) <> 0);
end;
procedure BME280setTempCal(Cal: float);
begin
TempCal:= Cal;
end;
}
//-----------------------------------------------------------
procedure BME280readTempDruckFeucht;
begin
Case CASE_BME280readTDF of // BME280 initialisieren.
0 : If IsSysTimerZero(TmIntervall) Then
BME280_ADDR:= BME280_I2C_Adress;
Id:= BME280read8(BME280_REGISTER_CHIPID);
If Id = $60 Then
// BME280write8(BME280_REGISTER_SOFTRESET, $B6);
BME280_ReadSensorCoefficients();
mdelay(10);
// making sure sensor is in sleep mode before setting configuration
// as it otherwise may be ignored
// BME280write8(BME280_REGISTER_CONTROL, MODE_SLEEP);
// Set Humidity oversampling to 16x
BME280write8(BME280_REGISTER_CONTROLHUMID, $03); // Set before CONTROL (DS 5.4.3)
BME280write8(BME280_REGISTER_CONTROL, $3F);
BME_280:= ja;
CASE_BME280readTDF:= 10;
Else
BME_280:= nein;
CASE_BME280readTDF:= 100; // Fehler, kein Sensor vorhanden.
Endif;
Endif;
|
10 : // BME280readTemperature;
If IsSysTimerZero(TmIntervall) Then // BME280readTemperature;
adc_T:= longint(BME280read24(BME280_REGISTER_TEMPDATA) shr 4); // lowest 4 bits get dropped
CASE_BME280readTDF:= 11;
var1:= longint((adc_T shr 3) - (longint(cal_data.dig_T1 shl 1)));
var1:= (var1 * (longint(cal_data.dig_T2))) shr 11;
var2:= longint(((adc_T shr 4) - (longint(cal_data.dig_T1))));
var2:= (((var2 * var2) shr 12) * (longint(cal_data.dig_T3))) shr 14;
t_fine:= var1 + var2;
Temperature:= float((((t_fine * 5) + 128) shr 8));
Temperature:= Temperature / 100;
Temperature:= (Temperature + TempCal);
CASE_BME280readTDF:= 20;
EndIf;
|
20 : // BME280readPressure;
adc_P:= longint(BME280read24(BME280_REGISTER_PRESSUREDATA) shr 4); // lowest 4 bits get dropped
var3:= int64(t_fine) - 128000;
var4:= var3 * var3 * int64(cal_data.dig_P6);
var4:= var4 + ((var3 * int64(cal_data.dig_P5)) shl 17);
var4:= var4 + (int64(cal_data.dig_P4) shl 35);
var3:= ((var3 * var3 * int64(cal_data.dig_P3)) shr 8) +
((var3 * int64(cal_data.dig_P2)) shl 12);
var3:= (((int64(1) shl 47) + var3) * int64(cal_data.dig_P1)) shr 33;
If (var3 = 0) Then // avoid exception caused by division by zero
Pressure:= 0.0;
Return;
EndIf;
p:= 1048576 - int64(adc_P);
p:= (((p shl 31) - var4) * 3125) div var3;
var3:= (int64(cal_data.dig_P9) * (p shr 13) * (p shr 13)) shr 25;
var4:= int64(cal_data.dig_P8) * (p shr 19);
p:= ((p + var3 + var4) shr 8) + (int64(cal_data.dig_P7) shl 4);
// Pressure:= float(p) div 256; // Error: not implemented
xStrg:= Long64ToStr(p: 6: 2: '0'); // better with Fix64
Pressure:= StrToFloat(xStrg) / 256;
CASE_BME280readTDF:= 30;
|
30 : // BME280readHumidity;
adc_H:= longint(BME280read16(BME280_REGISTER_HUMIDDATA));
v_x1_u32r:= (t_fine - (76800));
v_x1_u32r:= (((((adc_H shl 14) - ((longint(cal_data.dig_H4)) shl 20) -
((longint(cal_data.dig_H5)) * v_x1_u32r)) + (16384)) shr 15) *
(((((((v_x1_u32r * (longint(cal_data.dig_H6))) shr 10) *
(((v_x1_u32r * (longint(cal_data.dig_H3))) shr 11) + (32768))) shr 10) +
(2097152)) * (longint(cal_data.dig_H2)) + 8192) shr 14));
v_x1_u32r:= (v_x1_u32r - (((((v_x1_u32r shr 15) * (v_x1_u32r shr 15)) shr 7) *
(longint(cal_data.dig_H1))) shr 4));
If (v_x1_u32r < 0) Then
v_x1_u32r:= 0;
EndIf;
If v_x1_u32r > 419430400 Then
v_x1_u32r:= 419430400;
EndIf;
h:= float(v_x1_u32r shr 12);
Humidity:= (h / 1024.0);
CASE_BME280readTDF:= 100;
|
100 : If BME_280 = ja Then
Writeln(Serout, '');
Writeln(Serout, ' BME 280 Test....');
Writeln(Serout, ' Sensor found at Addr: 0x' + ByteToHex(BME280_ADDR));
// BME280setTempCal(-1);
Writeln(Serout, ' Temp: ' + FloatToStr(Temperature: 3: 2: '0') + ' C');
Writeln(Serout, ' Humity: ' + FloatToStr(Humidity: 3: 2: '0') + ' %');
Writeln(Serout, ' Pressure: ' + FloatToStr(Pressure: 4: 2: '0') + ' hPa');
Else
Writeln(Serout, 'Could not find a valid BME280 sensor, check wiring, address, sensor ID!');
CASE_BME280readTDF:= 0;
EndIf;
SetSysTimer(TmIntervall, 1000);
CASE_BME280readTDF:= 10;
|
EndCase;
end BME280readTempDruckFeucht;
{--------------------------------------------------------------}
{ Main Program }
{$IDATA}
begin
EnableInts;
loop
BME280readTempDruckFeucht;
endloop;
end BME280_Test_3.