kopia lustrzana https://github.com/pjalocha/esp32-ogn-tracker
Add more info-parameters, BME280 support, remove I2C mutex
rodzic
1aae80e8d7
commit
2a0e0fa849
|
@ -0,0 +1,113 @@
|
|||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
|
||||
#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;
|
||||
}
|
||||
|
||||
} ;
|
||||
|
|
@ -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);
|
||||
|
|
|
@ -84,7 +84,7 @@ 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; Idx<GPS_PosPipeSize; Idx++) // loop over GPS positions
|
||||
{ GPS_Position *Pos = Position+Idx;
|
||||
if( !Pos->hasGPS || !Pos->isValid() ) continue; // skip invalid positions
|
||||
Speed += Pos->Speed +abs(Pos->ClimbRate); Count++;
|
||||
|
@ -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;
|
||||
|
|
31
main/hal.cpp
31
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_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();
|
||||
|
|
14
main/hal.h
14
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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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; }
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
static const uint8_t InfoParmNum = 11; // [int] number of info-parameters
|
||||
char *InfoParmValue(uint8_t Idx) { return Idx<InfoParmNum ? Pilot + Idx*InfoParmLen:0; }
|
||||
const char *InfoParmName(uint8_t Idx) const { static const char *Name[InfoParmNum] = { "Pilot", "Manuf", "Model", "Reg", "Base", "ICE" } ;
|
||||
uint8_t InfoParmValueLen(uint8_t Idx) { return strlen(InfoParmValue(Idx)); }
|
||||
const char *InfoParmName(uint8_t Idx) const { static const char *Name[InfoParmNum] =
|
||||
{ "Pilot", "Manuf", "Model", "Type", "SN", "Reg", "ID", "Class", "Task", "Base", "ICE" } ;
|
||||
return Idx<InfoParmNum ? Name[Idx]:0; }
|
||||
char Pilot[InfoParmLen];
|
||||
char Manuf[InfoParmLen];
|
||||
char Model[InfoParmLen];
|
||||
char Reg[InfoParmLen];
|
||||
char Base[InfoParmLen];
|
||||
char ICE[InfoParmLen];
|
||||
char Pilot[InfoParmLen]; // Pilot name
|
||||
char Manuf[InfoParmLen]; // Manufacturer
|
||||
char Model[InfoParmLen]; // Model
|
||||
char Type[InfoParmLen]; // Type
|
||||
char SN[InfoParmLen]; // Serial Number
|
||||
char Reg[InfoParmLen]; // Registration
|
||||
char ID[InfoParmLen]; // Competition ID
|
||||
char Class[InfoParmLen]; // Competition class
|
||||
char Task[InfoParmLen]; // Competition task
|
||||
char Base[InfoParmLen]; // Base airfield
|
||||
char ICE[InfoParmLen]; // In Case of Emergency
|
||||
|
||||
// char BTname[8];
|
||||
// char BTpin[4];
|
||||
// char Pilot[16];
|
||||
// char Copilot[16]
|
||||
// char Category[16]
|
||||
|
||||
|
@ -102,14 +110,18 @@ class FlashParameters
|
|||
TimeCorr = 0; // [sec]
|
||||
GeoidSepar = 470; // [0.1m]
|
||||
|
||||
Pilot[0] = 0;
|
||||
Manuf[0] = 0;
|
||||
Model[0] = 0;
|
||||
Reg[0] = 0;
|
||||
Base[0] = 0;
|
||||
ICE[0] = 0;
|
||||
for(uint8_t Idx=0; Idx<InfoParmNum; Idx++)
|
||||
InfoParmValue(Idx)[0] = 0;
|
||||
|
||||
}
|
||||
|
||||
// void WriteHeader(OGN_Packet &Packet)
|
||||
// { Packet.HeaderWord=0;
|
||||
// Packet.Header.Address = Parameters.Address; // set address
|
||||
// Packet.Header.AddrType = Parameters.AddrType; // address-type
|
||||
// Packet.Header.Other=1;
|
||||
// Packet.calcAddrParity(); } // parity of (part of) the header
|
||||
|
||||
#ifdef WITH_ESP32
|
||||
esp_err_t WriteToNVS(const char *Name="Parameters", const char *NameSpace="TRACKER")
|
||||
{ nvs_handle Handle;
|
||||
|
@ -194,6 +206,9 @@ class FlashParameters
|
|||
#endif
|
||||
#ifdef WITH_RFM95
|
||||
Len+=Format_String(Line+Len, " RFM95");
|
||||
#endif
|
||||
#ifdef WITH_SX1272
|
||||
Len+=Format_String(Line+Len, " SX1272");
|
||||
#endif
|
||||
Line[Len++]='/';
|
||||
Len+=Format_SignDec(Line+Len, (int16_t)getTxPower());
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
#include <stdint.h>
|
||||
|
||||
#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,7 +71,7 @@ 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;
|
||||
|
||||
// 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
|
||||
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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<int32_t, 8> 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);
|
||||
|
|
|
@ -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
|
||||
#
|
||||
|
|
Ładowanie…
Reference in New Issue