This forum uses cookies
This forum makes use of cookies to store your login information if you are registered, and your last visit if you are not. Cookies are small text documents stored on your computer; the cookies set by this forum can only be used on this website and pose no security risk. Cookies on this forum also track the specific topics you have read and when you last read them. Please confirm whether you accept or reject these cookies being set.

A cookie will be stored in your browser regardless of choice to prevent you being asked this question again. You will be able to change your cookie settings at any time using the link in the footer.

Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
weathersensors with bmp180
#1
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];
Reply


Forum Jump:


Users browsing this thread: 1 Guest(s)