new oled driver (experimental)

This commit is contained in:
Verkehrsrot 2019-09-27 12:47:00 +02:00
parent cb67e368ba
commit 0f9e2dfd63
21 changed files with 190 additions and 222 deletions

View File

@ -1,16 +1,13 @@
#ifndef _DISPLAY_H
#define _DISPLAY_H
#include <U8x8lib.h>
#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

View File

@ -4,6 +4,7 @@
#ifdef USE_OTA
#include "globals.h"
#include <ss_oled.h>
#include <Update.h>
#include <WiFi.h>
#include <WiFiClientSecure.h>
@ -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

View File

@ -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 =

View File

@ -26,11 +26,11 @@ line 7: y = LMIC event message; ab = payload queue length
// Basic Config
#include "globals.h"
#include <ss_oled.h>
#include <esp_spi_flash.h> // 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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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)

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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)

View File

@ -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)

View File

@ -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

View File

@ -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); }

View File

@ -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