OpenMarine

Full Version: weathersensors with bmp180
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
hi!

thank you for this great development, sean.
i built weathersensors but i haven't got a bmp280 but instead a bmp180 - so i modified the code to work with it. i don't know if its for common interest, so i attach the diff right here if anybody needs it. would it make sense to extract the bmp280-code from weathersensors.ino  into a seperate .c/.h file? so it would be  possible to change the sensor with only changing the includes (via #define)...

kind regards....martin.


Code:
--- weathersensors.ino.orig    2021-02-10 22:28:43.805432769 +0000
+++ weathersensors.ino    2021-02-09 20:25:08.209423143 +0000
@@ -6,7 +6,7 @@
 * version 3 of the License, or (at your option) any later version.
 */

-/* this program interfaces with the bmp280 pressure sensor and outputs
+/* this program interfaces with the bmp180 pressure sensor and outputs
   calibrated nmea0183 data over serial at 38400 baud

   anemometer wires
@@ -56,10 +56,10 @@

int16_t cross_count = 1000; // calibrate range during first 1000 crossings of 0

-uint8_t have_bmp280 = 0;
-uint8_t bmX280_tries = 10;  // try 10 times to configure
-uint16_t dig_T1, dig_P1;
-int16_t dig_T2, dig_T3, dig_P2, dig_P3, dig_P4, dig_P5, dig_P6, dig_P7, dig_P8, dig_P9;
+uint8_t have_bmp180 = 0;
+uint8_t bmp180_tries = 10;  // try 10 times to configure
+uint16_t dig_AC4, dig_AC5, dig_AC6;
+int16_t dig_AC1, dig_AC2, dig_AC3, dig_B1, dig_B2, dig_MB, dig_MC, dig_MD;

int16_t cal_wind_min_reading, cal_wind_max_reading;
uint32_t eeprom_write_timeout = 0;
@@ -93,12 +93,12 @@
const uint32_t baro_times[3] = {60000L*5/history_len, 60000L*60/history_len, 60000L*60*24/history_len};


-void bmX280_setup()
+void bmp180_setup()
{
-  Serial.println(F("bmX280 setup"));
+  Serial.println(F("bmp180 setup"));

  // NOTE:  local version of twi does not enable pullup as
-  // bmX_280 device is 3.3v and arduino runs at 5v
+  // bmp_180 device is 3.3v and arduino runs at 5v

  twi_init();

@@ -108,18 +108,18 @@
  pinMode(SCL, INPUT);
  delay(1);

-  have_bmp280 = 0;
-  bmX280_tries--;
+  have_bmp180 = 0;
+  bmp180_tries--;

  uint8_t d[24];
  d[0] = 0xd0;

-  if(twi_writeTo(0x76, d, 1, 1, 1) == 0 &&
-     twi_readFrom(0x76, d, 1, 1) == 1 &&
-     d[0] == 0x58)
-      have_bmp280 = 1;
+  if(twi_writeTo(0x77, d, 1, 1, 1) == 0 &&
+     twi_readFrom(0x77, d, 1, 1) == 1 &&
+     d[0] == 0x55)
+      have_bmp180 = 1;
  else {
-      Serial.print(F("bmp280 not found: "));
+      Serial.print(F("bmp180 not found: "));
      Serial.println(d[0]);
      // attempt reset command
      //d[0] = 0xe0;
@@ -129,51 +129,44 @@
      return;
  }

-  d[0] = 0x88;
-  if(twi_writeTo(0x76, d, 1, 1, 1) != 0)
-      have_bmp280 = 0;
-
-  uint8_t c = twi_readFrom(0x76, d, 24, 1);
-  if(c != 24) {
-      Serial.println(F("bmp280 failed to read calibration"));
-      have_bmp280 = 0;
+  d[0] = 0xAA;
+  if(twi_writeTo(0x77, d, 1, 1, 1) != 0)
+      have_bmp180 = 0;
+
+  uint8_t c = twi_readFrom(0x77, d, 22, 1);
+  if(c != 22) {
+      Serial.println(F("bmp180 failed to read calibration"));
+      have_bmp180 = 0;
  }
     
-  dig_T1 = d[0] | d[1] << 8;
-  dig_T2 = d[2] | d[3] << 8;
-  dig_T3 = d[4] | d[5] << 8;
-  dig_P1 = d[6] | d[7] << 8;
-  dig_P2 = d[8] | d[9] << 8;
-  dig_P3 = d[10] | d[11] << 8;
-  dig_P4 = d[12] | d[13] << 8;
-  dig_P5 = d[14] | d[15] << 8;
-  dig_P6 = d[16] | d[17] << 8;
-  dig_P7 = d[18] | d[19] << 8;
-  dig_P8 = d[20] | d[21] << 8;
-  dig_P9 = d[22] | d[23] << 8;
+  dig_AC1 = d[0] << 8 | d[1];
+  dig_AC2 = d[2] << 8 | d[3];
+  dig_AC3 = d[4] << 8 | d[5];
+  dig_AC4 = d[6] << 8 | d[7];
+  dig_AC5 = d[8] << 8 | d[9];
+  dig_AC6 = d[10] << 8 | d[11];
+  dig_B1 = d[12] << 8 | d[13];
+  dig_B2 = d[14] << 8 | d[15];
+  dig_MB = d[16] << 8 | d[17];
+  dig_MC = d[18] << 8 | d[19];
+  dig_MD = d[20] << 8 | d[21];

 
#if 0
-  Serial.println("bmp280 pressure compensation:");
-  Serial.println(dig_T1);
-  Serial.println(dig_T2);
-  Serial.println(dig_T3);
-  Serial.println(dig_P1);
-  Serial.println(dig_P2);
-  Serial.println(dig_P3);
-  Serial.println(dig_P4);
-  Serial.println(dig_P5);
-  Serial.println(dig_P6);
-  Serial.println(dig_P7);
-  Serial.println(dig_P8);
-  Serial.println(dig_P9);
+  Serial.println("bmp180 pressure compensation:");
+  Serial.println(dig_AC1);
+  Serial.println(dig_AC2);
+  Serial.println(dig_AC3);
+  Serial.println(dig_AC4);
+  Serial.println(dig_AC5);
+  Serial.println(dig_AC6);
+  Serial.println(dig_B1);
+  Serial.println(dig_B2);
+  Serial.println(dig_MB);
+  Serial.println(dig_MC);
+  Serial.println(dig_MD);
#endif  

-  // b00011111  // configure
-  d[0] = 0xf4;
-  d[1] = 0xff;
-  if(twi_writeTo(0x76, d, 2, 1, 1) != 0)
-      have_bmp280 = 0;
}

volatile unsigned int rotation_count;
@@ -321,7 +314,7 @@
        )
        Serial.print(F("Warning, fuses set wrong, flash may become corrupted"));

-    bmX280_setup();
+    bmp180_setup();

    attachInterrupt(0, isr_anemometer_count, CHANGE);
    pinMode(analogInPin, INPUT);
@@ -390,36 +383,48 @@
}

int32_t t_fine;
-int32_t bmp280_compensate_T_int32(int32_t adc_T)
+int32_t bmp180_compensate_T_int32(int32_t adc_T)
{
    int32_t var1, var2, T;
-    var1 = ((((adc_T>>3) - ((int32_t)dig_T1<<1))) * ((int32_t)dig_T2)) >> 11;
-    var2 = (((((adc_T>>4) - ((int32_t)dig_T1)) * ((adc_T>>4) - ((int32_t)dig_T1))) >> 12) * ((int32_t)dig_T3)) >> 14;
+    var1 = (adc_T - (int32_t)dig_AC6) * ((int32_t)dig_AC5) >> 15;
+    var2 = ((int32_t)dig_MC << 11) / (var1 + (int32_t)dig_MD);
+    T = (((var1 + var2) * 10 + 8) >> 4) ;
    t_fine = var1 + var2;
-    T = (t_fine * 5 + 128) >> 8;
    return T;
}

// Returns pressure in Pa as unsigned 32 bit integer in Q24.8 format (24 integer bits and 8 fractional bits).
// Output value of “24674867” represents 24674867/256 = 96386.2 Pa = 963.862 hPa
-uint32_t bmp280_compensate_P_int64(int32_t adc_P)
+uint32_t bmp180_compensate_P_int64(int32_t adc_P)
{
-    uint64_t var1, var2, p;
-    var1 = ((int64_t)t_fine) - 128000;
-    var2 = var1 * var1 * (uint64_t)dig_P6;
-    var2 = var2 + ((var1*(uint64_t)dig_P5)<<17);
-    var2 = var2 + (((uint64_t)dig_P4)<<35);
-    var1 = ((var1 * var1 * (uint64_t)dig_P3)>>8) + ((var1 * (uint64_t)dig_P2)<<12);
-    var1 = (((((int64_t)1)<<47)+var1))*((uint64_t)dig_P1)>>33;
-    if (var1 == 0)
+    int32_t b3, b6, x1, x2, x3, p;
+    uint32_t b4, b7;
+
+    b6 = t_fine - 4000;
+    x1 = ((int32_t)dig_B2 * (b6 * b6) >> 12 ) >> 11 ;
+    x2 = ((int32_t)dig_AC2 * b6) >> 11;
+    x3 = x1 + x2;
+    b3 = ((((int32_t)dig_AC1 * 4 + x3) << 0) + 2) / 4;
+    x1 = ((int32_t)dig_AC3 * b6) >> 13;
+    x2 = ((int32_t)dig_B1 * ((b6 * b6) >> 12)) >> 16;
+    x3 = ((x1 + x2) + 2) >> 2;
+    b4 = ((uint32_t)dig_AC4 * (uint32_t)(x3 + 32768)) >> 15;
+    b7 = ((uint32_t)adc_P - b3) * (uint32_t)(50000UL >> 0);
+    if (b4 == 0)
    {
        return 0; // avoid exception caused by division by zero
    }
-    p = 1048576-adc_P;
-    p = (((p<<31)-var2)*3125)/var1;
-    var1 = (((uint64_t)dig_P9) * (p>>13) * (p>>13)) >> 25;
-    var2 = (((uint64_t)dig_P8) * p) >> 19;
-    p = ((p + var1 + var2) >> 8) + (((uint64_t)dig_P7)<<4);
+    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;
+    p = p + ((x1 + x2 + (int32_t)3791) >> 4);
+    p = p * 256;
+
    return (uint32_t)p;
}

@@ -644,7 +649,7 @@

uint32_t pressure, temperature;
int32_t pressure_comp, temperature_comp;
-int bmp280_count;
+int bmp180_count;

static uint32_t baro_val, baro_count;
void put_baro_history(uint8_t index, int32_t val)
@@ -684,49 +689,73 @@

void read_pressure_temperature()
{
-    if(!bmX280_tries)
+    if(!bmp180_tries)
        return;

    uint8_t buf[6] = {0};
-    buf[0] = 0xf7;
-    uint8_t r = twi_writeTo(0x76, buf, 1, 1, 1);
-    if(r && have_bmp280) {
-        Serial.print(F("bmp280 twierror "));
-        Serial.println(r);
-    }
+    uint8_t r, c;
+    int32_t p, t;

-    uint8_t c = twi_readFrom(0x76, buf, 6, 1);
-    if(c != 6 && have_bmp280)
-        Serial.println(F("bmp280 failed to read 6 bytes from bmp280"));

-    int32_t p, t;
-    
-    p = (int32_t)buf[0] << 16 | (int32_t)buf[1] << 8 | (int32_t)buf[2];
-    t = (int32_t)buf[3] << 16 | (int32_t)buf[4] << 8 | (int32_t)buf[5];
-    
+    // get raw temperature
+    buf[0] = 0xf4;
+    buf[1] = 0x2E; // control instruction measure temperature
+    r = twi_writeTo(0x77, buf, 2, 1, 1);
+    if(r && have_bmp180) {
+        Serial.println(F("bmp180 twierror "));
+        have_bmp180 = 0;
+    }
+    delay(5);
+    buf[0] = 0xf6; // data register
+    r = twi_writeTo(0x77, buf, 1, 1, 1);
+    c = twi_readFrom(0x77, buf, 2, 1);
+    if(c != 2 && have_bmp180) {
+        Serial.println(F("bmp180 failed to read 2 bytes for temperature"));
+        have_bmp180 = 0;
+    }
+    t = (int32_t)buf[0] << 8 | (int32_t)buf[1];
+
+    // get raw pressure
+    buf[0] = 0xf4;
+    buf[1] = 0x34;  // control instruction measure pressure
+    r = twi_writeTo(0x77, buf, 2, 1, 1);
+    if(r && have_bmp180) {
+        Serial.println(F("bmp180 twierror "));
+        
+    }
+    delay(5);
+    buf[0] = 0xf6; // data register
+    r = twi_writeTo(0x77, buf, 1, 1, 1);
+    c = twi_readFrom(0x77, buf, 3, 1);
+    if(c != 3 && have_bmp180) {
+        Serial.println(F("bmp180 failed to read 3 bytes for pressure"));
+        have_bmp180 = 0;
+    }
+    p = ((int32_t)buf[0] << 16 | (int32_t)buf[1] << 8 | (int32_t)buf[2]) >> 8;
+
    if(t == 0 || p == 0)
-        have_bmp280 = 0;
+        have_bmp180 = 0;

-    pressure += p >> 2;
-    temperature += t >> 2;
-    bmp280_count++;
-
-    if(!have_bmp280) {
-        if(bmp280_count == 256) {
-            bmp280_count = 0;
+    pressure += p << 2;
+    temperature += t << 2;
+    bmp180_count++;
+
+    if(!have_bmp180) {
+        if(bmp180_count == 256) {
+            bmp180_count = 0;
            /* only re-run setup when count elapse */
-            bmX280_setup();
+            bmp180_setup();
        }
        return;
    }

-    if(bmp280_count == 1024) {
-        bmp280_count = 0;
+    if(bmp180_count == 1024) {
+        bmp180_count = 0;
        pressure >>= 12;
        temperature >>= 12;
   
-        temperature_comp = bmp280_compensate_T_int32(temperature);
-        pressure_comp = bmp280_compensate_P_int64(pressure) >> 8;
+        temperature_comp = bmp180_compensate_T_int32(temperature);
+        pressure_comp = bmp180_compensate_P_int64(pressure) >> 8;
        pressure = temperature = 0;
 
        char buf[128];