v1.8.34 (power on/off features for T-BEAM V10)

This commit is contained in:
Verkehrsrot 2019-09-23 15:45:47 +02:00
parent 6abfc26f2e
commit 7daa36366b
7 changed files with 120 additions and 82 deletions

View File

@ -9,16 +9,16 @@
#define DEFAULT_VREF 1100 // tbd: use adc2_vref_to_gpio() for better estimate #define DEFAULT_VREF 1100 // tbd: use adc2_vref_to_gpio() for better estimate
#define NO_OF_SAMPLES 64 // we do some multisampling to get better values #define NO_OF_SAMPLES 64 // we do some multisampling to get better values
#ifdef HAS_PMU
#include <axp20x.h>
void pover_event_IRQ(void);
void AXP192_power(bool on);
#endif
void AXP192_init(void);
void AXP192_displaypower(void);
uint16_t read_voltage(void); uint16_t read_voltage(void);
void calibrate_voltage(void); void calibrate_voltage(void);
bool batt_sufficient(void); bool batt_sufficient(void);
#ifdef HAS_PMU
#include <axp20x.h>
void power_event_IRQ(void);
void AXP192_power(bool on);
void AXP192_init(void);
void AXP192_showstatus(void);
#endif // HAS_PMU
#endif #endif

View File

@ -43,7 +43,7 @@ description = Paxcounter is a device for metering passenger flows in realtime. I
[common] [common]
; for release_version use max. 10 chars total, use any decimal format like "a.b.c" ; for release_version use max. 10 chars total, use any decimal format like "a.b.c"
release_version = 1.8.31 release_version = 1.8.34
; DEBUG LEVEL: For production run set to 0, otherwise device will leak RAM while running! ; DEBUG LEVEL: For production run set to 0, otherwise device will leak RAM while running!
; 0=None, 1=Error, 2=Warn, 3=Info, 4=Debug, 5=Verbose ; 0=None, 1=Error, 2=Warn, 3=Info, 4=Debug, 5=Verbose
debug_level = 3 debug_level = 3
@ -55,7 +55,7 @@ platform_espressif32 = espressif32@1.10.0
monitor_speed = 115200 monitor_speed = 115200
upload_speed = 115200 upload_speed = 115200
lib_deps_lora = lib_deps_lora =
;MCCI LoRaWAN LMIC library@2.3.2 ;MCCI LoRaWAN LMIC library@3.1.0
https://github.com/mcci-catena/arduino-lmic.git#852f348 https://github.com/mcci-catena/arduino-lmic.git#852f348
lib_deps_display = lib_deps_display =
U8g2@>=2.26.13 U8g2@>=2.26.13
@ -73,8 +73,9 @@ lib_deps_basic =
76@>=1.2.2 ;Timezone by Jack Christensen 76@>=1.2.2 ;Timezone by Jack Christensen
274@>=2.3.3 ;RTC by Michael Miller 274@>=2.3.3 ;RTC by Michael Miller
SimpleButton SimpleButton
;AXP202X_Library@^1.0.0 ;AXP202X_Library@^1.0.1
https://github.com/cyberman54/AXP202X_Library.git https://github.com/lewisxhe/AXP202X_Library.git#8045ddf
;https://github.com/cyberman54/AXP202X_Library.git#b7116de
lib_deps_all = lib_deps_all =
${common.lib_deps_basic} ${common.lib_deps_basic}
${common.lib_deps_lora} ${common.lib_deps_lora}
@ -120,6 +121,4 @@ upload_protocol = esptool
upload_protocol = esptool upload_protocol = esptool
build_type = debug build_type = debug
platform = https://github.com/platformio/platform-espressif32.git#develop platform = https://github.com/platformio/platform-espressif32.git#develop
platform_packages = platform_packages = framework-arduinoespressif32 @ https://github.com/espressif/arduino-esp32.git
; use upstream Git version
framework-arduinoespressif32 @ https://github.com/espressif/arduino-esp32.git

View File

@ -62,10 +62,7 @@ void doHousekeeping() {
else else
ESP_LOGI(TAG, "Battery: %dmV", batt_voltage); ESP_LOGI(TAG, "Battery: %dmV", batt_voltage);
#ifdef HAS_PMU #ifdef HAS_PMU
if (I2C_MUTEX_LOCK()) { AXP192_showstatus();
AXP192_displaypower();
I2C_MUTEX_UNLOCK();
}
#endif #endif
#endif #endif

View File

@ -179,7 +179,10 @@ void draw_page(time_t t, uint8_t page) {
// update Battery status (line 2) // update Battery status (line 2)
#if (defined BAT_MEASURE_ADC || defined HAS_PMU) #if (defined BAT_MEASURE_ADC || defined HAS_PMU)
u8x8.setCursor(0, 2); u8x8.setCursor(0, 2);
u8x8.printf("B:%.2fV", batt_voltage / 1000.0); if (batt_voltage == 0xffff)
u8x8.printf("B:USB ");
else
u8x8.printf("B:%.2fV", batt_voltage / 1000.0);
#endif #endif
// update GPS status (line 2) // update GPS status (line 2)
@ -204,10 +207,10 @@ void draw_page(time_t t, uint8_t page) {
#endif #endif
#if (HAS_LORA) #if (HAS_LORA)
u8x8.setCursor(11, 3); u8x8.setCursor(12, 3);
if (!cfg.adrmode) // if ADR=off then display SF value inverse if (!cfg.adrmode) // if ADR=off then display SF value inverse
u8x8.setInverseFont(1); u8x8.setInverseFont(1);
u8x8.printf("%4s", getSfName(updr2rps(LMIC.datarate))); u8x8.printf("%-4s", getSfName(updr2rps(LMIC.datarate)));
if (!cfg.adrmode) // switch off inverse if it was turned on if (!cfg.adrmode) // switch off inverse if it was turned on
u8x8.setInverseFont(0); u8x8.setInverseFont(0);
#endif // HAS_LORA #endif // HAS_LORA

View File

@ -7,9 +7,24 @@
#include <stdint.h> #include <stdint.h>
// Hardware related definitions for TTGO T-Beam board /*
// (only) for newer T-Beam version T22_V10 Hardware related definitions for TTGO T-Beam board
// pinouts taken from https://github.com/lewisxhe/TTGO-T-Beam (only) for newer T-Beam version T22_V10
pinouts taken from https://github.com/lewisxhe/TTGO-T-Beam
/// Button functions: ///
Power, short press -> set device on (toggles display while device is on)
Power, long press -> set device off
User, short press -> flip display page
User, long press -> send LORA message
Reset -> reset device
*/
//#define HAS_DISPLAY U8X8_SSD1306_128X64_NONAME_HW_I2C
#define MY_OLED_SDA SDA
#define MY_OLED_SCL SCL
#define MY_OLED_RST U8X8_PIN_NONE
//#define DISPLAY_FLIP 1 // use if display is rotated
#define HAS_LORA 1 // comment out if device shall not send data via LoRa #define HAS_LORA 1 // comment out if device shall not send data via LoRa
#define CFG_sx1276_radio 1 // HPD13A LoRa SoC #define CFG_sx1276_radio 1 // HPD13A LoRa SoC
@ -30,16 +45,30 @@
//#define HAS_BME680 SDA, SCL //#define HAS_BME680 SDA, SCL
//#define BME680_ADDR BME680_I2C_ADDR_PRIMARY // !! connect SDIO of BME680 to GND !! //#define BME680_ADDR BME680_I2C_ADDR_PRIMARY // !! connect SDIO of BME680 to GND !!
// display (if connected)
//#define HAS_DISPLAY U8X8_SSD1306_128X64_NONAME_HW_I2C
//#define MY_OLED_SDA SDA
//#define MY_OLED_SCL SCL
//#define MY_OLED_RST U8X8_PIN_NONE
//#define DISPLAY_FLIP 1 // use if display is rotated
// user defined sensors (if connected) // user defined sensors (if connected)
//#define HAS_SENSORS 1 // comment out if device has user defined sensors //#define HAS_SENSORS 1 // comment out if device has user defined sensors
//#define DISABLE_BROWNOUT 1 // comment out if you want to keep brownout feature //#define DISABLE_BROWNOUT 1 // comment out if you want to keep brownout feature
#endif #endif
/*
// T-Beam V10 has on board power management by AXP192 PMU chip:
//
// DCDC1 0.7-3.5V @ 1200mA -> OLED
// DCDC3 0.7-3.5V @ 700mA -> ESP32 (keep this on!)
// LDO1 30mA -> GPS Backup
// LDO2 200mA -> LORA
// LDO3 200mA -> GPS
// Wiring for I2C OLED display:
//
// Signal Header OLED
// 3V3 7 VCC
// GND 8 GND
// IO22(SCL) 9 SCL
// IO21(SDA) 10 SDA
//
*/

View File

@ -66,7 +66,7 @@ void irqHandler(void *pvParameters) {
// do we have a power event? // do we have a power event?
#if (HAS_PMU) #if (HAS_PMU)
if (InterruptStatus & PMU_IRQ) if (InterruptStatus & PMU_IRQ)
pover_event_IRQ(); power_event_IRQ();
#endif #endif
// is time to send the payload? // is time to send the payload?

View File

@ -9,9 +9,12 @@ static const char TAG[] = __FILE__;
AXP20X_Class pmu; AXP20X_Class pmu;
void pover_event_IRQ(void) { void power_event_IRQ(void) {
// block i2c bus access
if (I2C_MUTEX_LOCK()) { if (!I2C_MUTEX_LOCK())
ESP_LOGW(TAG, "[%0.3f] i2c mutex lock failed", millis() / 1000.0);
else {
pmu.readIRQ(); pmu.readIRQ();
// put your power event handler code here // put your power event handler code here
@ -36,61 +39,63 @@ void pover_event_IRQ(void) {
if (pmu.isBattTempHighIRQ()) if (pmu.isBattTempHighIRQ())
ESP_LOGI(TAG, "Battery low temperature."); ESP_LOGI(TAG, "Battery low temperature.");
// wake up // display on/off
if (pmu.isPEKShortPressIRQ()) { if (pmu.isPEKShortPressIRQ()) {
ESP_LOGI(TAG, "Power Button short pressed."); cfg.screenon = !cfg.screenon;
AXP192_power(true);
} }
// enter sleep mode
// shutdown power
if (pmu.isPEKLongtPressIRQ()) { if (pmu.isPEKLongtPressIRQ()) {
ESP_LOGI(TAG, "Power Button long pressed."); AXP192_power(false); // switch off Lora, GPS, display
AXP192_power(false); pmu.shutdown();
delay(20);
esp_sleep_enable_ext1_wakeup(GPIO_SEL_38, ESP_EXT1_WAKEUP_ALL_LOW);
esp_deep_sleep_start();
} }
pmu.clearIRQ(); pmu.clearIRQ();
I2C_MUTEX_UNLOCK(); // release i2c bus access I2C_MUTEX_UNLOCK();
} else } // mutex
ESP_LOGI(TAG, "Unknown PMU event.");
// refresh stored voltage value
read_voltage();
} }
void AXP192_power(bool on) { void AXP192_power(bool on) {
if (on) { if (on) {
pmu.setPowerOutPut(AXP192_LDO2, AXP202_ON); // Lora on T-Beam V1.0 pmu.setPowerOutPut(AXP192_LDO2, AXP202_ON); // Lora on T-Beam V1.0
pmu.setPowerOutPut(AXP192_LDO3, AXP202_ON); // Gps on T-Beam V1.0 pmu.setPowerOutPut(AXP192_LDO3, AXP202_ON); // Gps on T-Beam V1.0
pmu.setPowerOutPut(AXP192_DCDC2, AXP202_ON); pmu.setPowerOutPut(AXP192_DCDC1, AXP202_ON); // OLED on T-Beam v1.0
pmu.setPowerOutPut(AXP192_EXTEN, AXP202_ON);
pmu.setPowerOutPut(AXP192_DCDC1, AXP202_ON);
// pmu.setChgLEDMode(AXP20X_LED_LOW_LEVEL); // pmu.setChgLEDMode(AXP20X_LED_LOW_LEVEL);
pmu.setChgLEDMode(AXP20X_LED_BLINK_1HZ); pmu.setChgLEDMode(AXP20X_LED_BLINK_1HZ);
} else { } else {
pmu.setChgLEDMode(AXP20X_LED_OFF);
pmu.setPowerOutPut(AXP192_DCDC1, AXP202_OFF); pmu.setPowerOutPut(AXP192_DCDC1, AXP202_OFF);
pmu.setPowerOutPut(AXP192_EXTEN, AXP202_OFF);
pmu.setPowerOutPut(AXP192_DCDC2, AXP202_OFF);
pmu.setPowerOutPut(AXP192_LDO3, AXP202_OFF); pmu.setPowerOutPut(AXP192_LDO3, AXP202_OFF);
pmu.setPowerOutPut(AXP192_LDO2, AXP202_OFF); pmu.setPowerOutPut(AXP192_LDO2, AXP202_OFF);
pmu.setChgLEDMode(AXP20X_LED_OFF);
} }
} }
void AXP192_displaypower(void) { void AXP192_showstatus(void) {
if (pmu.isBatteryConnect())
if (pmu.isChargeing())
ESP_LOGI(TAG, "Battery charging, %.2fV @ %.0fmAh",
pmu.getBattVoltage() / 1000, pmu.getBattChargeCurrent());
else
ESP_LOGI(TAG, "Battery not charging");
else
ESP_LOGI(TAG, "No Battery");
if (pmu.isVBUSPlug()) if (!I2C_MUTEX_LOCK())
ESP_LOGI(TAG, "USB present, %.2fV @ %.0fmA", pmu.getVbusVoltage() / 1000, ESP_LOGW(TAG, "[%0.3f] i2c mutex lock failed", millis() / 1000.0);
pmu.getVbusCurrent()); else {
else
ESP_LOGI(TAG, "USB not present"); if (pmu.isBatteryConnect())
if (pmu.isChargeing())
ESP_LOGI(TAG, "Battery charging, %.2fV @ %.0fmAh",
pmu.getBattVoltage() / 1000, pmu.getBattChargeCurrent());
else
ESP_LOGI(TAG, "Battery not charging");
else
ESP_LOGI(TAG, "No Battery");
if (pmu.isVBUSPlug())
ESP_LOGI(TAG, "USB powered, %.0fmW",
pmu.getVbusVoltage() / 1000 * pmu.getVbusCurrent());
else
ESP_LOGI(TAG, "USB not present");
I2C_MUTEX_UNLOCK();
} // mutex
} }
void AXP192_init(void) { void AXP192_init(void) {
@ -102,9 +107,10 @@ void AXP192_init(void) {
ESP_LOGI(TAG, "AXP192 PMU initialization failed"); ESP_LOGI(TAG, "AXP192 PMU initialization failed");
else { else {
// switch power on // configure AXP192
pmu.setDCDC1Voltage(3300); // for external OLED display pmu.setDCDC1Voltage(3300); // for external OLED display
AXP192_power(true); pmu.setTimeOutShutdown(false); // no automatic shutdown
pmu.setTSmode(AXP_TS_PIN_MODE_DISABLE); // TS pin mode off to save power
// switch ADCs on // switch ADCs on
pmu.adc1Enable(AXP202_BATT_VOL_ADC1, true); pmu.adc1Enable(AXP202_BATT_VOL_ADC1, true);
@ -112,8 +118,8 @@ void AXP192_init(void) {
pmu.adc1Enable(AXP202_VBUS_VOL_ADC1, true); pmu.adc1Enable(AXP202_VBUS_VOL_ADC1, true);
pmu.adc1Enable(AXP202_VBUS_CUR_ADC1, true); pmu.adc1Enable(AXP202_VBUS_CUR_ADC1, true);
// set TS pin mode off to save power // switch power rails on
pmu.setTSmode(AXP_TS_PIN_MODE_DISABLE); AXP192_power(true);
// I2C access of AXP202X library currently is not mutexable // I2C access of AXP202X library currently is not mutexable
// so we better should disable AXP interrupts... ? // so we better should disable AXP interrupts... ?
@ -121,13 +127,13 @@ void AXP192_init(void) {
pinMode(PMU_INT, INPUT_PULLUP); pinMode(PMU_INT, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(PMU_INT), PMUIRQ, FALLING); attachInterrupt(digitalPinToInterrupt(PMU_INT), PMUIRQ, FALLING);
pmu.enableIRQ(AXP202_VBUS_REMOVED_IRQ | AXP202_VBUS_CONNECT_IRQ | pmu.enableIRQ(AXP202_VBUS_REMOVED_IRQ | AXP202_VBUS_CONNECT_IRQ |
AXP202_BATT_REMOVED_IRQ | AXP202_BATT_CONNECT_IRQ, AXP202_BATT_REMOVED_IRQ | AXP202_BATT_CONNECT_IRQ |
AXP202_CHARGING_FINISHED_IRQ,
1); 1);
pmu.clearIRQ(); pmu.clearIRQ();
#endif // PMU_INT #endif // PMU_INT
ESP_LOGI(TAG, "AXP192 PMU initialized, chip temp %.1f°C", pmu.getTemp()); ESP_LOGI(TAG, "AXP192 PMU initialized");
AXP192_displaypower();
} }
I2C_MUTEX_UNLOCK(); // release i2c bus access I2C_MUTEX_UNLOCK(); // release i2c bus access
} else } else
@ -157,7 +163,7 @@ void calibrate_voltage(void) {
ESP_ERROR_CHECK(adc1_config_width(ADC_WIDTH_BIT_12)); ESP_ERROR_CHECK(adc1_config_width(ADC_WIDTH_BIT_12));
ESP_ERROR_CHECK(adc1_config_channel_atten(adc_channel, atten)); ESP_ERROR_CHECK(adc1_config_channel_atten(adc_channel, atten));
#else // ADC2 #else // ADC2
// ESP_ERROR_CHECK(adc2_config_width(ADC_WIDTH_BIT_12)); // ESP_ERROR_CHECK(adc2_config_width(ADC_WIDTH_BIT_12));
ESP_ERROR_CHECK(adc2_config_channel_atten(adc_channel, atten)); ESP_ERROR_CHECK(adc2_config_channel_atten(adc_channel, atten));
#endif #endif
// calibrate ADC // calibrate ADC
@ -187,11 +193,15 @@ bool batt_sufficient() {
} }
uint16_t read_voltage() { uint16_t read_voltage() {
uint16_t voltage = 0; uint16_t voltage = 0;
#ifdef HAS_PMU #ifdef HAS_PMU
voltage = pmu.isVBUSPlug() ? 0xffff : pmu.getBattVoltage(); if (!I2C_MUTEX_LOCK())
ESP_LOGW(TAG, "[%0.3f] i2c mutex lock failed", millis() / 1000.0);
else {
voltage = pmu.isVBUSPlug() ? 0xffff : pmu.getBattVoltage();
I2C_MUTEX_UNLOCK();
}
#else #else
#ifdef BAT_MEASURE_ADC #ifdef BAT_MEASURE_ADC