34 files changed
+581
-388
No files matched your search
@@ -20,7 +20,7 @@ void defaultConfig() {
|
||||
cfg.adrmode = 1; // 0=disabled, 1=enabled
|
||||
cfg.screensaver = 0; // 0=disabled, 1=enabled
|
||||
cfg.screenon = 1; // 0=disabled, 1=enabled
|
||||
cfg.countermode = 0; // 0=cyclic, 1=cumulative, 2=cyclic confirmed
|
||||
cfg.countermode = COUNTERMODE; // 0=cyclic, 1=cumulative, 2=cyclic confirmed
|
||||
cfg.rssilimit = 0; // threshold for rssilimiter, negative value!
|
||||
cfg.sendcycle = SENDCYCLE; // payload send cycle [seconds/2]
|
||||
cfg.wifichancycle =
|
||||
|
||||
@@ -128,5 +128,9 @@ void reset_counters() {
|
||||
macs_total = 0; // reset all counters
|
||||
macs_wifi = 0;
|
||||
macs_ble = 0;
|
||||
#ifdef HAS_DISPLAY
|
||||
oledPlotCurve(0, true);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
}
|
||||
+321
-189
@@ -4,116 +4,134 @@
|
||||
|
||||
Display-Mask (128 x 64 pixel):
|
||||
|
||||
| 111111
|
||||
|0123456789012345
|
||||
------------------
|
||||
0|PAX:aabbccddee
|
||||
1|PAX:aabbccddee
|
||||
2|B:a.bcV Sats:ab
|
||||
3|BLTH:abcde SFab
|
||||
4|WIFI:abcde ch:ab
|
||||
5|RLIM:abcd abcdKB
|
||||
6|20:27:00* 27.Feb
|
||||
7|yyyyyyyyyyyyyyab
|
||||
| | |
|
||||
| 11111111112
|
||||
|012345678901234567890 Font
|
||||
----------------------- ---------
|
||||
0|PAX:aabbccdd STRETCHED
|
||||
1|PAX:aabbccdd STRETCHED
|
||||
2|
|
||||
3|B:a.bcV Sats:ab ch:ab SMALL
|
||||
4|WIFI:abcde BLTH:abcde SMALL
|
||||
5|RLIM:abcd Mem:abcdKB SMALL
|
||||
6|27.Feb 2019 20:27:00* SMALL
|
||||
7|yyyyyyyyyyyyyyyy SFab SMALL
|
||||
|
||||
line 6: * = char {L|G|R|?} indicates time source,
|
||||
inverse = clock controller is active,
|
||||
pulsed = pps input signal is active
|
||||
* = char {L|G|R|?} indicates time source,
|
||||
inverse = clock controller is active,
|
||||
pulsed = pps input signal is active
|
||||
|
||||
line 7: y = LMIC event message; ab = payload queue length
|
||||
y = LMIC event message; ab = payload queue length
|
||||
|
||||
FONT_SMALL: 6x8px = 21 chars / line
|
||||
FONT_NORMAL: 8x8px = 16 chars / line
|
||||
FONT_STRETCHED: 16x32px = 8 chars / line
|
||||
|
||||
*/
|
||||
|
||||
// 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
|
||||
// local Tag for logging
|
||||
static const char TAG[] = __FILE__;
|
||||
|
||||
HAS_DISPLAY u8x8(MY_OLED_RST, MY_OLED_SCL, MY_OLED_SDA);
|
||||
#define DISPLAY_PAGES (5) // number of paxcounter display pages
|
||||
|
||||
// helper arry for converting month values to text
|
||||
// settings for oled display library
|
||||
#define USE_BACKBUFFER
|
||||
|
||||
// settings for qr code generator
|
||||
#define QR_VERSION 3 // 29 x 29px
|
||||
#define QR_SCALEFACTOR 2 // 29 -> 58x < 64px
|
||||
|
||||
// settings for curve plotter
|
||||
#define DISPLAY_WIDTH 128 // Width in pixels of OLED-display, must be 32X
|
||||
#define DISPLAY_HEIGHT 64 // Height in pixels of OLED-display, must be 64X
|
||||
|
||||
// helper array for converting month values to text
|
||||
const char *printmonth[] = {"xxx", "Jan", "Feb", "Mar", "Apr", "May", "Jun",
|
||||
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
|
||||
|
||||
uint8_t DisplayIsOn = 0;
|
||||
uint8_t displaybuf[DISPLAY_WIDTH * DISPLAY_HEIGHT / 8] = {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");
|
||||
}
|
||||
QRCode qrcode;
|
||||
|
||||
void init_display(const char *Productname, const char *Version) {
|
||||
void init_display(uint8_t verbose) {
|
||||
|
||||
// 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
|
||||
oledSetContrast(DISPLAYCONTRAST);
|
||||
oledFill(0, 1);
|
||||
|
||||
if (verbose) {
|
||||
|
||||
// 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,
|
||||
esp_chip_info_t chip_info;
|
||||
esp_chip_info(&chip_info);
|
||||
dp_printf(0, 0, 0, 0, "** PAXCOUNTER **");
|
||||
dp_printf(0, 1, 0, 0, "Software v%s", PROGVERSION);
|
||||
dp_printf(0, 3, 0, 0, "ESP32 %d cores", chip_info.cores);
|
||||
dp_printf(0, 4, 0, 0, "Chip Rev.%d", chip_info.revision);
|
||||
dp_printf(0, 5, 0, 0, "WiFi%s%s",
|
||||
(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),
|
||||
dp_printf(0, 6, 0, 0, "%dMB %s Flash",
|
||||
spi_flash_get_chip_size() / (1024 * 1024),
|
||||
(chip_info.features & CHIP_FEATURE_EMB_FLASH) ? "int."
|
||||
: "ext.");
|
||||
|
||||
// give user some time to read or take picture
|
||||
oledDumpBuffer(NULL);
|
||||
delay(2000);
|
||||
oledFill(0x00, 1);
|
||||
#endif // VERBOSE
|
||||
|
||||
u8x8.print(Productname);
|
||||
u8x8.print(" v");
|
||||
u8x8.println(PROGVERSION);
|
||||
|
||||
#if (HAS_LORA)
|
||||
u8x8.println("DEVEUI:");
|
||||
os_getDevEui((u1_t *)buf);
|
||||
DisplayKey(buf, 8, true);
|
||||
delay(3000);
|
||||
// generate DEVEUI as QR code and text
|
||||
uint8_t buf[8];
|
||||
char deveui[17];
|
||||
os_getDevEui((u1_t *)buf);
|
||||
sprintf(deveui, "%016llX", *((uint64_t *)&buf));
|
||||
|
||||
// display DEVEUI as QR code on the left
|
||||
oledSetContrast(30);
|
||||
dp_printqr(3, 3, deveui);
|
||||
|
||||
// display DEVEUI as plain text on the right
|
||||
dp_printf(72, 0, FONT_NORMAL, 0, "LORAWAN");
|
||||
dp_printf(72, 1, FONT_NORMAL, 0, "DEVEUI:");
|
||||
dp_printf(80, 3, FONT_NORMAL, 0, "%4.4s", deveui);
|
||||
dp_printf(80, 4, FONT_NORMAL, 0, "%4.4s", deveui + 4);
|
||||
dp_printf(80, 5, FONT_NORMAL, 0, "%4.4s", deveui + 8);
|
||||
dp_printf(80, 6, FONT_NORMAL, 0, "%4.4s", deveui + 12);
|
||||
|
||||
// give user some time to read or take picture
|
||||
oledDumpBuffer(NULL);
|
||||
delay(8000);
|
||||
oledSetContrast(DISPLAYCONTRAST);
|
||||
oledFill(0x00, 1);
|
||||
#endif // HAS_LORA
|
||||
u8x8.clear();
|
||||
u8x8.setPowerSave(!cfg.screenon); // set display off if disabled
|
||||
u8x8.draw2x2String(0, 0, "PAX:0");
|
||||
#if (BLECOUNTER)
|
||||
u8x8.setCursor(0, 3);
|
||||
u8x8.printf("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);
|
||||
|
||||
} // verbose
|
||||
|
||||
oledPower(cfg.screenon); // set display off if disabled
|
||||
|
||||
I2C_MUTEX_UNLOCK(); // release i2c bus access
|
||||
} // mutex
|
||||
@@ -137,15 +155,16 @@ 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);
|
||||
oledDumpBuffer(NULL);
|
||||
|
||||
I2C_MUTEX_UNLOCK(); // release i2c bus access
|
||||
|
||||
@@ -154,191 +173,160 @@ void refreshTheDisplay(bool nextPage) {
|
||||
|
||||
void draw_page(time_t t, uint8_t page) {
|
||||
|
||||
char timeState, buff[16];
|
||||
char timeState;
|
||||
uint8_t msgWaiting;
|
||||
#if (HAS_GPS)
|
||||
static bool wasnofix = true;
|
||||
#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
|
||||
// line 1/2: pax counter
|
||||
dp_printf(0, 0, FONT_STRETCHED, 0, "PAX:%-4d",
|
||||
macs.size()); // display number of unique macs total Wifi + BLE
|
||||
|
||||
// update histogram if we have a display
|
||||
oledPlotCurve(macs.size(), false);
|
||||
|
||||
switch (page % DISPLAY_PAGES) {
|
||||
|
||||
// page 0: parameters overview
|
||||
// page 1: time
|
||||
// page 1: pax graph
|
||||
// page 2: GPS
|
||||
// page 3: BME280/680
|
||||
// page 4: time
|
||||
|
||||
// page 0: parameters overview
|
||||
case 0:
|
||||
|
||||
// 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 ");
|
||||
else
|
||||
u8x8.printf("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);
|
||||
}
|
||||
#endif
|
||||
|
||||
// update bluetooth counter + LoRa SF (line 3)
|
||||
// line 3: wifi + bluetooth counters
|
||||
dp_printf(0, 3, FONT_SMALL, 0, "WIFI:%-5d", macs_wifi);
|
||||
#if (BLECOUNTER)
|
||||
u8x8.setCursor(0, 3);
|
||||
if (cfg.blescan)
|
||||
u8x8.printf("BLTH:%-5d", macs_ble);
|
||||
dp_printf(66, 3, FONT_SMALL, 0, "BLTH:%-5d", macs_ble);
|
||||
else
|
||||
u8x8.printf("%s", "BLTH:off");
|
||||
dp_printf(66, 3, FONT_SMALL, 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);
|
||||
#endif // HAS_LORA
|
||||
// line 4: Battery + GPS status + Wifi channel
|
||||
#if (defined BAT_MEASURE_ADC || defined HAS_PMU)
|
||||
if (batt_voltage == 0xffff)
|
||||
dp_printf(0, 4, FONT_SMALL, 0, "%s", "USB ");
|
||||
else if (batt_voltage == 0)
|
||||
dp_printf(0, 4, FONT_SMALL, 0, "%s", "No batt");
|
||||
else
|
||||
dp_printf(0, 4, FONT_SMALL, 0, "B:%.2fV", batt_voltage / 1000.0);
|
||||
#endif
|
||||
#if (HAS_GPS)
|
||||
if (gps.location.age() < 1500) // if no fix then display Sats value inverse
|
||||
dp_printf(48, 4, FONT_SMALL, 0, "Sats:%.2d", gps.satellites.value());
|
||||
else
|
||||
dp_printf(48, 4, FONT_SMALL, 1, "Sats:%.2d", gps.satellites.value());
|
||||
#endif
|
||||
dp_printf(96, 4, FONT_SMALL, 0, "ch:%02d", channel);
|
||||
|
||||
// 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);
|
||||
// line 5: RSSI limiter + free memory
|
||||
dp_printf(0, 5, FONT_SMALL, 0, !cfg.rssilimit ? "RLIM:off " : "RLIM:%-4d",
|
||||
cfg.rssilimit);
|
||||
dp_printf(66, 5, FONT_SMALL, 0, "Mem:%4dKB", getFreeRAM() / 1024);
|
||||
|
||||
// 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);
|
||||
|
||||
// line 6: update time-of-day or LoRa status display
|
||||
u8x8.setCursor(0, 6);
|
||||
// line 6: time + date
|
||||
#if (TIME_SYNC_INTERVAL)
|
||||
// we want a systime display instead LoRa status
|
||||
timeState = TimePulseTick ? ' ' : timeSetSymbols[timeSource];
|
||||
TimePulseTick = false;
|
||||
|
||||
dp_printf(0, 6, FONT_SMALL, 0, "%02d.%3s %4d", day(t), printmonth[month(t)],
|
||||
year(t));
|
||||
dp_printf(72, 6, FONT_SMALL, 0, "%02d:%02d:%02d", hour(t), minute(t),
|
||||
second(t));
|
||||
|
||||
// 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(120, 6, FONT_SMALL, 1, "%c", timeState);
|
||||
#else
|
||||
u8x8.printf("%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(120, 6, FONT_SMALL, 0, "%c", timeState);
|
||||
#endif
|
||||
|
||||
#endif // TIME_SYNC_INTERVAL
|
||||
|
||||
// line 7: LORA network status
|
||||
#if (HAS_LORA)
|
||||
// line 7: update LMiC event display
|
||||
u8x8.setCursor(0, 7);
|
||||
u8x8.printf("%-14s", lmic_event_msg);
|
||||
|
||||
// update LoRa send queue display
|
||||
// LMiC event display, display inverse if sendqueue not empty
|
||||
msgWaiting = uxQueueMessagesWaiting(LoraSendQueue);
|
||||
if (msgWaiting) {
|
||||
sprintf(buff, "%2d", msgWaiting);
|
||||
u8x8.setCursor(14, 7);
|
||||
u8x8.printf("%-2s", msgWaiting == SEND_QUEUE_SIZE ? "<>" : buff);
|
||||
} else
|
||||
u8x8.printf(" ");
|
||||
if (msgWaiting)
|
||||
dp_printf(0, 7, FONT_SMALL, 1, "%-16s", lmic_event_msg);
|
||||
else
|
||||
dp_printf(0, 7, FONT_SMALL, 0, "%-16s", lmic_event_msg);
|
||||
// LORA datarate, display inverse if ADR disabled
|
||||
if (cfg.adrmode)
|
||||
dp_printf(100, 7, FONT_SMALL, 0, "%-4s",
|
||||
getSfName(updr2rps(LMIC.datarate)));
|
||||
else
|
||||
dp_printf(100, 7, FONT_SMALL, 1, "%-4s",
|
||||
getSfName(updr2rps(LMIC.datarate)));
|
||||
#endif // HAS_LORA
|
||||
|
||||
break; // page0
|
||||
|
||||
// page 1: pax graph
|
||||
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);
|
||||
|
||||
oledDumpBuffer(displaybuf);
|
||||
break; // page1
|
||||
|
||||
// page 2: GPS
|
||||
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
|
||||
|
||||
// page 3: BME280/680
|
||||
case 3:
|
||||
|
||||
#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
|
||||
|
||||
// page 4: time
|
||||
case 4:
|
||||
|
||||
dp_printf(0, 4, FONT_LARGE, 0, "%02d:%02d:%02d", hour(t), minute(t),
|
||||
second(t));
|
||||
break;
|
||||
|
||||
default:
|
||||
break; // default
|
||||
|
||||
@@ -346,4 +334,148 @@ void draw_page(time_t t, uint8_t page) {
|
||||
|
||||
} // draw_page
|
||||
|
||||
// display helper functions
|
||||
void dp_printf(uint16_t x, uint16_t y, uint8_t font, uint8_t 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, false);
|
||||
if (temp != loc_buf) {
|
||||
free(temp);
|
||||
}
|
||||
}
|
||||
|
||||
void dp_printqr(uint16_t offset_x, uint16_t offset_y, const char *Message) {
|
||||
uint8_t qrcodeData[qrcode_getBufferSize(QR_VERSION)];
|
||||
qrcode_initText(&qrcode, qrcodeData, QR_VERSION, ECC_HIGH, Message);
|
||||
|
||||
// draw QR code
|
||||
for (uint16_t y = 0; y < qrcode.size; y++)
|
||||
for (uint16_t x = 0; x < qrcode.size; x++)
|
||||
if (!qrcode_getModule(&qrcode, x, y)) // "black"
|
||||
oledfillRect(x * QR_SCALEFACTOR + offset_x,
|
||||
y * QR_SCALEFACTOR + offset_y, QR_SCALEFACTOR,
|
||||
QR_SCALEFACTOR, false);
|
||||
// draw horizontal frame lines
|
||||
oledfillRect(0, 0, qrcode.size * QR_SCALEFACTOR + 2 * offset_x, offset_y,
|
||||
false);
|
||||
oledfillRect(0, qrcode.size * QR_SCALEFACTOR + offset_y,
|
||||
qrcode.size * QR_SCALEFACTOR + 2 * offset_x, offset_y, false);
|
||||
// draw vertical frame lines
|
||||
oledfillRect(0, 0, offset_x, qrcode.size * QR_SCALEFACTOR + 2 * offset_y,
|
||||
false);
|
||||
oledfillRect(qrcode.size * QR_SCALEFACTOR + offset_x, 0, offset_x,
|
||||
qrcode.size * QR_SCALEFACTOR + 2 * offset_y, false);
|
||||
}
|
||||
|
||||
void oledfillRect(uint16_t x, uint16_t y, uint16_t width, uint16_t height,
|
||||
uint8_t bRender) {
|
||||
for (uint16_t xi = x; xi < x + width; xi++)
|
||||
oledDrawLine(xi, y, xi, y + height - 1, bRender);
|
||||
}
|
||||
|
||||
int oledDrawPixel(uint8_t *buf, const uint16_t x, const uint16_t y,
|
||||
const uint8_t dot) {
|
||||
|
||||
if (x > DISPLAY_WIDTH || y > DISPLAY_HEIGHT)
|
||||
return -1;
|
||||
|
||||
uint8_t bit = y & 7;
|
||||
uint16_t idx = y / 8 * DISPLAY_WIDTH + x;
|
||||
|
||||
buf[idx] &= ~(1 << bit); // clear pixel
|
||||
if (dot)
|
||||
buf[idx] |= (1 << bit); // set pixel
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void oledScrollBufferLeft(uint8_t *buf, const uint16_t width,
|
||||
const uint16_t height) {
|
||||
|
||||
uint16_t col, page, idx;
|
||||
|
||||
for (page = 0; page < height / 8; page++) {
|
||||
for (col = 0; col < width - 1; col++) {
|
||||
idx = page * width + col;
|
||||
buf[idx] = buf[idx + 1];
|
||||
}
|
||||
buf[idx + 1] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void oledPlotCurve(uint16_t count, bool reset) {
|
||||
|
||||
static uint16_t last_count = 0, col = 0, row = 0;
|
||||
static int scalefactor = 1, oldsf = 1;
|
||||
|
||||
if ((last_count == count) && !reset)
|
||||
return;
|
||||
|
||||
if (reset) { // next count cycle?
|
||||
if (col < DISPLAY_WIDTH - 1) // matrix not full -> increment column
|
||||
col++;
|
||||
else // matrix full -> scroll left 1 dot
|
||||
oledScrollBufferLeft(displaybuf, DISPLAY_WIDTH, DISPLAY_HEIGHT);
|
||||
|
||||
} else // clear current dot
|
||||
oledDrawPixel(displaybuf, col, row, 0);
|
||||
|
||||
// re-scale, if necessary
|
||||
oldsf = scalefactor;
|
||||
while (((count / scalefactor) <= DISPLAY_HEIGHT) && (scalefactor > 1))
|
||||
scalefactor--;
|
||||
while ((count / scalefactor) > DISPLAY_HEIGHT)
|
||||
scalefactor++;
|
||||
if (scalefactor != oldsf)
|
||||
oledRescaleBuffer(displaybuf, scalefactor);
|
||||
|
||||
// set new dot
|
||||
row = DISPLAY_HEIGHT - 1 - (count / scalefactor) % DISPLAY_HEIGHT;
|
||||
last_count = count;
|
||||
oledDrawPixel(displaybuf, col, row, 1);
|
||||
}
|
||||
|
||||
void oledRescaleBuffer(uint8_t *buf, const int factor) {
|
||||
|
||||
if (!factor)
|
||||
return;
|
||||
|
||||
uint64_t buf_col;
|
||||
|
||||
for (uint16_t col = 0; col < DISPLAY_WIDTH; col++) {
|
||||
// convert column bytes from display buffer to uint64_t
|
||||
buf_col = *(uint64_t *)&buf[col * DISPLAY_HEIGHT / 8];
|
||||
|
||||
if (factor < 0)
|
||||
// shift left: scroll up = scale down
|
||||
buf_col <= abs(factor);
|
||||
else
|
||||
// shift right: scroll down = scale up
|
||||
buf_col >= abs(factor);
|
||||
|
||||
// write back uint64_t to uint8_t display buffer
|
||||
*(uint64_t *)&buf[col * DISPLAY_HEIGHT / 8] = buf_col;
|
||||
}
|
||||
}
|
||||
|
||||
#endif // HAS_DISPLAY
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
// clang-format off
|
||||
// upload_speed 115200
|
||||
// upload_speed 921600
|
||||
// board esp32dev
|
||||
|
||||
#ifndef _EBOX_H
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
// clang-format off
|
||||
// upload_speed 115200
|
||||
// upload_speed 921600
|
||||
// board esp32dev
|
||||
|
||||
|
||||
|
||||
+2
-2
@@ -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
|
||||
|
||||
+1
-1
@@ -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
|
||||
|
||||
+1
-1
@@ -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
|
||||
|
||||
|
||||
+1
-1
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
+2
-2
@@ -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
|
||||
+2
-2
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
+2
-2
@@ -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
|
||||
|
||||
+1
-1
@@ -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
|
||||
|
||||
+2
-2
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -94,7 +94,7 @@ void refreshTheMatrixDisplay(bool nextPage) {
|
||||
if (col < (LED_MATRIX_WIDTH - 1))
|
||||
col++;
|
||||
else
|
||||
ScrollLeft(displaybuf, LED_MATRIX_WIDTH, LED_MATRIX_HEIGHT);
|
||||
ScrollMatrixLeft(displaybuf, LED_MATRIX_WIDTH, LED_MATRIX_HEIGHT);
|
||||
|
||||
} else
|
||||
matrix.drawPoint(col, row, 0); // clear current dot
|
||||
@@ -204,7 +204,7 @@ uint8_t GetCharWidth(char cChar) {
|
||||
return CharDescriptor.width;
|
||||
}
|
||||
|
||||
void ScrollLeft(uint8_t *buf, const uint16_t cols, const uint16_t rows) {
|
||||
void ScrollMatrixLeft(uint8_t *buf, const uint16_t cols, const uint16_t rows) {
|
||||
uint32_t i, k, idx;
|
||||
const uint32_t x = cols / 8;
|
||||
|
||||
|
||||
+4
-4
@@ -129,7 +129,7 @@ void setup() {
|
||||
esp_log_level_set("*", ESP_LOG_NONE);
|
||||
#endif
|
||||
|
||||
ESP_LOGI(TAG, "Starting %s v%s", PRODUCTNAME, PROGVERSION);
|
||||
ESP_LOGI(TAG, "Starting Software v%s", PROGVERSION);
|
||||
|
||||
// print chip information on startup if in verbose mode
|
||||
#if (VERBOSE)
|
||||
@@ -172,9 +172,9 @@ void setup() {
|
||||
|
||||
// open i2c bus
|
||||
#ifdef HAS_DISPLAY
|
||||
Wire.begin(MY_OLED_SDA, MY_OLED_SCL, 100000);
|
||||
Wire.begin(MY_OLED_SDA, MY_OLED_SCL, 400000);
|
||||
#else
|
||||
Wire.begin(SDA, SCL, 100000);
|
||||
Wire.begin(SDA, SCL, 400000);
|
||||
#endif
|
||||
|
||||
// setup power on boards with power management logic
|
||||
@@ -200,7 +200,7 @@ void setup() {
|
||||
#ifdef HAS_DISPLAY
|
||||
strcat_P(features, " OLED");
|
||||
DisplayIsOn = cfg.screenon;
|
||||
init_display(PRODUCTNAME, PROGVERSION); // note: blocking call
|
||||
init_display(!cfg.runmode); // note: blocking call
|
||||
#endif
|
||||
|
||||
#ifdef BOARD_HAS_PSRAM
|
||||
|
||||
+41
-42
@@ -48,25 +48,25 @@ void start_ota_update() {
|
||||
|
||||
switch_LED(LED_ON);
|
||||
|
||||
// init display
|
||||
#ifdef HAS_DISPLAY
|
||||
u8x8.begin();
|
||||
u8x8.setFont(u8x8_font_chroma48medium8_r);
|
||||
u8x8.clear();
|
||||
#ifdef DISPLAY_FLIP
|
||||
u8x8.setFlipMode(1);
|
||||
#ifndef DISPLAY_FLIP
|
||||
oledInit(OLED_128x64, ANGLE_0, false, -1, -1, 400000L);
|
||||
#else
|
||||
oledInit(OLED_128x64, ANGLE_FLIPY, false, -1, -1, 400000L);
|
||||
#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 ..");
|
||||
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 ..");
|
||||
oledDumpBuffer(NULL);
|
||||
#endif
|
||||
|
||||
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,26 @@ 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());
|
||||
}
|
||||
oledDumpBuffer(NULL);
|
||||
#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); }
|
||||
|
||||
+4
-4
@@ -6,18 +6,17 @@
|
||||
//
|
||||
// Note: After editing, before "build", use "clean" button in PlatformIO!
|
||||
|
||||
#define PRODUCTNAME "PAXCNT"
|
||||
|
||||
// Verbose enables serial output
|
||||
#define VERBOSE 1 // set to 0 to silence the device, for mute use build option
|
||||
|
||||
// Payload send cycle and encoding
|
||||
#define SENDCYCLE 30 // payload send cycle [seconds/2], 0 .. 255
|
||||
#define PAYLOAD_ENCODER 2 // payload encoder: 1=Plain, 2=Packed, 3=Cayenne LPP dynamic, 4=Cayenne LPP packed
|
||||
#define COUNTERMODE 0 // 0=cyclic, 1=cumulative, 2=cyclic confirmed
|
||||
|
||||
// Set this to include BLE counting and vendor filter functions, or to switch off WIFI counting
|
||||
#define VENDORFILTER 1 // set to 0 if you want to count things, not people
|
||||
#define BLECOUNTER 0 // set it to 1 if you want to use BLE count, at expense of power & memory
|
||||
#define BLECOUNTER 1 // set it to 1 if you want to use BLE count, at expense of power & memory
|
||||
#define WIFICOUNTER 1 // set it to 0 if you want to switch off WIFI count
|
||||
|
||||
// BLE scan parameters
|
||||
@@ -56,6 +55,7 @@
|
||||
// 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 DISPLAYCONTRAST 80 // 0 .. 255, OLED display contrast [default = 80]
|
||||
#define HOMECYCLE 30 // house keeping cycle in seconds [default = 30 secs]
|
||||
|
||||
// Settings for BME680 environmental sensor
|
||||
@@ -75,7 +75,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 0 // 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
|
||||
|
||||
+125
-97
@@ -11,48 +11,41 @@ AXP20X_Class pmu;
|
||||
|
||||
void power_event_IRQ(void) {
|
||||
|
||||
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
|
||||
if (pmu.isVbusOverVoltageIRQ())
|
||||
ESP_LOGI(TAG, "USB voltage %.2fV too high.", pmu.getVbusVoltage() / 1000);
|
||||
if (pmu.isVbusPlugInIRQ())
|
||||
ESP_LOGI(TAG, "USB plugged, %.2fV @ %.0mA", pmu.getVbusVoltage() / 1000,
|
||||
pmu.getVbusCurrent());
|
||||
if (pmu.isVbusRemoveIRQ())
|
||||
ESP_LOGI(TAG, "USB unplugged.");
|
||||
|
||||
if (pmu.isVbusOverVoltageIRQ())
|
||||
ESP_LOGI(TAG, "USB voltage %.2fV too high.", pmu.getVbusVoltage() / 1000);
|
||||
if (pmu.isVbusPlugInIRQ())
|
||||
ESP_LOGI(TAG, "USB plugged, %.2fV @ %.0mA", pmu.getVbusVoltage() / 1000,
|
||||
pmu.getVbusCurrent());
|
||||
if (pmu.isVbusRemoveIRQ())
|
||||
ESP_LOGI(TAG, "USB unplugged.");
|
||||
if (pmu.isBattPlugInIRQ())
|
||||
ESP_LOGI(TAG, "Battery is connected.");
|
||||
if (pmu.isBattRemoveIRQ())
|
||||
ESP_LOGI(TAG, "Battery was removed.");
|
||||
if (pmu.isChargingIRQ())
|
||||
ESP_LOGI(TAG, "Battery charging.");
|
||||
if (pmu.isChargingDoneIRQ())
|
||||
ESP_LOGI(TAG, "Battery charging done.");
|
||||
if (pmu.isBattTempLowIRQ())
|
||||
ESP_LOGI(TAG, "Battery high temperature.");
|
||||
if (pmu.isBattTempHighIRQ())
|
||||
ESP_LOGI(TAG, "Battery low temperature.");
|
||||
|
||||
if (pmu.isBattPlugInIRQ())
|
||||
ESP_LOGI(TAG, "Battery is connected.");
|
||||
if (pmu.isBattRemoveIRQ())
|
||||
ESP_LOGI(TAG, "Battery was removed.");
|
||||
if (pmu.isChargingIRQ())
|
||||
ESP_LOGI(TAG, "Battery charging.");
|
||||
if (pmu.isChargingDoneIRQ())
|
||||
ESP_LOGI(TAG, "Battery charging done.");
|
||||
if (pmu.isBattTempLowIRQ())
|
||||
ESP_LOGI(TAG, "Battery high temperature.");
|
||||
if (pmu.isBattTempHighIRQ())
|
||||
ESP_LOGI(TAG, "Battery low temperature.");
|
||||
// display on/off
|
||||
if (pmu.isPEKShortPressIRQ()) {
|
||||
cfg.screenon = !cfg.screenon;
|
||||
}
|
||||
|
||||
// display on/off
|
||||
if (pmu.isPEKShortPressIRQ()) {
|
||||
cfg.screenon = !cfg.screenon;
|
||||
}
|
||||
// shutdown power
|
||||
if (pmu.isPEKLongtPressIRQ()) {
|
||||
AXP192_power(false); // switch off Lora, GPS, display
|
||||
pmu.shutdown();
|
||||
}
|
||||
|
||||
// shutdown power
|
||||
if (pmu.isPEKLongtPressIRQ()) {
|
||||
AXP192_power(false); // switch off Lora, GPS, display
|
||||
pmu.shutdown();
|
||||
}
|
||||
|
||||
pmu.clearIRQ();
|
||||
I2C_MUTEX_UNLOCK();
|
||||
} // mutex
|
||||
pmu.clearIRQ();
|
||||
|
||||
// refresh stored voltage value
|
||||
read_voltage();
|
||||
@@ -75,70 +68,103 @@ void AXP192_power(bool on) {
|
||||
|
||||
void AXP192_showstatus(void) {
|
||||
|
||||
if (!I2C_MUTEX_LOCK())
|
||||
ESP_LOGW(TAG, "[%0.3f] i2c mutex lock failed", millis() / 1000.0);
|
||||
else {
|
||||
|
||||
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");
|
||||
if (pmu.isBatteryConnect())
|
||||
if (pmu.isChargeing())
|
||||
ESP_LOGI(TAG, "Battery charging, %.2fV @ %.0fmAh",
|
||||
pmu.getBattVoltage() / 1000, pmu.getBattChargeCurrent());
|
||||
else
|
||||
ESP_LOGI(TAG, "No Battery");
|
||||
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
|
||||
if (pmu.isVBUSPlug())
|
||||
ESP_LOGI(TAG, "USB powered, %.0fmW",
|
||||
pmu.getVbusVoltage() / 1000 * pmu.getVbusCurrent());
|
||||
else
|
||||
ESP_LOGI(TAG, "USB not present");
|
||||
}
|
||||
|
||||
void AXP192_init(void) {
|
||||
|
||||
// block i2c bus access
|
||||
if (I2C_MUTEX_LOCK()) {
|
||||
if (pmu.begin(i2c_readBytes, i2c_writeBytes, AXP192_PRIMARY_ADDRESS) == AXP_FAIL)
|
||||
ESP_LOGI(TAG, "AXP192 PMU initialization failed");
|
||||
else {
|
||||
|
||||
if (pmu.begin(Wire, AXP192_PRIMARY_ADDRESS))
|
||||
ESP_LOGI(TAG, "AXP192 PMU initialization failed");
|
||||
else {
|
||||
// configure AXP192
|
||||
pmu.setDCDC1Voltage(3300); // for external OLED display
|
||||
pmu.setTimeOutShutdown(false); // no automatic shutdown
|
||||
pmu.setTSmode(AXP_TS_PIN_MODE_DISABLE); // TS pin mode off to save power
|
||||
|
||||
// configure AXP192
|
||||
pmu.setDCDC1Voltage(3300); // for external OLED display
|
||||
pmu.setTimeOutShutdown(false); // no automatic shutdown
|
||||
pmu.setTSmode(AXP_TS_PIN_MODE_DISABLE); // TS pin mode off to save power
|
||||
// switch ADCs on
|
||||
pmu.adc1Enable(AXP202_BATT_VOL_ADC1, true);
|
||||
pmu.adc1Enable(AXP202_BATT_CUR_ADC1, true);
|
||||
pmu.adc1Enable(AXP202_VBUS_VOL_ADC1, true);
|
||||
pmu.adc1Enable(AXP202_VBUS_CUR_ADC1, true);
|
||||
|
||||
// switch ADCs on
|
||||
pmu.adc1Enable(AXP202_BATT_VOL_ADC1, true);
|
||||
pmu.adc1Enable(AXP202_BATT_CUR_ADC1, true);
|
||||
pmu.adc1Enable(AXP202_VBUS_VOL_ADC1, true);
|
||||
pmu.adc1Enable(AXP202_VBUS_CUR_ADC1, true);
|
||||
// switch power rails on
|
||||
AXP192_power(true);
|
||||
|
||||
// switch power rails on
|
||||
AXP192_power(true);
|
||||
|
||||
// I2C access of AXP202X library currently is not mutexable
|
||||
// so we better should disable AXP interrupts... ?
|
||||
#ifdef PMU_INT
|
||||
pinMode(PMU_INT, INPUT_PULLUP);
|
||||
attachInterrupt(digitalPinToInterrupt(PMU_INT), PMUIRQ, FALLING);
|
||||
pmu.enableIRQ(AXP202_VBUS_REMOVED_IRQ | AXP202_VBUS_CONNECT_IRQ |
|
||||
AXP202_BATT_REMOVED_IRQ | AXP202_BATT_CONNECT_IRQ |
|
||||
AXP202_CHARGING_FINISHED_IRQ,
|
||||
1);
|
||||
pmu.clearIRQ();
|
||||
pinMode(PMU_INT, INPUT_PULLUP);
|
||||
attachInterrupt(digitalPinToInterrupt(PMU_INT), PMUIRQ, FALLING);
|
||||
pmu.enableIRQ(AXP202_VBUS_REMOVED_IRQ | AXP202_VBUS_CONNECT_IRQ |
|
||||
AXP202_BATT_REMOVED_IRQ | AXP202_BATT_CONNECT_IRQ |
|
||||
AXP202_CHARGING_FINISHED_IRQ,
|
||||
1);
|
||||
pmu.clearIRQ();
|
||||
#endif // PMU_INT
|
||||
|
||||
ESP_LOGI(TAG, "AXP192 PMU initialized");
|
||||
}
|
||||
I2C_MUTEX_UNLOCK(); // release i2c bus access
|
||||
} else
|
||||
ESP_LOGE(TAG, "I2c bus busy - PMU initialization error");
|
||||
ESP_LOGI(TAG, "AXP192 PMU initialized");
|
||||
}
|
||||
}
|
||||
|
||||
// helper functions for mutexing i2c access
|
||||
uint8_t i2c_readBytes(uint8_t addr, uint8_t reg, uint8_t *data, uint8_t len) {
|
||||
if (I2C_MUTEX_LOCK()) {
|
||||
|
||||
uint8_t ret = 0;
|
||||
Wire.beginTransmission(addr);
|
||||
Wire.write(reg);
|
||||
Wire.endTransmission(false);
|
||||
uint8_t cnt = Wire.requestFrom(addr, (uint8_t)len, (uint8_t)1);
|
||||
if (!cnt) {
|
||||
ret = 0xFF;
|
||||
}
|
||||
uint16_t index = 0;
|
||||
while (Wire.available()) {
|
||||
if (index > len)
|
||||
return 0xFF;
|
||||
data[index++] = Wire.read();
|
||||
}
|
||||
|
||||
I2C_MUTEX_UNLOCK(); // release i2c bus access
|
||||
return ret;
|
||||
} else {
|
||||
ESP_LOGW(TAG, "[%0.3f] i2c mutex lock failed", millis() / 1000.0);
|
||||
return 0xFF;
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t i2c_writeBytes(uint8_t addr, uint8_t reg, uint8_t *data, uint8_t len) {
|
||||
if (I2C_MUTEX_LOCK()) {
|
||||
|
||||
uint8_t ret = 0;
|
||||
Wire.beginTransmission(addr);
|
||||
Wire.write(reg);
|
||||
for (uint16_t i = 0; i < len; i++) {
|
||||
Wire.write(data[i]);
|
||||
}
|
||||
ret = Wire.endTransmission();
|
||||
|
||||
I2C_MUTEX_UNLOCK(); // release i2c bus access
|
||||
return ret ? 0xFF : ret;
|
||||
//return ret ? ret : 0xFF;
|
||||
} else {
|
||||
ESP_LOGW(TAG, "[%0.3f] i2c mutex lock failed", millis() / 1000.0);
|
||||
return 0xFF;
|
||||
}
|
||||
}
|
||||
|
||||
#endif // HAS_PMU
|
||||
|
||||
#ifdef BAT_MEASURE_ADC
|
||||
@@ -196,26 +222,28 @@ uint16_t read_voltage() {
|
||||
uint16_t voltage = 0;
|
||||
|
||||
#ifdef HAS_PMU
|
||||
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();
|
||||
}
|
||||
// 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
|
||||
|
||||
#ifdef BAT_MEASURE_ADC
|
||||
// multisample ADC
|
||||
uint32_t adc_reading = 0;
|
||||
#ifndef BAT_MEASURE_ADC_UNIT // ADC1
|
||||
for (int i = 0; i < NO_OF_SAMPLES; i++) {
|
||||
adc_reading += adc1_get_raw(adc_channel);
|
||||
}
|
||||
#else // ADC2
|
||||
int adc_buf = 0;
|
||||
for (int i = 0; i < NO_OF_SAMPLES; i++) {
|
||||
#ifndef BAT_MEASURE_ADC_UNIT // ADC1
|
||||
adc_reading += adc1_get_raw(adc_channel);
|
||||
#else // ADC2
|
||||
ESP_ERROR_CHECK(adc2_get_raw(adc_channel, ADC_WIDTH_BIT_12, &adc_buf));
|
||||
adc_reading += adc_buf;
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
adc_reading /= NO_OF_SAMPLES;
|
||||
// Convert ADC reading to voltage in mV
|
||||
voltage = esp_adc_cal_raw_to_voltage(adc_reading, adc_characs);
|
||||
|
||||
@@ -75,6 +75,10 @@ void sendData() {
|
||||
get_salt(); // get new salt for salting hashes
|
||||
ESP_LOGI(TAG, "Counter cleared");
|
||||
}
|
||||
#ifdef HAS_DISPLAY
|
||||
else
|
||||
oledPlotCurve(macs.size(), true);
|
||||
#endif
|
||||
break;
|
||||
#endif
|
||||
|
||||
|
||||
Reference in new issue
Block a user