diff --git a/src/battery.cpp b/src/battery.cpp index 147e5d0b..454538a9 100644 --- a/src/battery.cpp +++ b/src/battery.cpp @@ -5,50 +5,48 @@ // Local logging tag static const char TAG[] = "main"; -static void print_char_val_type(esp_adc_cal_value_t val_type) { +esp_adc_cal_characteristics_t *adc_characs = + (esp_adc_cal_characteristics_t *)calloc( + 1, sizeof(esp_adc_cal_characteristics_t)); + +static const adc1_channel_t adc_channel = HAS_BATTERY_PROBE; +static const adc_atten_t atten = ADC_ATTEN_DB_11; +static const adc_unit_t unit = ADC_UNIT_1; + +void calibrate_voltage(void) { + // configure ADC + ESP_ERROR_CHECK(adc1_config_width(ADC_WIDTH_BIT_12)); + ESP_ERROR_CHECK(adc1_config_channel_atten(adc_channel, atten)); + // calibrate ADC + esp_adc_cal_value_t val_type = esp_adc_cal_characterize( + unit, atten, ADC_WIDTH_BIT_12, DEFAULT_VREF, adc_characs); + // show ADC characterization base if (val_type == ESP_ADC_CAL_VAL_EFUSE_TP) { - ESP_LOGD(TAG, + ESP_LOGI(TAG, "ADC characterization based on Two Point values stored in eFuse"); } else if (val_type == ESP_ADC_CAL_VAL_EFUSE_VREF) { - ESP_LOGD(TAG, + ESP_LOGI(TAG, "ADC characterization based on reference voltage stored in eFuse"); } else { - ESP_LOGD(TAG, "ADC characterization based on default reference voltage"); + ESP_LOGI(TAG, "ADC characterization based on default reference voltage"); } } -uint16_t read_voltage(void) { - static const adc1_channel_t channel = HAS_BATTERY_PROBE; - static const adc_atten_t atten = ADC_ATTEN_DB_11; - static const adc_unit_t unit = ADC_UNIT_1; - - // configure ADC1 - ESP_ERROR_CHECK(adc1_config_width(ADC_WIDTH_BIT_12)); - ESP_ERROR_CHECK(adc1_config_channel_atten(channel, atten)); - - // calibrate ADC1 - esp_adc_cal_characteristics_t *adc_chars = - (esp_adc_cal_characteristics_t *)calloc( - 1, sizeof(esp_adc_cal_characteristics_t)); - esp_adc_cal_value_t val_type = esp_adc_cal_characterize( - unit, atten, ADC_WIDTH_BIT_12, DEFAULT_VREF, adc_chars); - print_char_val_type(val_type); - - // multisample ADC1 +uint16_t read_voltage() { + // multisample ADC uint32_t adc_reading = 0; for (int i = 0; i < NO_OF_SAMPLES; i++) { - adc_reading += adc1_get_raw(channel); + adc_reading += adc1_get_raw(adc_channel); } - adc_reading /= NO_OF_SAMPLES; - - // Convert adc_reading to voltage in mV + // Convert ADC reading to voltage in mV uint16_t voltage = - (uint16_t)esp_adc_cal_raw_to_voltage(adc_reading, adc_chars); + (uint16_t)esp_adc_cal_raw_to_voltage(adc_reading, adc_characs); #ifdef BATT_FACTOR voltage *= BATT_FACTOR; #endif - ESP_LOGD(TAG, "Raw: %d / Voltage: %dmV", adc_reading, voltage); + ESP_LOGI(TAG, "Raw: %d / Voltage: %dmV", adc_reading, voltage); return voltage; } + #endif // HAS_BATTERY_PROBE \ No newline at end of file diff --git a/src/battery.h b/src/battery.h index d05dc9b1..93696fb5 100644 --- a/src/battery.h +++ b/src/battery.h @@ -5,8 +5,9 @@ #include #define DEFAULT_VREF 1100 // tbd: use adc2_vref_to_gpio() for better estimate -#define NO_OF_SAMPLES 64 // we do multisampling +#define NO_OF_SAMPLES 64 // we do some multisampling to get better values uint16_t read_voltage(void); +void calibrate_voltage(void); #endif diff --git a/src/display.cpp b/src/display.cpp index a5116041..52decae1 100644 --- a/src/display.cpp +++ b/src/display.cpp @@ -89,7 +89,7 @@ void init_display(const char *Productname, const char *Version) { } // init_display -void refreshDisplay() { +void refreshtheDisplay() { // set display on/off according to current device configuration if (DisplayState != cfg.screenon) { @@ -109,13 +109,11 @@ void refreshDisplay() { u8x8.draw2x2String(0, 0, buff); // display number on unique macs total Wifi + BLE -/* // update Battery status (line 2) #ifdef HAS_BATTERY_PROBE u8x8.setCursor(0, 2); - u8x8.printf("B:%.1fV", read_voltage() / 1000.0); + u8x8.printf("B:%.1fV", batt_voltage / 1000.0); #endif -*/ // update GPS status (line 2) #ifdef HAS_GPS diff --git a/src/display.h b/src/display.h index a444de7b..c88d9315 100644 --- a/src/display.h +++ b/src/display.h @@ -6,7 +6,7 @@ extern uint8_t DisplayState; void init_display(const char *Productname, const char *Version); -void refreshDisplay(void); +void refreshtheDisplay(void); void DisplayKey(const uint8_t *key, uint8_t len, bool lsb); #endif \ No newline at end of file diff --git a/src/globals.h b/src/globals.h index b02bc37a..10324461 100644 --- a/src/globals.h +++ b/src/globals.h @@ -40,8 +40,8 @@ typedef struct { extern configData_t cfg; // current device configuration extern char display_line6[], display_line7[]; // screen buffers extern uint8_t channel; // wifi channel rotation counter -extern uint16_t macs_total, macs_wifi, macs_ble; // display values -extern std::set macs; // temp storage for MACs +extern uint16_t macs_total, macs_wifi, macs_ble, batt_voltage; // display values +extern std::set macs; // temp storage for MACs extern hw_timer_t *channelSwitch, *sendCycle; extern portMUX_TYPE timerMux; diff --git a/src/main.cpp b/src/main.cpp index 55ba10d2..784fe0ad 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -30,13 +30,16 @@ licenses. Refer to LICENSE.txt file in repository for more details. configData_t cfg; // struct holds current device configuration char display_line6[16], display_line7[16]; // display buffers uint8_t channel = 0; // channel rotation counter -uint16_t macs_total = 0, macs_wifi = 0, macs_ble = 0; // globals for display -hw_timer_t *channelSwitch = NULL, *displaytimer = NULL, - *sendCycle = NULL; // configure hardware timer for cyclic tasks +uint16_t macs_total = 0, macs_wifi = 0, macs_ble = 0, + batt_voltage = 0; // globals for display + +// hardware timer for cyclic tasks +hw_timer_t *channelSwitch = NULL, *displaytimer = NULL, *sendCycle = NULL, + *battCycle = NULL; // this variables will be changed in the ISR, and read in main loop static volatile int ButtonPressedIRQ = 0, ChannelTimerIRQ = 0, - SendCycleTimerIRQ = 0, DisplayTimerIRQ = 0; + SendCycleTimerIRQ = 0, DisplayTimerIRQ = 0, BattReadIRQ = 0; portMUX_TYPE timerMux = portMUX_INITIALIZER_UNLOCKED; // sync main loop and ISR when modifying IRQ @@ -116,17 +119,30 @@ void IRAM_ATTR DisplayIRQ() { DisplayTimerIRQ++; portEXIT_CRITICAL_ISR(&timerMux); } - void updateDisplay() { - // refresh display according to refresh cycle setting if (DisplayTimerIRQ) { portENTER_CRITICAL(&timerMux); DisplayTimerIRQ = 0; portEXIT_CRITICAL(&timerMux); - refreshDisplay(); + refreshtheDisplay(); } } +#endif +#ifdef HAS_BATTERY_PROBE +void IRAM_ATTR BattCycleIRQ() { + portENTER_CRITICAL(&timerMux); + BattReadIRQ++; + portEXIT_CRITICAL(&timerMux); +} +void readBattery() { + if (BattReadIRQ) { + portENTER_CRITICAL(&timerMux); + BattReadIRQ = 0; + portEXIT_CRITICAL(&timerMux); + batt_voltage = read_voltage(); + } +} #endif #ifdef HAS_BUTTON @@ -313,6 +329,13 @@ void setup() { strcat_P(features, " GPS"); #endif +// initialize battery status if present +#ifdef HAS_BATTERY_PROBE + strcat_P(features, " BATT"); + calibrate_voltage(); + batt_voltage = read_voltage(); +#endif + // initialize display if present #ifdef HAS_DISPLAY strcat_P(features, " OLED"); @@ -344,6 +367,14 @@ void setup() { timerAlarmWrite(sendCycle, cfg.sendcycle * 2 * 10000, true); timerAlarmEnable(sendCycle); + // setup battery read cycle trigger IRQ using esp32 hardware timer 3 +#ifdef HAS_BATTERY_PROBE + battCycle = timerBegin(3, 8000, true); + timerAttachInterrupt(battCycle, &BattCycleIRQ, true); + timerAlarmWrite(battCycle, BATTREADCYCLE * 10000, true); + timerAlarmEnable(battCycle); +#endif + // show payload encoder #if PAYLOAD_ENCODER == 1 strcat_P(features, " PAYLOAD_PLAIN"); @@ -431,6 +462,10 @@ void loop() { readButton(); #endif +#ifdef HAS_BATTERY_PROBE + readBattery(); +#endif + #ifdef HAS_DISPLAY updateDisplay(); #endif diff --git a/src/paxcounter.conf b/src/paxcounter.conf index 14d76816..501cc1c2 100644 --- a/src/paxcounter.conf +++ b/src/paxcounter.conf @@ -58,11 +58,10 @@ #define BUTTONPORT 5 // Port on which device sends button pressed signal #define CAYENNEPORT 2 // Port for Cayenne LPP 2.0 packet sensor encoding -// Default RGB LED luminosity (in %) -#define RGBLUMINOSITY 30 // 30% - -// OLED Display refresh cycle (in Milliseconds) -#define DISPLAYREFRESH_MS 40 // e.g. 40ms -> 1000/40 = 25 frames per second +// Some hardware settings +#define RGBLUMINOSITY 30 // RGB LED luminosity [default = 30%] +#define DISPLAYREFRESH_MS 40 // OLED refresh cycle in ms [default = 40] -> 1000/40 = 25 frames per second +#define BATTREADCYCLE 60 // battery measuring cycle in seconds [default = 60 secs] // LMIC settings // define hardware independent LMIC settings here, settings of standard library in /lmic/config.h will be ignored