Merge branch 'dev' into scan_exp

This commit is contained in:
Scott Powell
2025-05-26 16:44:27 +10:00
9 changed files with 160 additions and 108 deletions

1
.gitignore vendored
View File

@@ -8,3 +8,4 @@ out/
.direnv/
.DS_Store
.vscode/settings.json
.vscode/extensions.json

View File

@@ -22,7 +22,7 @@
#define PIN_BOARD_SCL1 41 //SCL for PMU and PFC8563 (RTC)
#define PIN_PMU_IRQ 40 //IRQ pin for PMU
#define PIN_USER_BTN 0
//#define PIN_USER_BTN 0
#define P_BOARD_SPI_MOSI 35 //SPI for SD Card and QMI8653 (IMU)
#define P_BOARD_SPI_MISO 37 //SPI for SD Card and QMI8653 (IMU)
@@ -61,10 +61,10 @@ public:
void begin() {
power_init();
ESP32Board::begin();
power_init();
esp_reset_reason_t reason = esp_reset_reason();
if (reason == ESP_RST_DEEPSLEEP) {
long wakeup_source = esp_sleep_get_ext1_wakeup_status();

View File

@@ -80,6 +80,11 @@ bool RAK4631Board::startOTAUpdate(const char* id, char reply[]) {
Bluefruit.Advertising.setFastTimeout(30); // number of seconds in fast mode
Bluefruit.Advertising.start(0); // 0 = Don't stop advertising after n seconds
strcpy(reply, "OK - started");
uint8_t mac_addr[6];
memset(mac_addr, 0, sizeof(mac_addr));
Bluefruit.getAddr(mac_addr);
sprintf(reply, "OK - mac: %02X:%02X:%02X:%02X:%02X:%02X",
mac_addr[0], mac_addr[1], mac_addr[2], mac_addr[3], mac_addr[4], mac_addr[5]);
return true;
}

View File

@@ -17,11 +17,20 @@ build_flags =
-D SX126X_DIO3_TCXO_VOLTAGE=1.8
-D SX126X_CURRENT_LIMIT=140
-D SX126X_RX_BOOSTED_GAIN=1
-D ENV_INCLUDE_AHTX0=1
-D ENV_INCLUDE_BME280=1
-D ENV_INCLUDE_INA3221=1
-D ENV_INCLUDE_INA219=1
build_src_filter = ${esp32_base.build_src_filter}
+<../variants/heltec_v3>
+<helpers/sensors>
lib_deps =
${esp32_base.lib_deps}
adafruit/Adafruit SSD1306 @ ^2.5.13
adafruit/Adafruit INA3221 Library @ ^1.0.1
adafruit/Adafruit INA219 @ ^1.2.3
adafruit/Adafruit AHTX0 @ ^2.0.5
adafruit/Adafruit BME280 Library @ ^2.3.0
[env:Heltec_v3_repeater]
extends = Heltec_lora32_v3

View File

@@ -14,7 +14,7 @@ WRAPPER_CLASS radio_driver(radio, board);
ESP32RTCClock fallback_clock;
AutoDiscoverRTCClock rtc_clock(fallback_clock);
SensorManager sensors;
EnvironmentSensorManager sensors;
#ifdef DISPLAY_CLASS
DISPLAY_CLASS display;

View File

@@ -7,6 +7,7 @@
#include <helpers/CustomSX1262Wrapper.h>
#include <helpers/AutoDiscoverRTCClock.h>
#include <helpers/SensorManager.h>
#include <helpers/sensors/EnvironmentSensorManager.h>
#ifdef DISPLAY_CLASS
#include <helpers/ui/SSD1306Display.h>
#endif
@@ -14,7 +15,7 @@
extern HeltecV3Board board;
extern WRAPPER_CLASS radio_driver;
extern AutoDiscoverRTCClock rtc_clock;
extern SensorManager sensors;
extern EnvironmentSensorManager sensors;
#ifdef DISPLAY_CLASS
extern DISPLAY_CLASS display;

View File

@@ -8,19 +8,22 @@ build_flags =
-D P_LORA_TX_LED=6
-D PIN_BOARD_SDA=17
-D PIN_BOARD_SCL=18
-D PIN_USER_BTN=0
-D RADIO_CLASS=CustomSX1262
-D WRAPPER_CLASS=CustomSX1262Wrapper
;-D DISPLAY_CLASS=SSD1306Display ;Needs to be modified for SH1106
-D DISPLAY_CLASS=SH1106Display
-D SX126X_RX_BOOSTED_GAIN=1
-D SX126X_CURRENT_LIMIT=140
build_src_filter = ${esp32_base.build_src_filter}
+<../variants/lilygo_tbeam_supreme_SX1262>
+<helpers/ui/SH1106Display.cpp>
board_build.partitions = min_spiffs.csv ; get around 4mb flash limit
lib_deps =
${esp32_base.lib_deps}
lewisxhe/XPowersLib @ ^0.2.7
;adafruit/Adafruit SSD1306 @ ^2.5.13
adafruit/Adafruit SH110X @ ^2.1.13
stevemarple/MicroNMEA @ ^2.0.6
adafruit/Adafruit BME280 Library @ ^2.3.0
; === LILYGO T-Beam S3 Supreme with SX1262 environments ===
[env:T_Beam_S3_Supreme_SX1262_repeater]
@@ -64,8 +67,8 @@ build_flags =
-D MAX_CONTACTS=100
-D MAX_GROUP_CHANNELS=8
-D BLE_PIN_CODE=123456
-D BLE_DEBUG_LOGGING=1
-D OFFLINE_QUEUE_SIZE=256
; -D BLE_DEBUG_LOGGING=1
; -D ENABLE_PRIVATE_KEY_IMPORT=1
; -D ENABLE_PRIVATE_KEY_EXPORT=1
; -D MESH_PACKET_LOGGING=8

View File

@@ -4,6 +4,10 @@
TBeamS3SupremeBoard board;
#ifdef DISPLAY_CLASS
DISPLAY_CLASS display;
#endif
bool pmuIntFlag;
#ifndef LORA_CR
@@ -46,7 +50,7 @@ void scanDevices(TwoWire *w)
switch (addr) {
case 0x77:
case 0x76:
Serial.println("\tFound BMX280 Sensor");
Serial.println("\tFound BME280 Sensor");
deviceOnline |= BME280_ONLINE;
break;
case 0x34:
@@ -107,6 +111,26 @@ void TBeamS3SupremeBoard::printPMU()
Serial.println();
}
void TbeamSupSensorManager::printBMEValues() {
Serial.print("Temperature = ");
Serial.print(bme.readTemperature());
Serial.println(" *C");
Serial.print("Pressure = ");
Serial.print(bme.readPressure() / 100.0F);
Serial.println(" hPa");
Serial.print("Approx. Altitude = ");
Serial.print(bme.readAltitude(SEALEVELPRESSURE_HPA));
Serial.println(" m");
Serial.print("Humidity = ");
Serial.print(bme.readHumidity());
Serial.println(" %");
Serial.println();
}
#endif
bool TBeamS3SupremeBoard::power_init()
@@ -119,9 +143,9 @@ bool TBeamS3SupremeBoard::power_init()
PMU.setChargingLedMode(XPOWERS_CHG_LED_CTRL_CHG);
// Set up PMU interrupts
// MESH_DEBUG_PRINTLN("Setting up PMU interrupts");
// pinMode(PIN_PMU_IRQ, INPUT_PULLUP);
// attachInterrupt(PIN_PMU_IRQ, setPMUIntFlag, FALLING);
MESH_DEBUG_PRINTLN("Setting up PMU interrupts");
pinMode(PIN_PMU_IRQ, INPUT_PULLUP);
attachInterrupt(PIN_PMU_IRQ, setPMUIntFlag, FALLING);
// GPS
MESH_DEBUG_PRINTLN("Setting and enabling a-ldo4 for GPS");
@@ -164,22 +188,22 @@ bool TBeamS3SupremeBoard::power_init()
PMU.enableBLDO1();
// Out to header pins
// MESH_DEBUG_PRINTLN("Setting and enabling b-ldo2 for output to header");
// PMU.setBLDO2Voltage(3300);
// PMU.enableBLDO2();
MESH_DEBUG_PRINTLN("Setting and enabling b-ldo2 for output to header");
PMU.setBLDO2Voltage(3300);
PMU.enableBLDO2();
// MESH_DEBUG_PRINTLN("Setting and enabling dcdc4 for output to header");
// PMU.setDC4Voltage(XPOWERS_AXP2101_DCDC4_VOL2_MAX); // 1.8V
// PMU.enableDC4();
MESH_DEBUG_PRINTLN("Setting and enabling dcdc4 for output to header");
PMU.setDC4Voltage(XPOWERS_AXP2101_DCDC4_VOL2_MAX); // 1.8V
PMU.enableDC4();
// MESH_DEBUG_PRINTLN("Setting and enabling dcdc5 for output to header");
// PMU.setDC5Voltage(3300);
// PMU.enableDC5();
MESH_DEBUG_PRINTLN("Setting and enabling dcdc5 for output to header");
PMU.setDC5Voltage(3300);
PMU.enableDC5();
// Unused power rails
MESH_DEBUG_PRINTLN("Disabling unused supplies dcdc2, dldo1 and dldo2");
MESH_DEBUG_PRINTLN("Disabling unused supplies dcdc2, dcdc5, dldo1 and dldo2");
PMU.disableDC2();
PMU.disableDC5();
//PMU.disableDC5();
PMU.disableDLDO1();
PMU.disableDLDO2();
@@ -199,18 +223,18 @@ bool TBeamS3SupremeBoard::power_init()
PMU.enableVbusVoltageMeasure();
// Reset and re-enable PMU interrupts
// MESH_DEBUG_PRINTLN("Re-enable interrupts");
// PMU.disableIRQ(XPOWERS_AXP2101_ALL_IRQ);
// PMU.clearIrqStatus();
// PMU.enableIRQ(
// XPOWERS_AXP2101_BAT_INSERT_IRQ | XPOWERS_AXP2101_BAT_REMOVE_IRQ | // Battery interrupts
// XPOWERS_AXP2101_VBUS_INSERT_IRQ | XPOWERS_AXP2101_VBUS_REMOVE_IRQ | // VBUS interrupts
// XPOWERS_AXP2101_PKEY_SHORT_IRQ | XPOWERS_AXP2101_PKEY_LONG_IRQ | // Power Key interrupts
// XPOWERS_AXP2101_BAT_CHG_DONE_IRQ | XPOWERS_AXP2101_BAT_CHG_START_IRQ // Charging interrupts
// );
MESH_DEBUG_PRINTLN("Re-enable interrupts");
PMU.disableIRQ(XPOWERS_AXP2101_ALL_IRQ);
PMU.clearIrqStatus();
PMU.enableIRQ(
XPOWERS_AXP2101_BAT_INSERT_IRQ | XPOWERS_AXP2101_BAT_REMOVE_IRQ | // Battery interrupts
XPOWERS_AXP2101_VBUS_INSERT_IRQ | XPOWERS_AXP2101_VBUS_REMOVE_IRQ | // VBUS interrupts
XPOWERS_AXP2101_PKEY_SHORT_IRQ | XPOWERS_AXP2101_PKEY_LONG_IRQ | // Power Key interrupts
XPOWERS_AXP2101_BAT_CHG_DONE_IRQ | XPOWERS_AXP2101_BAT_CHG_START_IRQ // Charging interrupts
);
#ifdef MESH_DEBUG
// scanDevices(&Wire);
// scanDevices(&Wire1);
scanDevices(&Wire);
scanDevices(&Wire1);
printPMU();
#endif
@@ -235,60 +259,14 @@ static bool readStringUntil(Stream& s, char dest[], size_t max_len, char term, u
return millis() < timeout; // false, if timed out
}
static bool l76kProbe()
{
bool result = false;
uint32_t startTimeout ;
Serial1.write("$PCAS03,0,0,0,0,0,0,0,0,0,0,,,0,0*02\r\n");
delay(5);
// Get version information
startTimeout = millis() + 3000;
MESH_DEBUG_PRINTLN("Trying to init L76K GPS");
// Serial1.flush();
while (Serial1.available()) {
int c = Serial1.read();
// Serial.write(c);
// Serial.print(".");
// Serial.flush();
// Serial1.flush();
if (millis() > startTimeout) {
MESH_DEBUG_PRINTLN("L76K NMEA timeout!");
return false;
}
};
Serial1.flush();
delay(200);
Serial1.write("$PCAS06,0*1B\r\n");
char ver[100];
if (!readStringUntil(Serial1, ver, sizeof(ver), '\n', 500)) {
MESH_DEBUG_PRINTLN("Get L76K timeout!");
return false;
}
if (memcmp(ver, "$GPTXT,01,01,02", 15) == 0) {
MESH_DEBUG_PRINTLN("L76K GNSS init succeeded, using L76K GNSS Module\n");
result = true;
}
delay(500);
// Initialize the L76K Chip, use GPS + GLONASS
Serial1.write("$PCAS04,5*1C\r\n");
delay(250);
// only ask for RMC and GGA
Serial1.write("$PCAS03,1,0,0,0,1,0,0,0,0,0,,,0,0*02\r\n");
delay(250);
// Switch to Vehicle Mode, since SoftRF enables Aviation < 2g
Serial1.write("$PCAS11,3*1E\r\n");
return result;
}
bool radio_init() {
fallback_clock.begin();
rtc_clock.begin(Wire1);
// #ifdef MESH_DEBUG
// printBMEValues();
// #endif
#ifdef SX126X_DIO3_TCXO_VOLTAGE
float tcxo = SX126X_DIO3_TCXO_VOLTAGE;
@@ -340,55 +318,95 @@ void TbeamSupSensorManager::sleep_gps() {
}
bool TbeamSupSensorManager::begin() {
//init BME280
if (! bme.begin(0x77, &Wire)) {
MESH_DEBUG_PRINTLN("Could not find a valid BME280 sensor");
bme_active = false;
}
else
MESH_DEBUG_PRINTLN("BME280 found and init!");
bme_active = true;
// init GPS port
Serial1.begin(GPS_BAUD_RATE, SERIAL_8N1, P_GPS_RX, P_GPS_TX);
bool result = false;
for ( int i = 0; i < 3; ++i) {
result = l76kProbe();
if (result) {
gps_active = true;
return result;
}
}
return result;
MESH_DEBUG_PRINTLN("Sleeping GPS for initial state");
sleep_gps();
return true;
}
bool TbeamSupSensorManager::querySensors(uint8_t requester_permissions, CayenneLPP& telemetry) {
if (requester_permissions & TELEM_PERM_LOCATION) { // does requester have permission?
telemetry.addGPS(TELEM_CHANNEL_SELF, node_lat, node_lon, node_altitude);
}
if (requester_permissions & TELEM_PERM_ENVIRONMENT && bme_active) { // does requester have permission?
telemetry.addTemperature(TELEM_CHANNEL_SELF, node_temp);
telemetry.addRelativeHumidity(TELEM_CHANNEL_SELF, node_hum);
telemetry.addBarometricPressure(TELEM_CHANNEL_SELF, node_pres);
//telemetry.addAltitude(TELEM_CHANNEL_SELF, node_alt);
}
return true;
}
void TbeamSupSensorManager::loop() {
static long next_gps_update = 0;
static long next_update = 0;
_nmea->loop();
if (millis() > next_gps_update) {
if (_nmea->isValid()) {
if (millis() > next_update) {
if (_nmea->isValid() && gps_active) {
node_lat = ((double)_nmea->getLatitude())/1000000.;
node_lon = ((double)_nmea->getLongitude())/1000000.;
node_altitude = ((double)_nmea->getAltitude()) / 1000.0;
//Serial.printf("lat %f lon %f\r\n", _lat, _lon);
MESH_DEBUG_PRINT("lat %f lon %f alt %f\r\n", node_lat, node_lon, node_altitude);
}
next_gps_update = millis() + 1000;
//read BME280 values
if(bme_active){
//node_alt = bme.readAltitude(SEALEVELPRESSURE_HPA);
node_temp = bme.readTemperature();
node_hum = bme.readHumidity();
node_pres = (bme.readPressure() / 100.0F);
#ifdef MESH_DEBUG
// Serial.print("Temperature = ");
// Serial.print(node_temp);
// Serial.println(" *C");
// Serial.print("Humidity = ");
// Serial.print(node_hum);
// Serial.println(" %");
// Serial.print("Pressure = ");
// Serial.print(node_pres);
// Serial.println(" hPa");
// Serial.print("Approx. Altitude = ");
// Serial.print(node_alt);
// Serial.println(" m");
#endif
}
next_update = millis() + 1000;
}
}
int TbeamSupSensorManager::getNumSettings() const { return 1; } // just one supported: "gps" (power switch)
int TbeamSupSensorManager::getNumSettings() const {
return 1;
}
const char* TbeamSupSensorManager::getSettingName(int i) const {
return i == 0 ? "gps" : NULL;
switch(i){
case 0: return "gps";
default: NULL;
}
}
const char* TbeamSupSensorManager::getSettingValue(int i) const {
if (i == 0) {
return gps_active ? "1" : "0";
switch(i){
case 0: return gps_active == true ? "1" : "0";
default: NULL;
}
return NULL;
}
bool TbeamSupSensorManager::setSettingValue(const char* name, const char* value) {

View File

@@ -8,15 +8,21 @@
#include <helpers/AutoDiscoverRTCClock.h>
#include <helpers/SensorManager.h>
#include <helpers/sensors/LocationProvider.h>
#include <Adafruit_BME280.h>
class TbeamSupSensorManager: public SensorManager {
bool gps_active = false;
bool bme_active = false;
LocationProvider * _nmea;
Adafruit_BME280 bme;
double node_temp, node_hum, node_pres;
#define SEALEVELPRESSURE_HPA (1013.25)
void start_gps();
void sleep_gps();
public:
TbeamSupSensorManager(LocationProvider &nmea): _nmea(&nmea) { }
TbeamSupSensorManager(LocationProvider &nmea): _nmea(&nmea) {node_temp = 0; node_hum = 0; node_pres = 0;}
bool begin() override;
bool querySensors(uint8_t requester_permissions, CayenneLPP& telemetry) override;
void loop() override;
@@ -24,6 +30,11 @@ class TbeamSupSensorManager: public SensorManager {
const char* getSettingName(int i) const override;
const char* getSettingValue(int i) const override;
bool setSettingValue(const char* name, const char* value) override;
#ifdef MESH_DEBUG
void printBMEValues();
#endif
};
extern TBeamS3SupremeBoard board;
@@ -31,6 +42,11 @@ extern WRAPPER_CLASS radio_driver;
extern AutoDiscoverRTCClock rtc_clock;
extern TbeamSupSensorManager sensors;
#ifdef DISPLAY_CLASS
#include <helpers/ui/SH1106Display.h>
extern DISPLAY_CLASS display;
#endif
enum {
POWERMANAGE_ONLINE = _BV(0),
DISPLAY_ONLINE = _BV(1),
@@ -48,7 +64,6 @@ enum {
OSC32768_ONLINE = _BV(13),
};
bool power_init();
bool radio_init();
uint32_t radio_get_rng_seed();
void radio_set_params(float freq, float bw, uint8_t sf, uint8_t cr);