From 2a0e0fa849b896e5d70172bb44e1fe0d1d063a7a Mon Sep 17 00:00:00 2001 From: Pawel Jalocha Date: Fri, 9 Mar 2018 13:11:21 +0000 Subject: [PATCH] Add more info-parameters, BME280 support, remove I2C mutex --- main/bme280.h | 113 ++++++++++++++++++++++++++++++++++++++++++++++ main/bmp280.h | 1 + main/gps.cpp | 6 ++- main/hal.cpp | 33 +++++++++----- main/hal.h | 14 ++++-- main/main.cpp | 8 ++-- main/nmea.cpp | 4 +- main/ogn.h | 4 +- main/parameters.h | 47 ++++++++++++------- main/proc.cpp | 58 ++++++++++++++---------- main/rf.cpp | 4 +- main/sens.cpp | 63 ++++++++++++++++++-------- sdkconfig | 7 +++ 13 files changed, 277 insertions(+), 85 deletions(-) create mode 100644 main/bme280.h diff --git a/main/bme280.h b/main/bme280.h new file mode 100644 index 0000000..69203dd --- /dev/null +++ b/main/bme280.h @@ -0,0 +1,113 @@ +#include +#include +#include + +#include "nmea.h" +#include "format.h" + +#include "bmp280.h" + +class BME280: public BMP280 +{ private: + static uint16_t SwapBytes(uint16_t Word) { return (Word>>8) | (Word<<8); } + + static const uint8_t ADDR0 = 0x76; // possible I2C addresses + static const uint8_t ADDR1 = 0x77; + + static const uint8_t REG_CALIB_A1 = 0xA1; // calibration register: + static const uint8_t REG_CALIB_HUM= 0xE1; // calibration register: + static const uint8_t REG_ID = 0xD0; // ID register: always reads 0x60 + static const uint8_t REG_CTRL_HUM = 0xF2; // control: _____HHH HHH=humidity oversampling + + static const uint8_t REG_HUM = 0xFD; // Humidity result: + static const uint8_t REG_HUM_MSB = 0xFD; // Humidity result: MSB + static const uint8_t REG_HUM_LSB = 0xFE; // Humidity result: LSB + uint8_t H1; + int16_t H2; + uint8_t H3; + int16_t H4; + int16_t H5; + int8_t H6; + + public: + uint16_t RawHum; // raw humidity - to be processed + int32_t Humidity; // [0.1 %] relative humidity after processing + + uint8_t CheckID(void) // check ID, to make sure the BME280 is connected and works correctly + { uint8_t ID; + ADDR=0; + Error=I2C_Read(Bus, ADDR0, REG_ID, ID); + if( (!Error) && (ID==0x60) ) { ADDR=ADDR0; return 0; } + Error=I2C_Read(Bus, ADDR1, REG_ID, ID); + if( (!Error) && (ID==0x60) ) { ADDR=ADDR1; return 0; } + return 1; } // 0 => no error and correct ID + + uint8_t ReadCalib(void) // read the calibration constants from the EEPROM + { Error=BMP280::ReadCalib(); if(Error) return Error; + Error=I2C_Read(Bus, ADDR, REG_CALIB_A1, (uint8_t *)(&H1), 1); if(Error) return Error; + uint8_t buf[7]; + Error=I2C_Read(Bus, ADDR, REG_CALIB_HUM, buf, 7); if(Error) return Error; + parse_humidity_calib_data(buf); + return 0; } + + void parse_humidity_calib_data(uint8_t *s) + { + int16_t lsb, msb; + + H2 = (int16_t)(((uint16_t)s[1] << 8) | (uint16_t)s[0]); + H3 = s[2]; + + msb = (int16_t)(int8_t)s[3] * 16; + lsb = (int16_t)(s[4] & 0x0F); + H4 = msb | lsb; + + msb = (int16_t)(int8_t)s[5] * 16; + lsb = (int16_t)(s[4] >> 4); + H5 = msb | lsb; + H6 = (int8_t)s[6]; + } + + uint8_t Trigger(void) // start measurement + { uint8_t Data=0x03; Error=I2C_Write(Bus, ADDR, REG_CTRL_HUM, Data); if(Error) return Error; // H.osp=3x + return BMP280::Trigger(); } + + uint8_t ReadRawHum(void) + { RawHum=0; + Error=I2C_Read(Bus, ADDR, REG_HUM, (uint8_t *)(&RawHum), 2); if(Error) return Error; + RawHum = SwapBytes(RawHum); + return 0; } + + uint8_t Acquire(void) + { Error=BMP280::Acquire(); if(Error) return Error; + return ReadRawHum(); } + + void Calculate(void) + { BMP280::Calculate(); + CalcHumidity(); } + + void CalcHumidity(void) // calculate the humidity from raw readout and calibration values + { + int32_t var1, var2, var3, var4, var5; + int32_t humidity_max = 100000; + + var1 = FineTemp - ((int32_t)76800); + var2 = (int32_t)(((uint32_t)RawHum & 0xFFFF) << 14); + var3 = (int32_t)(((int32_t)H4) << 20); + var4 = ((int32_t)H5) * var1; + var5 = (((var2 - var3) - var4) + (int32_t)16384) >> 15; + var2 = (var1 * ((int32_t)H6)) >> 10; + var3 = (var1 * ((int32_t)H3)) >> 11; + var4 = ((var2 * (var3 + (int32_t)32768)) >> 10) + (int32_t)2097152; + var2 = ((var4 * ((int32_t)H2)) + 8192) >> 14; + var3 = var5 * var2; + var4 = ((var3 >> 15) * (var3 >> 15)) >> 7; + var5 = var3 - ((var4 * ((int32_t)H1)) >> 4); + var5 = (var5 < 0 ? 0 : var5); + var5 = (var5 > 419430400 ? 419430400 : var5); + Humidity = (uint32_t)(var5 >> 12); + if (Humidity > humidity_max) Humidity = humidity_max; + Humidity /= 100; + } + +} ; + diff --git a/main/bmp280.h b/main/bmp280.h index 51fc925..8a6eddf 100644 --- a/main/bmp280.h +++ b/main/bmp280.h @@ -65,6 +65,7 @@ class BMP280 D = 0; } uint8_t CheckID(void) // check ID, to make sure the BMP280 is connected and works correctly + // if it finds a BME280 it will use it without the humidity part { uint8_t ID; ADDR=0; Error=I2C_Read(Bus, ADDR0, REG_ID, ID); diff --git a/main/gps.cpp b/main/gps.cpp index f4a422d..ca23daa 100644 --- a/main/gps.cpp +++ b/main/gps.cpp @@ -84,9 +84,9 @@ const uint8_t GPS_dynModel = 7; // for UBX GPS's: 6 = airborne with > int16_t GPS_AverageSpeed(void) // get average speed based on stored GPS positions { uint8_t Count=0; int16_t Speed=0; - for(uint8_t Idx=0; Idx<4; Idx++) // loop over GPS positions + for(uint8_t Idx=0; IdxhasGPS || !Pos->isValid() ) continue; // skip invalid positions + if( !Pos->hasGPS || !Pos->isValid() ) continue; // skip invalid positions Speed += Pos->Speed +abs(Pos->ClimbRate); Count++; } if(Count==0) return -1; @@ -400,11 +400,13 @@ static void GPS_NMEA(void) // wh } #ifdef WITH_GPS_UBX +#ifdef DEBUG_PRINT static void DumpUBX(void) { Format_String(CONS_UART_Write, "UBX:"); for(uint8_t Idx=0; Idx<20; Idx++) { CONS_UART_Write(' '); Format_Hex(CONS_UART_Write, UBX.Byte[Idx]); } Format_String(CONS_UART_Write, "\n"); } +#endif // DEBUG_PRINT static void GPS_UBX(void) // when GPS gets an UBX packet { GPS_Status.UBX=1; diff --git a/main/hal.cpp b/main/hal.cpp index 3dcd194..7a15e45 100644 --- a/main/hal.cpp +++ b/main/hal.cpp @@ -86,7 +86,12 @@ UART2 pins: */ +#ifdef WITH_TTGO +#define PIN_LED_PCB GPIO_NUM_2 // status LED on the PCB: 25 or 2. GPIO25 id DAC2 +#endif +#ifdef WITH_HELTEC #define PIN_LED_PCB GPIO_NUM_25 // status LED on the PCB: 25 or 2. GPIO25 id DAC2 +#endif // #define PIN_LED_TX GPIO_NUM_?? // #define PIN_LED_RX GPIO_NUM_?? @@ -445,26 +450,32 @@ static const esp_spp_role_t role_slave = ESP_SPP_ROLE_SLAVE; // static uint32_t ConnHandle=0; -extern "C" +// extern "C" void esp_spp_cb(esp_spp_cb_event_t Event, esp_spp_cb_param_t *Param) { switch (Event) { case ESP_SPP_INIT_EVT: esp_bt_dev_set_device_name("TRACKER"); esp_bt_gap_set_scan_mode(ESP_BT_SCAN_MODE_CONNECTABLE_DISCOVERABLE); - esp_spp_start_srv(sec_mask, role_slave, 0, "OGN"); + esp_spp_start_srv(sec_mask, role_slave, 0, "SPP_SERVER"); break; -/* - case ESP_SPP_SRV_OPEN_EVT: // open connection: new handle comes + case ESP_SPP_DISCOVERY_COMP_EVT: + break; + case ESP_SPP_START_EVT: // SPP server started succesfully + break; + case ESP_SPP_SRV_OPEN_EVT: // server connection opens: new handle comes // Param->open.handle, Param->open.rem_bda - case ESP_SPP_SRV_CLOSE_EVT: // connection closes for given handle + break; + case ESP_SPP_OPEN_EVT: // connection opens // Param->close.handle, Param->close.rem_bda break; - case ESP_SPP_DATA_IND_EVT: // data is sent by the client + case ESP_SPP_CLOSE_EVT: // connection closes for given handle + // Param->close.handle, Param->close.rem_bda + break; + case ESP_SPP_DATA_IND_EVT: // data is sent by the client // Param->data_ind.handle, Param->data_ind.data, Param->data_ind.len break; - case ESP_SPP_WRITE_EVT: // data has been sent to the cielnt + case ESP_SPP_WRITE_EVT: // (queued) data has been sent to the client break; -*/ default: break; } @@ -481,8 +492,8 @@ int BT_SPP_Init(void) esp_err_t Err; Err = esp_bt_controller_init(&BTconf); if(Err!=ESP_OK) return Err; Err = esp_bt_controller_enable(ESP_BT_MODE_CLASSIC_BT); if(Err!=ESP_OK) return Err; - Err = esp_bluedroid_init(); if(Err!=ESP_OK) return Err; - Err = esp_bluedroid_enable(); if(Err!=ESP_OK) return Err; + Err = esp_bluedroid_init(); if(Err!=ESP_OK) return Err; // init the BT stack + Err = esp_bluedroid_enable(); if(Err!=ESP_OK) return Err; // enable the BT stack Err = esp_spp_register_callback(esp_spp_cb); if(Err!=ESP_OK) return Err; Err = esp_spp_init(esp_spp_mode); if(Err!=ESP_OK) return Err; return Err; } @@ -518,7 +529,7 @@ int SPIFFS_Info(size_t &Total, size_t &Used, const char *Label) // ====================================================================================================== -SemaphoreHandle_t I2C_Mutex; +// SemaphoreHandle_t I2C_Mutex; uint8_t I2C_Read(uint8_t Bus, uint8_t Addr, uint8_t Reg, uint8_t *Data, uint8_t Len, uint8_t Wait) { i2c_cmd_handle_t Cmd = i2c_cmd_link_create(); diff --git a/main/hal.h b/main/hal.h index 972b5f0..45e1df8 100644 --- a/main/hal.h +++ b/main/hal.h @@ -17,8 +17,13 @@ #define USE_BLOCK_SPI // use block SPI interface for RF chip -#define WITH_RFM95 // RF chip selection +#define WITH_HELTEC // HELTEC module: PCB LED on GPI025 +// #define WITH_TTGO // TTGO module: PCB LED on GPIO2, GPIO25 free to use as DAC2 output +#define WITH_OLED // OLED display on the I2C: some TTGO modules are without OLED display + +#define WITH_RFM95 // RF chip selection: both HELTEC and TTGO use sx1276 which is same af RFM95 // #define WITH_RFM69 + // #define WITH_LED_RX // #define WITH_LED_TX @@ -32,16 +37,15 @@ // #define WITH_BMP180 // BMP180 pressure sensor // #define WITH_BMP280 // BMP280 pressure sensor +// #define WITH_BME280 // with humidity // #define WITH_MS5607 // MS5607 pressure sensor -#define I2C_SPEED 1000000 // [Hz] +#define I2C_SPEED 1000000 // [Hz] bit rate on the I2C (nominally up to 400000) #define WITH_PFLAA // PFLAU and PFLAA for compatibility with XCsoar and LK8000 #define WITH_CONFIG // interpret the console input: $POGNS to change parameters -#define WITH_OLED // OLED display on the I2C - // #define WITH_BT_SPP // Bluetooth serial port fo smartphone/tablet link // ============================================================================================================ @@ -56,7 +60,7 @@ extern uint8_t MAV_Seq; // sequence number for MAVlink messag // ============================================================================================================ extern SemaphoreHandle_t CONS_Mutex; // console port Mutex -extern SemaphoreHandle_t I2C_Mutex; // I2C port Mutex (OLED and Baro) +// extern SemaphoreHandle_t I2C_Mutex; // I2C port Mutex (OLED and Baro) uint64_t getUniqueID(void); // get some unique ID of the CPU/chip uint32_t getUniqueAddress(void); // get unique 24-bit address for the transmitted IF diff --git a/main/main.cpp b/main/main.cpp index 2eeb22c..5484f20 100644 --- a/main/main.cpp +++ b/main/main.cpp @@ -17,7 +17,7 @@ void app_main(void) // printf("OGN Tracker on ESP32\n"); CONS_Mutex = xSemaphoreCreateMutex(); // semaphore for sharing the writing to the console - I2C_Mutex = xSemaphoreCreateMutex(); // semaphore for sharing the I2C bus + // I2C_Mutex = xSemaphoreCreateMutex(); // semaphore for sharing the I2C bus NVS_Init(); // initialize Non-Volatile-Storage in Flash and read the tracker parameters @@ -27,16 +27,16 @@ void app_main(void) SPIFFS_Register(); // initialize the file system in the Flash + IO_Configuration(); // initialize the GPIO/UART/I2C/SPI for Radio, GPS, OLED, Baro + #ifdef WITH_BT_SPP BT_SPP_Init(); // start BT SPP #endif - IO_Configuration(); // initialize the GPIO/UART/I2C/SPI for Radio, GPS, OLED, Baro - xTaskCreate(vTaskRF, "RF", 2048, 0, tskIDLE_PRIORITY+4, 0); 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_MS5607) +#if defined(WITH_BMP180) || defined(WITH_BMP280) || defined(BME280) || defined(WITH_MS5607) xTaskCreate(vTaskSENS, "SENS", 2048, 0, tskIDLE_PRIORITY+4, 0); #endif // xTaskCreate(vTaskCTRL, "CTRL", 1536, 0, tskIDLE_PRIORITY+2, 0); diff --git a/main/nmea.cpp b/main/nmea.cpp index be34e51..239b271 100644 --- a/main/nmea.cpp +++ b/main/nmea.cpp @@ -15,5 +15,5 @@ uint8_t NMEA_AppendCheck(uint8_t *NMEA, uint8_t Len) uint8_t NMEA_AppendCheckCRNL(uint8_t *NMEA, uint8_t Len) { uint8_t CheckLen=NMEA_AppendCheck(NMEA, Len); - Len+=CheckLen; NMEA[Len]='\r'; NMEA[Len+1]='\n'; - return CheckLen+2; } + Len+=CheckLen; NMEA[Len]='\n'; + return CheckLen+1; } diff --git a/main/ogn.h b/main/ogn.h index 629497c..06a8254 100644 --- a/main/ogn.h +++ b/main/ogn.h @@ -625,8 +625,8 @@ class OGN_Packet // Packet structure for the OGN tracker { return DecodeUR2V12(Position.Altitude); } void EncodeDOP(uint8_t DOP) - { if(DOP<0) DOP=0; - else if(DOP<0x10) { } + { // if(DOP<0) DOP=0; + if(DOP<0x10) { } else if(DOP<0x30) DOP = 0x10 | ((DOP-0x10)>>1); else if(DOP<0x70) DOP = 0x20 | ((DOP-0x30)>>2); else if(DOP<0xF0) DOP = 0x30 | ((DOP-0x70)>>3); diff --git a/main/parameters.h b/main/parameters.h index 6db30c7..a102e85 100644 --- a/main/parameters.h +++ b/main/parameters.h @@ -6,6 +6,8 @@ #include "hal.h" +#include "ogn.h" + #ifdef WITH_ESP32 #include "nvs.h" #endif @@ -53,20 +55,26 @@ class FlashParameters uint16_t SoftPPSdelay; // [ms] static const uint8_t InfoParmLen = 16; // [char] max. size of an infp-parameter - static const uint8_t InfoParmNum = 6; // [int] number of info-parameters - char *InfoParmValue(uint8_t Idx) { return Idx #include "hal.h" - #include "proc.h" #include "ctrl.h" @@ -26,6 +25,7 @@ static LDPC_Decoder Decoder; // error corrector for the OGN Gallager co static OGN_PrioQueue<16> RelayQueue; // received packets and candidates to be relayed +#ifdef DEBUG_PRINT static void PrintRelayQueue(uint8_t Idx) // for debug { uint8_t Len=0; // Len+=Format_String(Line+Len, ""); @@ -34,27 +34,27 @@ static void PrintRelayQueue(uint8_t Idx) // for debug Line[Len++]='['; Len+=Format_Hex(Line+Len, Idx); Line[Len++]=']'; Line[Len++]=' '; Len+=RelayQueue.Print(Line+Len); Format_String(CONS_UART_Write, Line); - xSemaphoreGive(CONS_Mutex); -} + xSemaphoreGive(CONS_Mutex); } +#endif static bool GetRelayPacket(OGN_TxPacket *Packet) // prepare a packet to be relayed -{ if(RelayQueue.Sum==0) return 0; - XorShift32(RX_Random); - uint8_t Idx=RelayQueue.getRand(RX_Random); - if(RelayQueue.Packet[Idx].Rank==0) return 0; - memcpy(Packet->Packet.Byte(), RelayQueue[Idx]->Byte(), OGN_Packet::Bytes); - Packet->Packet.Header.RelayCount+=1; - Packet->Packet.Whiten(); Packet->calcFEC(); +{ if(RelayQueue.Sum==0) return 0; // if no packets in the relay queue + XorShift32(RX_Random); // produce a new random number + uint8_t Idx=RelayQueue.getRand(RX_Random); // get weight-random packet from the relay queue + if(RelayQueue.Packet[Idx].Rank==0) return 0; // should not happen ... + memcpy(Packet->Packet.Byte(), RelayQueue[Idx]->Byte(), OGN_Packet::Bytes); // copy the packet + Packet->Packet.Header.RelayCount+=1; // increment the relay count (in fact we only do single relay) + Packet->Packet.Whiten(); Packet->calcFEC(); // whiten and calc. the FEC code => packet ready for transmission // PrintRelayQueue(Idx); // for debug - RelayQueue.decrRank(Idx); + RelayQueue.decrRank(Idx); // reduce the rank of the packet selected for relay return 1; } -static void CleanRelayQueue(uint32_t Time, uint32_t Delay=20) -{ RelayQueue.cleanTime((Time-Delay)%60); } +static void CleanRelayQueue(uint32_t Time, uint32_t Delay=20) // remove "old" packets from the relay queue +{ RelayQueue.cleanTime((Time-Delay)%60); } // remove packets 20(default) seconds into the past // --------------------------------------------------------------------------------------------------------------------------------------- -static void ReadStatus(OGN_TxPacket &StatPacket) +static void ReadStatus(OGN_TxPacket &StatPacket) // read the device status and fill the status packet { #ifdef WITH_STM32 @@ -71,8 +71,8 @@ static void ReadStatus(OGN_TxPacket &StatPacket) uint16_t RxRate = RX_OGN_Count64+1; uint8_t RxRateLog2=0; RxRate>>=1; while(RxRate) { RxRate>>=1; RxRateLog2++; } StatPacket.Packet.Status.RxRate = RxRateLog2; - - { uint8_t Len=0; + // produce the POGNR sentence + { uint8_t Len=0; Len+=Format_String(Line+Len, "$POGNR,"); // NMEA report: radio status Len+=Format_UnsDec(Line+Len, RF_FreqPlan.Plan); // which frequency plan Line[Len++]=','; @@ -98,7 +98,7 @@ static void ReadStatus(OGN_TxPacket &StatPacket) #ifdef WITH_SDLOG if(Log_Free()>=128) { xSemaphoreTake(Log_Mutex, portMAX_DELAY); - Format_String(Log_Write, Line, Len); // send the NMEA out to the log file + Format_String(Log_Write, Line, Len, 0); // send the NMEA out to the log file xSemaphoreGive(Log_Mutex); } #endif } @@ -126,7 +126,7 @@ static void ProcessRxPacket(OGN_RxPacket *RxPacket, uint8_t RxPacketIdx) #ifdef WITH_SDLOG if(Log_Free()>=128) { xSemaphoreTake(Log_Mutex, portMAX_DELAY); - Format_String(Log_Write, Line, Len); + Format_String(Log_Write, Line, Len, 0); xSemaphoreGive(Log_Mutex); } #endif #ifdef WITH_PFLAA @@ -190,9 +190,13 @@ void vTaskPROC(void* pvParameters) #endif RelayQueue.Clear(); - OGN_TxPacket PosPacket; // position packet - uint32_t PosTime=0; // [sec] when the position was recorded - OGN_TxPacket StatPacket; // status report packet + static uint16_t AverSpeed=0; // [0.1m/s] average speed (including vertical) + static bool isMoving=0; // is the aircraft moving ? + + static OGN_TxPacket PosPacket; // position packet + static uint32_t PosTime=0; // [sec] when the position was recorded + static OGN_TxPacket StatPacket; // status report packet + static OGN_TxPacket InfoPacket; // information packet for( ; ; ) { vTaskDelay(1); @@ -240,7 +244,8 @@ void vTaskPROC(void* pvParameters) // GPS_Position *Position = GPS_getPosition(); if(Position) Position->EncodeStatus(StatPacket.Packet); // encode GPS altitude and pressure if( Position && Position->isReady && (!Position->Sent) && Position->isReady && Position->isValid() ) - { int16_t AverSpeed=GPS_AverageSpeed(); // [0.1m/s] average speed, including the vertical speed + { AverSpeed=GPS_AverageSpeed(); // [0.1m/s] average speed, including the vertical speed + isMoving = AverSpeed>10; RF_FreqPlan.setPlan(Position->Latitude, Position->Longitude); // set the frequency plan according to the GPS position /* #ifdef DEBUG_PRINT @@ -275,7 +280,7 @@ void vTaskPROC(void* pvParameters) xSemaphoreGive(CONS_Mutex); #endif XorShift32(RX_Random); - if( (AverSpeed>10) || ((RX_Random&0x3)==0) ) // send only some positions if the speed is less than 1m/s + if( isMoving || ((RX_Random&0x3)==0) ) // send only some positions if the speed is less than 1m/s RF_TxFIFO.Write(); // complete the write into the TxFIFO Position->Sent=1; #ifdef WITH_FLASHLOG @@ -312,6 +317,13 @@ void vTaskPROC(void* pvParameters) Format_String(CONS_UART_Write, Line); xSemaphoreGive(CONS_Mutex); #endif + // Parameters.WriteHeader(InfoPacket.Packet); + InfoPacket.Packet.HeaderWord=0; + InfoPacket.Packet.Header.Address = Parameters.Address; // set address + InfoPacket.Packet.Header.AddrType = Parameters.AddrType; // address-type + InfoPacket.Packet.Header.Other=1; + InfoPacket.Packet.calcAddrParity(); // parity of (part of) the header + StatPacket.Packet.HeaderWord=0; StatPacket.Packet.Header.Address = Parameters.Address; // set address StatPacket.Packet.Header.AddrType = Parameters.AddrType; // address-type diff --git a/main/rf.cpp b/main/rf.cpp index fd4be09..0886000 100644 --- a/main/rf.cpp +++ b/main/rf.cpp @@ -79,8 +79,8 @@ static uint32_t ReceiveUntil(TickType_t End) vTaskDelay(1); } return Count; } -static uint32_t ReceiveFor(TickType_t Ticks) // keep receiving packets for given period of time -{ return ReceiveUntil(xTaskGetTickCount()+Ticks); } +// static uint32_t ReceiveFor(TickType_t Ticks) // keep receiving packets for given period of time +// { return ReceiveUntil(xTaskGetTickCount()+Ticks); } static uint8_t Transmit(uint8_t TxChan, const uint8_t *PacketByte, uint8_t Thresh, uint8_t MaxWait=7) { diff --git a/main/sens.cpp b/main/sens.cpp index c4b4006..7dba949 100644 --- a/main/sens.cpp +++ b/main/sens.cpp @@ -11,7 +11,7 @@ // #define DEBUG_PRINT -#if defined(WITH_BMP180) || defined(WITH_BMP280) || defined(WITH_MS5607) +#if defined(WITH_BMP180) || defined(WITH_BMP280) || defined(WITH_MS5607) || defined(WITH_BME280) #ifdef WITH_BMP180 #include "bmp180.h" @@ -21,6 +21,10 @@ #include "bmp280.h" #endif +#ifdef WITH_BME280 +#include "bme280.h" +#endif + #ifdef WITH_MS5607 #include "ms5607.h" #endif @@ -63,6 +67,10 @@ static BMP180 Baro; // BMP180 barometer sensor static BMP280 Baro; // BMP280 barometer sensor #endif +#ifdef WITH_BME280 +static BME280 Baro; // BMP280 barometer sensor with humidity sensor +#endif + #ifdef WITH_MS5607 static MS5607 Baro; // BMP280 barometer sensor #endif @@ -81,7 +89,7 @@ static Delay PressDelay; // 4-second delay for long-term clim static char Line[64]; // line to prepare the barometer NMEA sentence static uint8_t InitBaro() -{ xSemaphoreTake(I2C_Mutex, portMAX_DELAY); +{ // xSemaphoreTake(I2C_Mutex, portMAX_DELAY); Baro.Bus=BARO_I2C; uint8_t Err=Baro.CheckID(); if(Err==0) Err=Baro.ReadCalib(); @@ -89,11 +97,11 @@ 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) +#if defined(WITH_BMP280) || defined(WITH_MS5607) || defined(WITH_BME280) if(Err==0) Err=Baro.Acquire(); if(Err==0) { Baro.Calculate(); } #endif - xSemaphoreGive(I2C_Mutex); + // xSemaphoreGive(I2C_Mutex); // if(Err) LED_BAT_On(); return Err==0 ? Baro.ADDR:0; } @@ -109,32 +117,41 @@ static void ProcBaro(void) #ifdef WITH_BMP180 TickType_t Start=xTaskGetTickCount(); - xSemaphoreTake(I2C_Mutex, portMAX_DELAY); + // xSemaphoreTake(I2C_Mutex, portMAX_DELAY); uint8_t Err=Baro.AcquireRawTemperature(); // measure temperature - xSemaphoreGive(I2C_Mutex); + // xSemaphoreGive(I2C_Mutex); if(Err==0) { Baro.CalcTemperature(); AverPress=0; AverCount=0; } // clear the average else { PipeCount=0; - xSemaphoreTake(I2C_Mutex, portMAX_DELAY); + // xSemaphoreTake(I2C_Mutex, portMAX_DELAY); I2C_Restart(Baro.Bus); - xSemaphoreGive(I2C_Mutex); + // xSemaphoreGive(I2C_Mutex); vTaskDelay(20); InitBaro(); // try to recover I2C bus and baro return; } - for(uint8_t Idx=0; Idx<24; Idx++) - { xSemaphoreTake(I2C_Mutex, portMAX_DELAY); + for(uint8_t Idx=0; Idx<16; Idx++) + { // xSemaphoreTake(I2C_Mutex, portMAX_DELAY); uint8_t Err=Baro.AcquireRawPressure(); // take pressure measurement - xSemaphoreGive(I2C_Mutex); + // xSemaphoreGive(I2C_Mutex); if(Err==0) { Baro.CalcPressure(); AverPress+=Baro.Pressure; AverCount++; } // sum-up average pressure TickType_t Time=xTaskGetTickCount()-Start; if(Time>=200) break; } // but no longer than 250ms to fit into 0.5 second slot if(AverCount==0) { PipeCount=0; return ; } // and we summed-up some measurements AverPress = ( (AverPress<<2) + (AverCount>>1) )/AverCount; // [0.25Pa]] make the average +#ifdef DEBUG_PRINT + xSemaphoreTake(CONS_Mutex, portMAX_DELAY); + Format_String(CONS_UART_Write, "BMP180: "); + Format_UnsDec(CONS_UART_Write, (AverPress+2)/4, 3, 2); + Format_String(CONS_UART_Write, "hPa/"); + Format_UnsDec(CONS_UART_Write, (uint16_t)AverCount); + Format_String(CONS_UART_Write, "\n"); + xSemaphoreGive(CONS_Mutex); #endif -#if defined(WITH_BMP280) || defined(WITH_MS5607) - xSemaphoreTake(I2C_Mutex, portMAX_DELAY); +#endif +#if defined(WITH_BMP280) || defined(WITH_MS5607) || defined(WITH_BME280) + // xSemaphoreTake(I2C_Mutex, portMAX_DELAY); uint8_t Err=Baro.Acquire(); - xSemaphoreGive(I2C_Mutex); + // xSemaphoreGive(I2C_Mutex); if(Err==0) { Baro.Calculate(); } else { PipeCount=0; return; } AverPress = Baro.Pressure; // [0.25Pa] @@ -207,6 +224,10 @@ static void ProcBaro(void) Line[Len++]=','; Len+=Format_SignDec(Line+Len, ClimbRate, 3, 2); // [m/s] climb rate Line[Len++]=','; +#ifdef WITH_BME280 + Len+=Format_SignDec(Line+Len, Baro.Humidity,3, 1); // [%] relative humidity + Line[Len++]=','; +#endif Len+=NMEA_AppendCheckCRNL(Line, Len); // if(CONS_UART_Free()>=128) { xSemaphoreTake(CONS_Mutex, portMAX_DELAY); @@ -215,7 +236,7 @@ static void ProcBaro(void) #ifdef WITH_SDLOG if(Log_Free()>=128) { xSemaphoreTake(Log_Mutex, portMAX_DELAY); - Format_String(Log_Write, Line, Len); // send NMEA sentence to the log file + Format_String(Log_Write, Line, Len, 0); // send NMEA sentence to the log file xSemaphoreGive(Log_Mutex); } #endif @@ -233,7 +254,7 @@ static void ProcBaro(void) } -#endif // WITH_BMP180/BMP280 +#endif // WITH_BMP180/BMP280/BME280 @@ -245,7 +266,7 @@ void vTaskSENS(void* pvParameters) // VarioSound(0); // #endif -#if defined(WITH_BMP180) || defined(WITH_BMP280) || defined(WITH_MS5607) +#if defined(WITH_BMP180) || defined(WITH_BMP280) || defined(WITH_MS5607) || defined(WITH_BME280) BaroPipe.Clear (4*90000); BaroNoise.Set(12*16); // guess the pressure noise level @@ -272,6 +293,12 @@ void vTaskSENS(void* pvParameters) else Format_String(CONS_UART_Write, " ?!"); #endif +#ifdef WITH_BME280 + Format_String(CONS_UART_Write, " BME280: "); + if(Detected) { Format_String(CONS_UART_Write, " @"); Format_Hex(CONS_UART_Write, Detected); } + else Format_String(CONS_UART_Write, " ?!"); +#endif + #ifdef WITH_MS5607 Format_String(CONS_UART_Write, " MS5607: "); if(Detected) { Format_String(CONS_UART_Write, " @"); Format_Hex(CONS_UART_Write, Detected); } @@ -283,7 +310,7 @@ void vTaskSENS(void* pvParameters) while(1) { -#if defined(WITH_BMP180) || defined(WITH_BMP280) || defined(WITH_MS5607) +#if defined(WITH_BMP180) || defined(WITH_BMP280) || defined(WITH_MS5607) || defined(WITH_BME280) ProcBaro(); #else vTaskDelay(1000); diff --git a/sdkconfig b/sdkconfig index 862cddd..c54237b 100644 --- a/sdkconfig +++ b/sdkconfig @@ -246,6 +246,13 @@ CONFIG_ESP32_PHY_MAX_TX_POWER=20 # CONFIG_PM_ENABLE= +# +# ADC-Calibration +# +CONFIG_ADC_CAL_EFUSE_TP_ENABLE=y +CONFIG_ADC_CAL_EFUSE_VREF_ENABLE=y +CONFIG_ADC_CAL_LUT_ENABLE=y + # # Ethernet #