From 0f9e2dfd63ed7c9eea82c28b0c3bdb35fb224d02 Mon Sep 17 00:00:00 2001 From: Verkehrsrot Date: Fri, 27 Sep 2019 12:47:00 +0200 Subject: [PATCH] new oled driver (experimental) --- include/display.h | 5 +- include/ota.h | 7 +- platformio.ini | 5 +- src/display.cpp | 257 +++++++++++++++++--------------------- src/hal/ecopower.h | 4 +- src/hal/generic.h | 2 +- src/hal/heltec.h | 2 +- src/hal/heltecv2.h | 2 +- src/hal/lolin32litelora.h | 4 +- src/hal/lolin32lora.h | 4 +- src/hal/octopus32.h | 4 +- src/hal/ttgobeam.h | 4 +- src/hal/ttgobeam10.h | 4 +- src/hal/ttgofox.h | 4 +- src/hal/ttgov1.h | 2 +- src/hal/ttgov2.h | 4 +- src/hal/ttgov21new.h | 4 +- src/hal/ttgov21old.h | 4 +- src/hal/wemos32oled.h | 4 +- src/ota.cpp | 84 ++++++------- src/paxcounter.conf | 2 +- 21 files changed, 190 insertions(+), 222 deletions(-) diff --git a/include/display.h b/include/display.h index bbaa568c..90ea3f38 100644 --- a/include/display.h +++ b/include/display.h @@ -1,16 +1,13 @@ #ifndef _DISPLAY_H #define _DISPLAY_H -#include #include "cyclic.h" extern uint8_t DisplayIsOn; -extern HAS_DISPLAY u8x8; - void init_display(const char *Productname, const char *Version); void refreshTheDisplay(bool nextPage = false); void draw_page(time_t t, uint8_t page); -void DisplayKey(const uint8_t *key, uint8_t len, bool lsb); +void dp_printf(int x, int y, int font, int inv, const char *format, ...); #endif \ No newline at end of file diff --git a/include/ota.h b/include/ota.h index 59bf876c..cec28750 100644 --- a/include/ota.h +++ b/include/ota.h @@ -4,6 +4,7 @@ #ifdef USE_OTA #include "globals.h" +#include #include #include #include @@ -14,11 +15,9 @@ int do_ota_update(); void start_ota_update(); int version_compare(const String v1, const String v2); -void display(const uint8_t row, const std::string status, - const std::string msg); -#ifdef HAS_DISPLAY +void ota_display(const uint8_t row, const std::string status, + const std::string msg); void show_progress(unsigned long current, unsigned long size); -#endif #endif // USE_OTA diff --git a/platformio.ini b/platformio.ini index adfcc3e1..ded8baf9 100644 --- a/platformio.ini +++ b/platformio.ini @@ -43,7 +43,7 @@ description = Paxcounter is a device for metering passenger flows in realtime. I [common] ; for release_version use max. 10 chars total, use any decimal format like "a.b.c" -release_version = 1.8.34 +release_version = 1.8.4 ; 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 debug_level = 3 @@ -57,7 +57,8 @@ upload_speed = 115200 lib_deps_lora = MCCI LoRaWAN LMIC library@>=3.0.99 lib_deps_display = - U8g2@>=2.26.13 + ss_oled@>=2.1.1 + BitBang_I2C@>=1.2.0 lib_deps_matrix_display = https://github.com/Seeed-Studio/Ultrathin_LED_Matrix.git lib_deps_rgbled = diff --git a/src/display.cpp b/src/display.cpp index b89f551d..8db7eefa 100644 --- a/src/display.cpp +++ b/src/display.cpp @@ -26,11 +26,11 @@ line 7: y = LMIC event message; ab = payload queue length // Basic Config #include "globals.h" +#include #include // needed for reading ESP32 chip attributes #define DISPLAY_PAGES (4) // number of display pages - -HAS_DISPLAY u8x8(MY_OLED_RST, MY_OLED_SCL, MY_OLED_SDA); +#define USE_BACKBUFFER // for display library // helper arry for converting month values to text const char *printmonth[] = {"xxx", "Jan", "Feb", "Mar", "Apr", "May", "Jun", @@ -38,82 +38,63 @@ const char *printmonth[] = {"xxx", "Jan", "Feb", "Mar", "Apr", "May", "Jun", uint8_t DisplayIsOn = 0; -// helper function, prints a hex key on display -void DisplayKey(const uint8_t *key, uint8_t len, bool lsb) { - const uint8_t *p; - for (uint8_t i = 0; i < len; i++) { - p = lsb ? key + len - i - 1 : key + i; - u8x8.printf("%02X", *p); - } - u8x8.printf("\n"); -} - void init_display(const char *Productname, const char *Version) { // block i2c bus access if (!I2C_MUTEX_LOCK()) ESP_LOGV(TAG, "[%0.3f] i2c mutex lock failed", millis() / 1000.0); else { - // show startup screen - uint8_t buf[32]; - u8x8.begin(); - u8x8.setFont(u8x8_font_chroma48medium8_r); - u8x8.clear(); - u8x8.setFlipMode(0); - u8x8.setInverseFont(1); - u8x8.draw2x2String(0, 0, Productname); - u8x8.setInverseFont(0); - u8x8.draw2x2String(2, 2, Productname); - delay(500); - u8x8.clear(); - u8x8.setFlipMode(1); - u8x8.setInverseFont(1); - u8x8.draw2x2String(0, 0, Productname); - u8x8.setInverseFont(0); - u8x8.draw2x2String(2, 2, Productname); - delay(500); - u8x8.setFlipMode(0); - u8x8.clear(); - -#ifdef DISPLAY_FLIP - u8x8.setFlipMode(1); + // init display +#ifndef DISPLAY_FLIP + oledInit(OLED_128x64, ANGLE_0, false, -1, -1, 400000L); +#else + oledInit(OLED_128x64, ANGLE_FLIPY, false, -1, -1, 400000L); #endif -// Display chip information + // clear display + oledFill(0, 1); + + // show startup screen + // to come -> display .bmp file with logo + +// show chip information #if (VERBOSE) esp_chip_info_t chip_info; esp_chip_info(&chip_info); - u8x8.printf("ESP32 %d cores\nWiFi%s%s\n", chip_info.cores, - (chip_info.features & CHIP_FEATURE_BT) ? "/BT" : "", - (chip_info.features & CHIP_FEATURE_BLE) ? "/BLE" : ""); - u8x8.printf("ESP Rev.%d\n", chip_info.revision); - u8x8.printf("%dMB %s Flash\n", spi_flash_get_chip_size() / (1024 * 1024), - (chip_info.features & CHIP_FEATURE_EMB_FLASH) ? "int." - : "ext."); + dp_printf(0, 0, 0, 0, "ESP32 %d cores", chip_info.cores); + dp_printf(0, 2, 0, 0, "Chip Rev.%d", chip_info.revision); + dp_printf(0, 1, 0, 0, "WiFi%s%s", + (chip_info.features & CHIP_FEATURE_BT) ? "/BT" : "", + (chip_info.features & CHIP_FEATURE_BLE) ? "/BLE" : ""); + dp_printf(0, 3, 0, 0, "%dMB %s Flash", + spi_flash_get_chip_size() / (1024 * 1024), + (chip_info.features & CHIP_FEATURE_EMB_FLASH) ? "int." : "ext."); #endif // VERBOSE - u8x8.print(Productname); - u8x8.print(" v"); - u8x8.println(PROGVERSION); - #if (HAS_LORA) - u8x8.println("DEVEUI:"); + uint8_t buf[34]; + const uint8_t *p; os_getDevEui((u1_t *)buf); - DisplayKey(buf, 8, true); - delay(3000); + dp_printf(0, 5, 0, 0, "DEVEUI:"); + for (uint8_t i = 0; i < 8; i++) { + p = buf + 7 - i; + dp_printf(i * 16, 6, 0, 0, "%02X", *p); + } #endif // HAS_LORA - u8x8.clear(); - u8x8.setPowerSave(!cfg.screenon); // set display off if disabled - u8x8.draw2x2String(0, 0, "PAX:0"); + + dp_printf(0, 4, 0, 0, "Software v%s", PROGVERSION); + delay(3000); + + oledFill(0, 1); + oledPower(cfg.screenon); // set display off if disabled + dp_printf(0, 0, 1, 0, "PAX:0"); #if (BLECOUNTER) - u8x8.setCursor(0, 3); - u8x8.printf("BLTH:0"); + dp_printf(0, 3, 0, 0, "BLTH:0"); #endif - u8x8.setCursor(0, 4); - u8x8.printf("WIFI:0"); - u8x8.setCursor(0, 5); - u8x8.printf(!cfg.rssilimit ? "RLIM:off " : "RLIM:%d", cfg.rssilimit); + dp_printf(0, 4, 0, 0, "WIFI:0"); + dp_printf(0, 5, 0, 0, !cfg.rssilimit ? "RLIM:off " : "RLIM:%d", + cfg.rssilimit); I2C_MUTEX_UNLOCK(); // release i2c bus access } // mutex @@ -137,12 +118,12 @@ void refreshTheDisplay(bool nextPage) { // set display on/off according to current device configuration if (DisplayIsOn != cfg.screenon) { DisplayIsOn = cfg.screenon; - u8x8.setPowerSave(!cfg.screenon); + oledPower(cfg.screenon); } if (nextPage) { DisplayPage = (DisplayPage >= DISPLAY_PAGES - 1) ? 0 : (DisplayPage + 1); - u8x8.clear(); + oledFill(0, 1); } draw_page(t, DisplayPage); @@ -161,11 +142,8 @@ void draw_page(time_t t, uint8_t page) { #endif // update counter (lines 0-1) - snprintf( - buff, sizeof(buff), "PAX:%-4d", - (int)macs.size()); // convert 16-bit MAC counter to decimal counter value - u8x8.draw2x2String(0, 0, - buff); // display number on unique macs total Wifi + BLE + dp_printf(0, 0, FONT_STRETCHED, 0, "PAX:%-4d", + (int)macs.size()); // display number of unique macs total Wifi + BLE switch (page % DISPLAY_PAGES) { @@ -178,139 +156,108 @@ void draw_page(time_t t, uint8_t page) { // update Battery status (line 2) #if (defined BAT_MEASURE_ADC || defined HAS_PMU) - u8x8.setCursor(0, 2); if (batt_voltage == 0xffff) - u8x8.printf("B:USB "); + dp_printf(0, 2, 0, 0, "%s", "B:USB "); else - u8x8.printf("B:%.2fV", batt_voltage / 1000.0); + dp_printf(0, 2, 0, 0, "B:%.2fV", batt_voltage / 1000.0); #endif // update GPS status (line 2) #if (HAS_GPS) - u8x8.setCursor(9, 2); if (gps.location.age() < 1500) // if no fix then display Sats value inverse - u8x8.printf("Sats:%.2d", gps.satellites.value()); - else { - u8x8.setInverseFont(1); - u8x8.printf("Sats:%.2d", gps.satellites.value()); - u8x8.setInverseFont(0); - } + dp_printf(72, 2, 0, 0, "Sats:%.2d", gps.satellites.value()); + else + dp_printf(72, 2, 0, 1, "Sats:%.2d", gps.satellites.value()); #endif - // update bluetooth counter + LoRa SF (line 3) + // update bluetooth counter + LoRa SF (line 3) #if (BLECOUNTER) - u8x8.setCursor(0, 3); if (cfg.blescan) - u8x8.printf("BLTH:%-5d", macs_ble); + dp_printf(0, 3, 0, 0, "BLTH:%-5d", macs_ble); else - u8x8.printf("%s", "BLTH:off"); + dp_printf(0, 3, 0, 0, "%s", "BLTH:off"); #endif #if (HAS_LORA) - u8x8.setCursor(12, 3); - if (!cfg.adrmode) // if ADR=off then display SF value inverse - u8x8.setInverseFont(1); - u8x8.printf("%-4s", getSfName(updr2rps(LMIC.datarate))); - if (!cfg.adrmode) // switch off inverse if it was turned on - u8x8.setInverseFont(0); + if (cfg.adrmode) + dp_printf(96, 3, 0, 0, "%-4s", getSfName(updr2rps(LMIC.datarate))); + else // if ADR=off then display SF value inverse + dp_printf(96, 3, 0, 1, "%-4s", getSfName(updr2rps(LMIC.datarate))); #endif // HAS_LORA // line 4: update wifi counter + channel display - u8x8.setCursor(0, 4); - u8x8.printf("WIFI:%-5d", macs_wifi); - u8x8.setCursor(11, 4); - u8x8.printf("ch:%02d", channel); + dp_printf(0, 4, 0, 0, "WIFI:%-5d", macs_wifi); + dp_printf(88, 4, 0, 0, "ch:%02d", channel); // line 5: update RSSI limiter status & free memory display - u8x8.setCursor(0, 5); - u8x8.printf(!cfg.rssilimit ? "RLIM:off " : "RLIM:%-4d", cfg.rssilimit); - u8x8.setCursor(10, 5); - u8x8.printf("%4dKB", getFreeRAM() / 1024); + dp_printf(0, 5, 0, 0, !cfg.rssilimit ? "RLIM:off " : "RLIM:%-4d", + cfg.rssilimit); + dp_printf(80, 5, 0, 0, "%4dKB", getFreeRAM() / 1024); // line 6: update time-of-day or LoRa status display - u8x8.setCursor(0, 6); #if (TIME_SYNC_INTERVAL) // we want a systime display instead LoRa status timeState = TimePulseTick ? ' ' : timeSetSymbols[timeSource]; TimePulseTick = false; // display inverse timeState if clock controller is enabled #if (defined HAS_DCF77) || (defined HAS_IF482) - u8x8.printf("%02d:%02d:%02d", hour(t), minute(t), second(t)); - u8x8.setInverseFont(1); - u8x8.printf("%c", timeState); - u8x8.setInverseFont(0); + dp_printf(0, 6, FONT_SMALL, 0, "%02d:%02d:%02d", hour(t), minute(t), + second(t)); + dp_printf(56, 6, FONT_SMALL, 1, "%c", timeState); #else - u8x8.printf("%02d:%02d:%02d%c", hour(t), minute(t), second(t), timeState); + dp_printf(0, 6, FONT_SMALL, 0, "%02d:%02d:%02d%c", hour(t), minute(t), + second(t), timeState); #endif // HAS_DCF77 || HAS_IF482 if (timeSource != _unsynced) - u8x8.printf(" %2d.%3s", day(t), printmonth[month(t)]); + dp_printf(72, 6, FONT_SMALL, 0, " %2d.%3s%4s", day(t), + printmonth[month(t)], year(t)); #endif // TIME_SYNC_INTERVAL #if (HAS_LORA) // line 7: update LMiC event display - u8x8.setCursor(0, 7); - u8x8.printf("%-14s", lmic_event_msg); + dp_printf(0, 7, FONT_SMALL, 0, "%-14s", lmic_event_msg); // update LoRa send queue display msgWaiting = uxQueueMessagesWaiting(LoraSendQueue); if (msgWaiting) { sprintf(buff, "%2d", msgWaiting); - u8x8.setCursor(14, 7); - u8x8.printf("%-2s", msgWaiting == SEND_QUEUE_SIZE ? "<>" : buff); + dp_printf(112, 7, FONT_SMALL, 0, "%-2s", + msgWaiting == SEND_QUEUE_SIZE ? "<>" : buff); } else - u8x8.printf(" "); + dp_printf(112, 7, FONT_SMALL, 0, " "); #endif // HAS_LORA break; // page0 case 1: - - // line 4-5: update time-of-day - snprintf(buff, sizeof(buff), "%02d:%02d:%02d", hour(t), minute(t), - second(t)); - u8x8.draw2x2String(0, 4, buff); - + dp_printf(0, 4, FONT_STRETCHED, 0, "%02d:%02d:%02d", hour(t), minute(t), + second(t)); break; // page1 case 2: - // update counter (lines 0-1) - snprintf( - buff, sizeof(buff), "PAX:%-4d", - (int) - macs.size()); // convert 16-bit MAC counter to decimal counter value - u8x8.draw2x2String(0, 0, - buff); // display number on unique macs total Wifi + BLE - #if (HAS_GPS) if (gps.location.age() < 1500) { // line 5: clear "No fix" if (wasnofix) { - snprintf(buff, sizeof(buff), " "); - u8x8.draw2x2String(2, 5, buff); + dp_printf(16, 5, FONT_STRETCHED, 0, " "); wasnofix = false; } // line 3-4: GPS latitude - snprintf(buff, sizeof(buff), "%c%07.4f", - gps.location.rawLat().negative ? 'S' : 'N', gps.location.lat()); - u8x8.draw2x2String(0, 3, buff); + dp_printf(0, 3, FONT_STRETCHED, 0, "%c%07.4f", + gps.location.rawLat().negative ? 'S' : 'N', gps.location.lat()); // line 6-7: GPS longitude - snprintf(buff, sizeof(buff), "%c%07.4f", - gps.location.rawLat().negative ? 'W' : 'E', gps.location.lng()); - u8x8.draw2x2String(0, 6, buff); + dp_printf(0, 6, FONT_STRETCHED, 0, "%c%07.4f", + gps.location.rawLat().negative ? 'W' : 'E', gps.location.lng()); } else { - snprintf(buff, sizeof(buff), "No fix"); - u8x8.setInverseFont(1); - u8x8.draw2x2String(2, 5, buff); - u8x8.setInverseFont(0); + dp_printf(16, 5, FONT_STRETCHED, 1, "No fix"); wasnofix = true; } #else - snprintf(buff, sizeof(buff), "No GPS"); - u8x8.draw2x2String(2, 5, buff); + dp_printf(16, 5, FONT_STRETCHED, 1, "No GPS"); #endif break; // page2 @@ -319,22 +266,18 @@ void draw_page(time_t t, uint8_t page) { #if (HAS_BME) // line 2-3: Temp - snprintf(buff, sizeof(buff), "TMP:%-2.1f", bme_status.temperature); - u8x8.draw2x2String(0, 2, buff); + dp_printf(0, 2, FONT_STRETCHED, 0, "TMP:%-2.1f", bme_status.temperature); // line 4-5: Hum - snprintf(buff, sizeof(buff), "HUM:%-2.1f", bme_status.humidity); - u8x8.draw2x2String(0, 4, buff); + dp_printf(0, 4, FONT_STRETCHED, 0, "HUM:%-2.1f", bme_status.humidity); #ifdef HAS_BME680 // line 6-7: IAQ - snprintf(buff, sizeof(buff), "IAQ:%-3.0f", bme_status.iaq); - u8x8.draw2x2String(0, 6, buff); + dp_printf(0, 6, FONT_STRETCHED, 0, "IAQ:%-3.0f", bme_status.iaq); #endif #else - snprintf(buff, sizeof(buff), "No BME"); - u8x8.draw2x2String(2, 5, buff); + dp_printf(16, 5, FONT_STRETCHED, 1, "No BME"); #endif break; // page3 @@ -346,4 +289,34 @@ void draw_page(time_t t, uint8_t page) { } // draw_page +// display print helper function + +void dp_printf(int x, int y, int font, int inv, const char *format, ...) { + char loc_buf[64]; + char *temp = loc_buf; + va_list arg; + va_list copy; + va_start(arg, format); + va_copy(copy, arg); + int len = vsnprintf(temp, sizeof(loc_buf), format, copy); + va_end(copy); + if (len < 0) { + va_end(arg); + return; + }; + if (len >= sizeof(loc_buf)) { + temp = (char *)malloc(len + 1); + if (temp == NULL) { + va_end(arg); + return; + } + len = vsnprintf(temp, len + 1, format, arg); + } + va_end(arg); + oledWriteString(0, x, y, temp, font, inv, 1); + if (temp != loc_buf) { + free(temp); + } +} + #endif // HAS_DISPLAY \ No newline at end of file diff --git a/src/hal/ecopower.h b/src/hal/ecopower.h index 4f4b303a..deca82d7 100644 --- a/src/hal/ecopower.h +++ b/src/hal/ecopower.h @@ -12,7 +12,7 @@ //#define DISABLE_BROWNOUT 1 // comment out if you want to keep brownout feature -#define HAS_DISPLAY U8X8_SSD1306_128X64_NONAME_HW_I2C +#define HAS_DISPLAY 1 //#define DISPLAY_FLIP 1 // use if display is rotated #define BAT_MEASURE_ADC ADC1_GPIO35_CHANNEL // battery probe GPIO pin -> ADC1_CHANNEL_7 #define BAT_VOLTAGE_DIVIDER ((82.0+220.0)/82.0) // 82k + 220k 1% @@ -29,7 +29,7 @@ // Pins for I2C interface of OLED Display #define MY_OLED_SDA SDA #define MY_OLED_SCL SCL -#define MY_OLED_RST U8X8_PIN_NONE +#define MY_OLED_RST NOT_A_PIN // Settings for on board DS3231 RTC chip // note: to use RTC_INT, capacitor 100nF next to red LED must be removed to sharpen interrupt signal slope diff --git a/src/hal/generic.h b/src/hal/generic.h index c606e5ba..909bef38 100644 --- a/src/hal/generic.h +++ b/src/hal/generic.h @@ -44,7 +44,7 @@ #define BOARD_HAS_PSRAM // use if board has external PSRAM #define DISABLE_BROWNOUT 1 // comment out if you want to keep brownout feature -#define HAS_DISPLAY U8X8_SSD1306_128X64_NONAME_HW_I2C +#define HAS_DISPLAY 1 //#define DISPLAY_FLIP 1 // use if display is rotated #define BAT_MEASURE_ADC ADC1_GPIO35_CHANNEL // battery probe GPIO pin -> ADC1_CHANNEL_7 #define BAT_VOLTAGE_DIVIDER 2 // voltage divider 100k/100k on board diff --git a/src/hal/heltec.h b/src/hal/heltec.h index 465793a1..4432c9a3 100644 --- a/src/hal/heltec.h +++ b/src/hal/heltec.h @@ -16,7 +16,7 @@ #define HAS_LORA 1 // comment out if device shall not send data via LoRa #define CFG_sx1276_radio 1 -#define HAS_DISPLAY U8X8_SSD1306_128X64_NONAME_HW_I2C // OLED-Display on board +#define HAS_DISPLAY 1 // OLED-Display on board #define HAS_LED LED_BUILTIN // white LED on board #define HAS_BUTTON KEY_BUILTIN // button "PROG" on board diff --git a/src/hal/heltecv2.h b/src/hal/heltecv2.h index adb74981..96024e38 100644 --- a/src/hal/heltecv2.h +++ b/src/hal/heltecv2.h @@ -16,7 +16,7 @@ #define HAS_LORA 1 // comment out if device shall not send data via LoRa #define CFG_sx1276_radio 1 -#define HAS_DISPLAY U8X8_SSD1306_128X64_NONAME_HW_I2C // OLED-Display on board +#define HAS_DISPLAY 1 // OLED-Display on board #define HAS_LED LED_BUILTIN // white LED on board #define HAS_BUTTON KEY_BUILTIN // button "PROG" on board diff --git a/src/hal/lolin32litelora.h b/src/hal/lolin32litelora.h index 11f3f156..07af6837 100644 --- a/src/hal/lolin32litelora.h +++ b/src/hal/lolin32litelora.h @@ -13,7 +13,7 @@ // disable brownout detection (avoid unexpected reset on some boards) #define DISABLE_BROWNOUT 1 // comment out if you want to keep brownout feature -#define HAS_DISPLAY U8X8_SSD1306_128X64_NONAME_HW_I2C // OLED-Display on board +#define HAS_DISPLAY 1 // OLED-Display on board //#define DISPLAY_FLIP 1 // uncomment this for rotated display #define HAS_LED 22 // ESP32 GPIO12 (pin22) On Board LED #define LED_ACTIVE_LOW 1 // Onboard LED is active when pin is LOW @@ -37,7 +37,7 @@ // Pins for I2C interface of OLED Display #define MY_OLED_SDA (14) #define MY_OLED_SCL (12) -#define MY_OLED_RST U8X8_PIN_NONE +#define MY_OLED_RST NOT_A_PIN // I2C config for Microchip 24AA02E64 DEVEUI unique address #define MCP_24AA02E64_I2C_ADDRESS 0x50 // I2C address for the 24AA02E64 diff --git a/src/hal/lolin32lora.h b/src/hal/lolin32lora.h index a79b0d84..a14c9605 100644 --- a/src/hal/lolin32lora.h +++ b/src/hal/lolin32lora.h @@ -13,7 +13,7 @@ // disable brownout detection (avoid unexpected reset on some boards) #define DISABLE_BROWNOUT 1 // comment out if you want to keep brownout feature -#define HAS_DISPLAY U8X8_SSD1306_128X64_NONAME_HW_I2C // OLED-Display on board +#define HAS_DISPLAY 1 // OLED-Display on board //#define DISPLAY_FLIP 1 // uncomment this for rotated display #define HAS_LED NOT_A_PIN // Led os on same pin as Lora SS pin, to avoid problems, we don't use it #define LED_ACTIVE_LOW 1 // Onboard LED is active when pin is LOW @@ -39,7 +39,7 @@ // Pins for I2C interface of OLED Display #define MY_OLED_SDA (21) #define MY_OLED_SCL (22) -#define MY_OLED_RST U8X8_PIN_NONE +#define MY_OLED_RST NOT_A_PIN // I2C config for Microchip 24AA02E64 DEVEUI unique address #define MCP_24AA02E64_I2C_ADDRESS 0x50 // I2C address for the 24AA02E64 diff --git a/src/hal/octopus32.h b/src/hal/octopus32.h index d245a8c2..f34f609b 100644 --- a/src/hal/octopus32.h +++ b/src/hal/octopus32.h @@ -41,10 +41,10 @@ #define LORA_IO2 LMIC_UNUSED_PIN // Pins for I2C interface of OLED Display -#define HAS_DISPLAY U8X8_SSD1306_128X64_NONAME_HW_I2C // U8X8_SSD1306_128X32_UNIVISION_SW_I2C // +#define HAS_DISPLAY 1 //#define DISPLAY_FLIP 1 // uncomment this for rotated display #define MY_OLED_SDA (23) #define MY_OLED_SCL (22) -#define MY_OLED_RST U8X8_PIN_NONE +#define MY_OLED_RST NOT_A_PIN #endif diff --git a/src/hal/ttgobeam.h b/src/hal/ttgobeam.h index f8be7ee0..a4d81926 100644 --- a/src/hal/ttgobeam.h +++ b/src/hal/ttgobeam.h @@ -33,10 +33,10 @@ #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 HAS_DISPLAY 1 #define MY_OLED_SDA SDA #define MY_OLED_SCL SCL -#define MY_OLED_RST U8X8_PIN_NONE +#define MY_OLED_RST NOT_A_PIN //#define DISPLAY_FLIP 1 // use if display is rotated // user defined sensors (if connected) diff --git a/src/hal/ttgobeam10.h b/src/hal/ttgobeam10.h index fa0b3ffa..35bd78da 100644 --- a/src/hal/ttgobeam10.h +++ b/src/hal/ttgobeam10.h @@ -20,10 +20,10 @@ User, long press -> send LORA message Reset -> reset device */ -//#define HAS_DISPLAY U8X8_SSD1306_128X64_NONAME_HW_I2C +#define HAS_DISPLAY 1 #define MY_OLED_SDA SDA #define MY_OLED_SCL SCL -#define MY_OLED_RST U8X8_PIN_NONE +#define MY_OLED_RST NOT_A_PIN //#define DISPLAY_FLIP 1 // use if display is rotated #define HAS_LORA 1 // comment out if device shall not send data via LoRa diff --git a/src/hal/ttgofox.h b/src/hal/ttgofox.h index 94b2b60f..8a7e3a9c 100644 --- a/src/hal/ttgofox.h +++ b/src/hal/ttgofox.h @@ -10,7 +10,7 @@ #define HAS_LORA 1 // comment out if device shall not send data via LoRa #define CFG_sx1276_radio 1 // HPD13A LoRa SoC -#define HAS_DISPLAY U8X8_SSD1306_128X64_NONAME_HW_I2C +#define HAS_DISPLAY 1 #define HAS_LED NOT_A_PIN // green on board LED is useless, is GPIO25, which switches power for Lora+Display #define EXT_POWER_SW GPIO_NUM_25 // switches power for LoRa chip @@ -23,7 +23,7 @@ // Pins for I2C interface of OLED Display #define MY_OLED_SDA (21) #define MY_OLED_SCL (22) -#define MY_OLED_RST U8X8_PIN_NONE +#define MY_OLED_RST NOT_A_PIN // Settings for on board DS3231 RTC chip #define HAS_RTC MY_OLED_SDA, MY_OLED_SCL // SDA, SCL diff --git a/src/hal/ttgov1.h b/src/hal/ttgov1.h index fddc3ef5..1aaf20c3 100644 --- a/src/hal/ttgov1.h +++ b/src/hal/ttgov1.h @@ -12,7 +12,7 @@ #define HAS_LORA 1 // comment out if device shall not send data via LoRa #define CFG_sx1276_radio 1 -#define HAS_DISPLAY U8X8_SSD1306_128X64_NONAME_HW_I2C // OLED-Display on board +#define HAS_DISPLAY 1 // OLED-Display on board //#define DISPLAY_FLIP 1 // uncomment this for rotated display #define HAS_LED LED_BUILTIN #define LED_ACTIVE_LOW 1 // Onboard LED is active when pin is LOW diff --git a/src/hal/ttgov2.h b/src/hal/ttgov2.h index 54f1657a..e5e784f3 100644 --- a/src/hal/ttgov2.h +++ b/src/hal/ttgov2.h @@ -12,7 +12,7 @@ #define HAS_LORA 1 // comment out if device shall not send data via LoRa #define CFG_sx1276_radio 1 // HPD13A LoRa SoC -#define HAS_DISPLAY U8X8_SSD1306_128X64_NONAME_HW_I2C +#define HAS_DISPLAY 1 //#define DISPLAY_FLIP 1 // uncomment this for rotated display #define HAS_LED NOT_A_PIN // on-board LED is wired to SCL (used by display) therefore totally useless @@ -22,7 +22,7 @@ // Pins for I2C interface of OLED Display #define MY_OLED_SDA (21) #define MY_OLED_SCL (22) -#define MY_OLED_RST U8X8_PIN_NONE +#define MY_OLED_RST NOT_A_PIN // Pins for LORA chip SPI interface come from board file, we need some // additional definitions for LMIC diff --git a/src/hal/ttgov21new.h b/src/hal/ttgov21new.h index c50869b2..4c1cd4fc 100644 --- a/src/hal/ttgov21new.h +++ b/src/hal/ttgov21new.h @@ -20,7 +20,7 @@ //#define HAS_BME 1 // Enable BME sensors in general //#define HAS_BME280 GPIO_NUM_21, GPIO_NUM_22 // SDA, SCL -#define HAS_DISPLAY U8X8_SSD1306_128X64_NONAME_HW_I2C +#define HAS_DISPLAY 1 #define HAS_LED (25) // green on board LED #define BAT_MEASURE_ADC ADC1_GPIO35_CHANNEL // battery probe GPIO pin -> ADC1_CHANNEL_7 #define BAT_VOLTAGE_DIVIDER 2 // voltage divider 100k/100k on board @@ -28,7 +28,7 @@ // Pins for I2C interface of OLED Display #define MY_OLED_SDA (21) #define MY_OLED_SCL (22) -#define MY_OLED_RST U8X8_PIN_NONE +#define MY_OLED_RST NOT_A_PIN // Pins for LORA chip SPI interface, reset line and interrupt lines #define LORA_SCK (5) diff --git a/src/hal/ttgov21old.h b/src/hal/ttgov21old.h index 0a7c386c..a19887ca 100644 --- a/src/hal/ttgov21old.h +++ b/src/hal/ttgov21old.h @@ -19,7 +19,7 @@ #define HAS_LED NOT_A_PIN // no usable LED on board #define DISABLE_BROWNOUT 1 // comment out if you want to keep brownout feature -#define HAS_DISPLAY U8X8_SSD1306_128X64_NONAME_HW_I2C +#define HAS_DISPLAY 1 //#define DISPLAY_FLIP 1 // rotated display //#define BAT_MEASURE_ADC ADC1_GPIO35_CHANNEL // battery probe GPIO pin -> ADC1_CHANNEL_7 //#define BAT_VOLTAGE_DIVIDER 2 // voltage divider 100k/100k on board @@ -27,7 +27,7 @@ // Pins for I2C interface of OLED Display #define MY_OLED_SDA (21) #define MY_OLED_SCL (22) -#define MY_OLED_RST U8X8_PIN_NONE +#define MY_OLED_RST NOT_A_PIN // Pins for LORA chip SPI interface, reset line and interrupt lines #define LORA_SCK (5) diff --git a/src/hal/wemos32oled.h b/src/hal/wemos32oled.h index 3b59e450..2955fbaa 100644 --- a/src/hal/wemos32oled.h +++ b/src/hal/wemos32oled.h @@ -9,10 +9,10 @@ #define HAS_LED NOT_A_PIN // no LED -#define HAS_DISPLAY U8X8_SSD1306_128X64_NONAME_HW_I2C +#define HAS_DISPLAY 1 #define MY_OLED_SDA (5) #define MY_OLED_SCL (4) -#define MY_OLED_RST U8X8_PIN_NONE +#define MY_OLED_RST NOT_A_PIN #define DISPLAY_FLIP 1 // use if display is rotated #define DISABLE_BROWNOUT 1 // comment out if you want to keep brownout feature diff --git a/src/ota.cpp b/src/ota.cpp index fc1662bc..e05b6f8f 100644 --- a/src/ota.cpp +++ b/src/ota.cpp @@ -49,24 +49,24 @@ void start_ota_update() { switch_LED(LED_ON); #ifdef HAS_DISPLAY - u8x8.begin(); - u8x8.setFont(u8x8_font_chroma48medium8_r); - u8x8.clear(); -#ifdef DISPLAY_FLIP - u8x8.setFlipMode(1); -#endif - u8x8.setInverseFont(1); - u8x8.print("SOFTWARE UPDATE \n"); - u8x8.setInverseFont(0); - u8x8.print("WiFi connect ..\n"); - u8x8.print("Has Update? ..\n"); - u8x8.print("Fetching ..\n"); - u8x8.print("Downloading ..\n"); - u8x8.print("Rebooting .."); + +// init display +#ifndef DISPLAY_FLIP + int rc = oledInit(OLED_128x64, ANGLE_0, false, -1, -1, 100000L); +#else + int rc = oledInit(OLED_128x64, ANGLE_FLIPY, false, -1, -1, 100000L); #endif + oledFill(0, 1); + dp_printf(0, 0, 0, 1, "SOFTWARE UPDATE"); + dp_printf(0, 1, 0, 0, "WiFi connect .."); + dp_printf(0, 2, 0, 0, "Has Update? .."); + dp_printf(0, 3, 0, 0, "Fetching .."); + dp_printf(0, 4, 0, 0, "Downloading .."); + dp_printf(0, 5, 0, 0, "Rebooting .."); + ESP_LOGI(TAG, "Starting Wifi OTA update"); - display(1, "**", WIFI_SSID); + ota_display(1, "**", WIFI_SSID); WiFi.mode(WIFI_STA); WiFi.begin(WIFI_SSID, WIFI_PASS); @@ -81,7 +81,7 @@ void start_ota_update() { if (WiFi.status() == WL_CONNECTED) { // we now have wifi connection and try to do an OTA over wifi update ESP_LOGI(TAG, "Connected to %s", WIFI_SSID); - display(1, "OK", "WiFi connected"); + ota_display(1, "OK", "WiFi connected"); // do a number of tries to update firmware limited by OTA_MAX_TRY uint8_t j = OTA_MAX_TRY; while ((j--) && (ret > 0)) { @@ -97,13 +97,13 @@ void start_ota_update() { // wifi did not connect ESP_LOGI(TAG, "Could not connect to %s", WIFI_SSID); - display(1, " E", "no WiFi connect"); + ota_display(1, " E", "no WiFi connect"); delay(5000); end: switch_LED(LED_OFF); ESP_LOGI(TAG, "Rebooting to %s firmware", (ret == 0) ? "new" : "current"); - display(5, "**", ""); // mark line rebooting + ota_display(5, "**", ""); // mark line rebooting delay(5000); ESP.restart(); @@ -119,7 +119,7 @@ int do_ota_update() { // Fetch the latest firmware version ESP_LOGI(TAG, "Checking latest firmware version on server"); - display(2, "**", "checking version"); + ota_display(2, "**", "checking version"); if (WiFi.status() != WL_CONNECTED) return 1; @@ -128,23 +128,23 @@ int do_ota_update() { if (latest.length() == 0) { ESP_LOGI(TAG, "Could not fetch info on latest firmware"); - display(2, " E", "file not found"); + ota_display(2, " E", "file not found"); return -1; } else if (version_compare(latest, cfg.version) <= 0) { ESP_LOGI(TAG, "Current firmware is up to date"); - display(2, "NO", "no update found"); + ota_display(2, "NO", "no update found"); return -1; } ESP_LOGI(TAG, "New firmware version v%s available", latest.c_str()); - display(2, "OK", latest.c_str()); + ota_display(2, "OK", latest.c_str()); - display(3, "**", ""); + ota_display(3, "**", ""); if (WiFi.status() != WL_CONNECTED) return 1; String firmwarePath = bintray.getBinaryPath(latest); if (!firmwarePath.endsWith(".bin")) { ESP_LOGI(TAG, "Unsupported binary format"); - display(3, " E", "file type error"); + ota_display(3, " E", "file type error"); return -1; } @@ -158,7 +158,7 @@ int do_ota_update() { if (!client.connect(currentHost.c_str(), port)) { ESP_LOGI(TAG, "Cannot connect to %s", currentHost.c_str()); - display(3, " E", "connection lost"); + ota_display(3, " E", "connection lost"); goto abort; } @@ -169,7 +169,7 @@ int do_ota_update() { if (!client.connect(currentHost.c_str(), port)) { ESP_LOGI(TAG, "Redirect detected, but cannot connect to %s", currentHost.c_str()); - display(3, " E", "server error"); + ota_display(3, " E", "server error"); goto abort; } } @@ -185,7 +185,7 @@ int do_ota_update() { while (client.available() == 0) { if ((millis() - timeout) > (RESPONSE_TIMEOUT_MS)) { ESP_LOGI(TAG, "Client timeout"); - display(3, " E", "client timeout"); + ota_display(3, " E", "client timeout"); goto abort; } } @@ -243,12 +243,12 @@ int do_ota_update() { } // while (client.available()) } // while (redirect) - display(3, "OK", ""); // line download + ota_display(3, "OK", ""); // line download // check whether we have everything for OTA update if (!(contentLength && isValidContentType)) { ESP_LOGI(TAG, "Invalid OTA server response"); - display(4, " E", "response error"); + ota_display(4, " E", "response error"); goto retry; } @@ -262,7 +262,7 @@ int do_ota_update() { if (!Update.begin(contentLength)) { #endif ESP_LOGI(TAG, "Not enough space to start OTA update"); - display(4, " E", "disk full"); + ota_display(4, " E", "disk full"); goto abort; } @@ -271,13 +271,13 @@ int do_ota_update() { Update.onProgress(&show_progress); #endif - display(4, "**", "writing..."); + ota_display(4, "**", "writing..."); written = Update.writeStream(client); // this is a blocking call if (written == contentLength) { ESP_LOGI(TAG, "Written %u bytes successfully", written); snprintf(buf, 17, "%ukB Done!", (uint16_t)(written / 1024)); - display(4, "OK", buf); + ota_display(4, "OK", buf); } else { ESP_LOGI(TAG, "Written only %u of %u bytes, OTA update attempt cancelled", written, contentLength); @@ -288,7 +288,7 @@ int do_ota_update() { } else { ESP_LOGI(TAG, "An error occurred. Error#: %d", Update.getError()); snprintf(buf, 17, "Error#: %d", Update.getError()); - display(4, " E", buf); + ota_display(4, " E", buf); goto retry; } @@ -307,27 +307,25 @@ retry: } // do_ota_update -void display(const uint8_t row, const std::string status, - const std::string msg) { +void ota_display(const uint8_t row, const std::string status, + const std::string msg) { #ifdef HAS_DISPLAY - u8x8.setCursor(14, row); - u8x8.print((status.substr(0, 2)).c_str()); + dp_printf(112, row, 0, 0, status.substr(0, 2).c_str()); if (!msg.empty()) { - u8x8.clearLine(7); - u8x8.setCursor(0, 7); - u8x8.print(msg.substr(0, 16).c_str()); + dp_printf(0, 7, 0, 0, " "); + dp_printf(0, 7, 0, 0, msg.substr(0, 16).c_str()); } #endif } -#ifdef HAS_DISPLAY // callback function to show download progress while streaming data void show_progress(unsigned long current, unsigned long size) { +#ifdef HAS_DISPLAY char buf[17]; snprintf(buf, 17, "%-9lu (%3lu%%)", current, current * 100 / size); - display(4, "**", buf); -} + ota_display(4, "**", buf); #endif +} // helper function to convert strings into lower case bool comp(char s1, char s2) { return tolower(s1) < tolower(s2); } diff --git a/src/paxcounter.conf b/src/paxcounter.conf index 38feccc3..79943454 100644 --- a/src/paxcounter.conf +++ b/src/paxcounter.conf @@ -76,7 +76,7 @@ #define TIME_SYNC_INTERVAL_RETRY 10 // retry time sync after lost sync each .. minutes [default = 10], 0 means off #define TIME_SYNC_COMPILEDATE 0 // set to 1 to use compile date to initialize RTC after power outage [default = 0] #define TIME_SYNC_LORAWAN 0 // set to 1 to use LORA network as time source, 0 means off [default = 0] -#define TIME_SYNC_LORASERVER 0 // set to 1 to use LORA timeserver as time source, 0 means off [default = 0] +#define TIME_SYNC_LORASERVER 1 // set to 1 to use LORA timeserver as time source, 0 means off [default = 0] // settings for syncing time with timeserver applications #define TIME_SYNC_SAMPLES 1 // number of time requests for averaging