Bascom ---> Pascal

  • 1
  • 2
  • 3
  • 5
  • 6
  • Page 6 of 6
miparo
Administrator
Avatar
Gender:
Location: Germany
Age: 59
Posts: 956
Registered: 09 / 2007
Subject:

Re: Bascom ---> Pascal

 · 
Posted: 19.08.2022 - 00:03  ·  #41
Hi Matthias,
schwierige Geburt, das Teil :(

BME 280 Test....
Sensor found at Addr: 0x76
Temp: 26.47 C
Humity: 54.42 %
Pressure: 1014.51 hPa

Test Prog anbei :)

miparo
Mathias
Benutzer
Avatar
Gender: n/a
Location: Weingarten - Baden
Posts: 307
Registered: 07 / 2003
Subject:

Re: Bascom ---> Pascal

 · 
Posted: 21.08.2022 - 21:24  ·  #42
Läuft prima!
Danke
Habe es mir angepasst.

Gruß
Mathias

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.

miparo
Administrator
Avatar
Gender:
Location: Germany
Age: 59
Posts: 956
Registered: 09 / 2007
Subject:

Re: Bascom ---> Pascal

 · 
Posted: 21.08.2022 - 22:01  ·  #43
Hi Matthias,
sehr schön.
Es sollte von mir auch nur eine Vorlage sein, damit du dich nicht mit Basic herumärgern musst :)
Es ist auch ein gutes Beispiel, das man mit den bestehenden I2C Treiber alle ICs mit bedienen kann.

Die Vars global schützen den Frame beim In64 . :zustimm:
Im Loop unten fehlt ein delay ? Der Sensor liefert nur jede Sekunde neue Werte.

miparo
  • 1
  • 2
  • 3
  • 5
  • 6
  • Page 6 of 6
Selected quotes for multi-quoting:   0

Registered users in this topic

Currently no registered users in this section

The statistic shows who was online during the last 5 minutes. Updated every 90 seconds.
MySQL Queries: 15 · Cache Hits: 14   64   78 · Page-Gen-Time: 0.019375s · Memory Usage: 2 MB · GZIP: on · Viewport: SMXL-HiDPI