From a0ba7ad4a3489c64dab836cdf6349a09be32ad92 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Farkas=20Szil=C3=A1rd?= Date: Sat, 18 Apr 2020 20:05:51 +0200 Subject: [PATCH] MS5611 pressure sensor code, which is more or less the same as MS5607 on the calculation parameters differ. I2C_Write function signature was wrong, and header define was missing in the ms5607.h --- main/config.h | 1 + main/disp_lcd.cpp | 4 ++ main/disp_oled.cpp | 7 +++ main/main.cpp | 2 +- main/ms5607.h | 11 +++-- main/ms5611.h | 114 +++++++++++++++++++++++++++++++++++++++++++++ main/sens.cpp | 26 ++++++++--- main/sens.h | 7 ++- 8 files changed, 161 insertions(+), 11 deletions(-) create mode 100644 main/ms5611.h diff --git a/main/config.h b/main/config.h index 6d60999..590a51b 100644 --- a/main/config.h +++ b/main/config.h @@ -46,6 +46,7 @@ // #define WITH_BMP280 // BMP280 pressure sensor #define WITH_BME280 // BMP280 with humidity (but still works with BMP280) // #define WITH_MS5607 // MS5607 pressure sensor +// #define WITH_MS5611 // MS5611 pressure sensor #define WITH_PFLAA // PFLAU and PFLAA for compatibility with XCsoar and LK8000 // #define WITH_POGNT diff --git a/main/disp_lcd.cpp b/main/disp_lcd.cpp index eb3a7d3..a039e79 100644 --- a/main/disp_lcd.cpp +++ b/main/disp_lcd.cpp @@ -360,6 +360,10 @@ static void LCD_UpdateSys(bool Redraw=0) #ifdef WITH_MS5607 Len+=Format_String(Line+Len, "MS5607 0x"); Len+=Format_Hex(Line+Len, Baro.ADDR); +#endif +#ifdef WITH_MS5611 + Len+=Format_String(Line+Len, "MS5611 0x"); + Len+=Format_Hex(Line+Len, Baro.ADDR); #endif Line[Len]=0; LCD_DrawString(Line, 4, PosY, RGB565_BLACK, RGB565_WHITE); diff --git a/main/disp_oled.cpp b/main/disp_oled.cpp index 10d4b28..95f6f32 100644 --- a/main/disp_oled.cpp +++ b/main/disp_oled.cpp @@ -402,6 +402,9 @@ void OLED_DrawBaro(u8g2_t *OLED, GPS_Position *GPS) #endif #ifdef WITH_MS5607 Len+=Format_String(Line+Len, "MS5607 "); +#endif +#ifdef WITH_MS5611 + Len+=Format_String(Line+Len, "MS5611 "); #endif if(GPS && GPS->hasBaro) { Len+=Format_UnsDec(Line+Len, GPS->Pressure/4, 5, 2); @@ -583,6 +586,10 @@ void OLED_DrawSystem(u8g2_t *OLED) #ifdef WITH_MS5607 Len+=Format_String(Line+Len, "MS5607 0x"); Len+=Format_Hex(Line+Len, Baro.ADDR); +#endif +#ifdef WITH_MS5611 + Len+=Format_String(Line+Len, "MS5611 0x"); + Len+=Format_Hex(Line+Len, Baro.ADDR); #endif Line[Len]=0; u8g2_DrawStr(OLED, 0, 48, Line); diff --git a/main/main.cpp b/main/main.cpp index 688d5db..9f29031 100644 --- a/main/main.cpp +++ b/main/main.cpp @@ -67,7 +67,7 @@ void app_main(void) #endif xTaskCreate(vTaskPROC, "PROC", 2048, 0, tskIDLE_PRIORITY+3, 0); xTaskCreate(vTaskGPS, "GPS", 2048, 0, tskIDLE_PRIORITY+4, 0); -#if defined(WITH_BMP180) || defined(WITH_BMP280) || defined(WITH_BME280) || defined(WITH_MS5607) +#if defined(WITH_BMP180) || defined(WITH_BMP280) || defined(WITH_BME280) || defined(WITH_MS5607) || defined(WITH_MS5611) xTaskCreate(vTaskSENS, "SENS", 2048, 0, tskIDLE_PRIORITY+4, 0); #endif #ifdef WITH_KNOB diff --git a/main/ms5607.h b/main/ms5607.h index aedcbe0..10e6d9d 100644 --- a/main/ms5607.h +++ b/main/ms5607.h @@ -1,3 +1,6 @@ +#ifndef __MS5607_H__ +#define __MS5607_H__ + #include #include #include @@ -49,7 +52,7 @@ class MS5607 C7 = 0; } uint8_t Reset(uint8_t Addr) // RESET: takes 2.8ms - { Error=I2C_Write(Bus, Addr, CMD_RESET, 0, 0); + { Error=I2C_Write(Bus, Addr, CMD_RESET, 0); return Error; } uint8_t CheckID(void) @@ -69,7 +72,7 @@ class MS5607 uint8_t ReadRawPress(void) // convert and read raw pressure { RawPress=0; - Error=I2C_Write(Bus, ADDR, CMD_ADC_CONV+CMD_ADC_D1+CMD_ADC_4096, 0, 0); if(Error) return Error; + Error=I2C_Write(Bus, ADDR, CMD_ADC_CONV+CMD_ADC_D1+CMD_ADC_4096, 0); if(Error) return Error; vTaskDelay(12); Error=I2C_Read(Bus, ADDR, CMD_ADC_READ, (uint8_t *)(&RawPress), 3); if(Error) return Error; RawPress = ((RawPress<<16)&0xFF0000) | (RawPress&0x00FF00) | ((RawPress>>16)&0x0000FF); // swap bytes @@ -77,7 +80,7 @@ class MS5607 uint8_t ReadRawTemp(void) // convert and read raw temperature { RawTemp=0; - Error=I2C_Write(Bus, ADDR, CMD_ADC_CONV+CMD_ADC_D2+CMD_ADC_4096, 0, 0); if(Error) return Error; + Error=I2C_Write(Bus, ADDR, CMD_ADC_CONV+CMD_ADC_D2+CMD_ADC_4096, 0); if(Error) return Error; vTaskDelay(12); Error=I2C_Read(Bus, ADDR, CMD_ADC_READ, (uint8_t *)(&RawTemp), 3); if(Error) return Error; RawTemp = ((RawTemp<<16)&0xFF0000) | (RawTemp&0x00FF00) | ((RawTemp>>16)&0x0000FF); // swap bytes @@ -107,3 +110,5 @@ class MS5607 } ; + +#endif // __MS5607_H__ diff --git a/main/ms5611.h b/main/ms5611.h new file mode 100644 index 0000000..ad59c8e --- /dev/null +++ b/main/ms5611.h @@ -0,0 +1,114 @@ +#ifndef __MS5611_H__ +#define __MS5611_H__ + +#include +#include +#include + +#include "hal.h" + +class MS5611 +{ private: + static const uint8_t ADDR0 = 0x77; // possible I2C addresses + static const uint8_t ADDR1 = 0x76; + + static const uint8_t CMD_RESET = 0x1E; // ADC reset command + static const uint8_t CMD_ADC_READ = 0x00; // ADC read command + static const uint8_t CMD_ADC_CONV = 0x40; // ADC conversion command + static const uint8_t CMD_ADC_D1 = 0x00; // ADC D1 conversion + static const uint8_t CMD_ADC_D2 = 0x10; // ADC D2 conversion + static const uint8_t CMD_ADC_256 = 0x00; // ADC OSR=256 + static const uint8_t CMD_ADC_512 = 0x02; // ADC OSR=512 + static const uint8_t CMD_ADC_1024 = 0x04; // ADC OSR=1024 + static const uint8_t CMD_ADC_2048 = 0x06; // ADC OSR=2048 + static const uint8_t CMD_ADC_4096 = 0x08; // ADC OSR=4096 + static const uint8_t CMD_PROM_READ = 0xA0; // Prom read command + public: + uint8_t Bus; // which I2C bus + uint8_t ADDR; // detected I2C address + private: + union + { int16_t Calib[8]; + struct + { uint16_t C0, C1, C2, C3, C4, C5, C6, C7; }; // 6 calibration values from EEPROM + } ; + public: + uint8_t Error; // error on the I2C bus (0=no error) + int32_t RawTemp; // raw temperature - to be processed + int32_t RawPress; // raw pressure - to be processed + int32_t Temperature; // [0.1 degC] temperature after correction + uint32_t Pressure; // [0.25Pa ] pressure after correction + + public: + + void DefaultCalib(void) // set default calibration constants + { C0 = 0; + C1 = 46372; + C2 = 43981; + C3 = 29059; + C4 = 27842; + C5 = 31553; + C6 = 28165; + C7 = 0; } + + uint8_t Reset(uint8_t Addr) // RESET: takes 2.8ms + { Error=I2C_Write(Bus, Addr, CMD_RESET, 0); + return Error; } + + uint8_t CheckID(void) + { ADDR=0; + Error=Reset(ADDR0); if(!Error) { vTaskDelay(3); ADDR=ADDR0; return 0; } + Error=Reset(ADDR1); if(!Error) { vTaskDelay(3); ADDR=ADDR1; return 0; } + return 1; } + + uint16_t SwapBytes(uint16_t Word) + { return (Word<<8) | (Word>>8); } + + uint8_t ReadCalib(void) // read the calibration constants from the PROM + { for(uint8_t Idx=0; Idx<8; Idx++) + { Error=I2C_Read(Bus, ADDR, CMD_PROM_READ + 2*Idx, (uint8_t *)(Calib+Idx), 2); if(Error) break; + Calib[Idx]=SwapBytes(Calib[Idx]); } + return 0; } + + uint8_t ReadRawPress(void) // convert and read raw pressure + { RawPress=0; + Error=I2C_Write(Bus, ADDR, CMD_ADC_CONV+CMD_ADC_D1+CMD_ADC_4096, 0); if(Error) return Error; + vTaskDelay(12); + Error=I2C_Read(Bus, ADDR, CMD_ADC_READ, (uint8_t *)(&RawPress), 3); if(Error) return Error; + RawPress = ((RawPress<<16)&0xFF0000) | (RawPress&0x00FF00) | ((RawPress>>16)&0x0000FF); // swap bytes + return 0; } + + uint8_t ReadRawTemp(void) // convert and read raw temperature + { RawTemp=0; + Error=I2C_Write(Bus, ADDR, CMD_ADC_CONV+CMD_ADC_D2+CMD_ADC_4096, 0); if(Error) return Error; + vTaskDelay(12); + Error=I2C_Read(Bus, ADDR, CMD_ADC_READ, (uint8_t *)(&RawTemp), 3); if(Error) return Error; + RawTemp = ((RawTemp<<16)&0xFF0000) | (RawTemp&0x00FF00) | ((RawTemp>>16)&0x0000FF); // swap bytes + return 0; } + + uint8_t Acquire(void) // convert and read raw pressure then temperature + { if(ReadRawPress()) return Error; + return ReadRawTemp(); } + + void Calculate(void) // process temperature and pressure with the calibration constants + { int32_t dT = RawTemp - ((int32_t)C5<<8); + int32_t TEMP = 2000 + (((int64_t)dT*C6)>>23); // [0.01degC] + int64_t OFF = ((uint64_t)C2<<16) + (((int64_t)dT*C4)>>7); + int64_t SENS = ((uint32_t)C1<<15) + (((int64_t)dT*C3)>>8); + if(TEMP<2000) + { int32_t dT2 = ((int64_t)dT*dT)>>31; + int32_t OFF2 = 5 * ((TEMP-2000)*(TEMP-2000)) / 2; + int32_t SENS2 = 5 * ((TEMP-2000)*(TEMP-2000)) / 4; + if(TEMP<(-1500)) + { OFF2 += 7 * ((TEMP+1500)*(TEMP+1500)); + SENS2 += 11 * ((TEMP+1500)*(TEMP+1500)) / 2; } + TEMP -= dT2; + OFF -= OFF2; + SENS -= SENS2; } + Temperature = TEMP; // [0.1degC] + Pressure = (((SENS*RawPress)>>21) - OFF)>>13; } // [0.25Pa] + +} ; + + +#endif // __MS5611_H__ diff --git a/main/sens.cpp b/main/sens.cpp index f2fe334..762fa3d 100644 --- a/main/sens.cpp +++ b/main/sens.cpp @@ -12,7 +12,7 @@ // #define DEBUG_PRINT -#if defined(WITH_BMP180) || defined(WITH_BMP280) || defined(WITH_MS5607) || defined(WITH_BME280) +#if defined(WITH_BMP180) || defined(WITH_BMP280) || defined(WITH_MS5607) || defined(WITH_BME280) || defined(WITH_MS5611) #ifdef WITH_BMP180 #include "bmp180.h" @@ -30,6 +30,10 @@ #include "ms5607.h" #endif +#ifdef WITH_MS5611 +#include "ms5611.h" +#endif + #include "atmosphere.h" #include "slope.h" #include "lowpass2.h" @@ -73,7 +77,11 @@ void VarioSound(int32_t ClimbRate) #endif #ifdef WITH_MS5607 - MS5607 Baro; // BMP280 barometer sensor + MS5607 Baro; // MS5607 barometer sensor +#endif + +#ifdef WITH_MS5611 + MS5611 Baro; // MS5611 barometer sensor #endif static uint32_t AverPress; // [ Pa] summed Pressure over several readouts @@ -98,7 +106,7 @@ static uint8_t InitBaro() if(Err==0) Err=Baro.AcquireRawTemperature(); if(Err==0) { Baro.CalcTemperature(); AverPress=0; AverCount=0; } #endif -#if defined(WITH_BMP280) || defined(WITH_MS5607) || defined(WITH_BME280) +#if defined(WITH_BMP280) || defined(WITH_MS5607) || defined(WITH_BME280) || defined(WITH_MS5611) if(Err==0) Err=Baro.Acquire(); if(Err==0) { Baro.Calculate(); } #endif @@ -149,7 +157,7 @@ static void ProcBaro(void) xSemaphoreGive(CONS_Mutex); #endif #endif -#if defined(WITH_BMP280) || defined(WITH_MS5607) || defined(WITH_BME280) +#if defined(WITH_BMP280) || defined(WITH_MS5607) || defined(WITH_BME280) || defined(WITH_MS5611) // xSemaphoreTake(I2C_Mutex, portMAX_DELAY); uint8_t Err=Baro.Acquire(); // xSemaphoreGive(I2C_Mutex); @@ -292,7 +300,7 @@ void vTaskSENS(void* pvParameters) // VarioSound(0); // #endif -#if defined(WITH_BMP180) || defined(WITH_BMP280) || defined(WITH_MS5607) || defined(WITH_BME280) +#if defined(WITH_BMP180) || defined(WITH_BMP280) || defined(WITH_MS5607) || defined(WITH_BME280) || defined(WITH_MS5611) BaroPipe.Clear (4*90000); BaroNoise.Set(12*16); // guess the pressure noise level @@ -331,12 +339,18 @@ void vTaskSENS(void* pvParameters) else Format_String(CONS_UART_Write, " ?!"); #endif +#ifdef WITH_MS5611 + Format_String(CONS_UART_Write, " MS5611: "); + if(Detected) { Format_String(CONS_UART_Write, " @"); Format_Hex(CONS_UART_Write, Detected); } + else Format_String(CONS_UART_Write, " ?!"); +#endif + Format_String(CONS_UART_Write, "\n"); xSemaphoreGive(CONS_Mutex); while(1) { -#if defined(WITH_BMP180) || defined(WITH_BMP280) || defined(WITH_MS5607) || defined(WITH_BME280) +#if defined(WITH_BMP180) || defined(WITH_BMP280) || defined(WITH_MS5607) || defined(WITH_BME280) || defined(WITH_MS5611) if(PowerMode) ProcBaro(); else vTaskDelay(100); #else diff --git a/main/sens.h b/main/sens.h index 9da4840..d6f8c7f 100644 --- a/main/sens.h +++ b/main/sens.h @@ -18,7 +18,12 @@ extern BME280 Baro; // BMP280 barometer sensor with humi #ifdef WITH_MS5607 #include "ms5607.h" -extern MS5607 Baro; // BMP280 barometer sensor +extern MS5607 Baro; // MS5607 barometer sensor +#endif + +#ifdef WITH_MS5611 +#include "ms5611.h" +extern MS5611 Baro; // MS5611 barometer sensor #endif