ESP32-PaxCounter/src/display.cpp

249 lines
6.7 KiB
C++
Raw Normal View History

2018-07-15 14:28:05 +02:00
#ifdef HAS_DISPLAY
/*
Display-Mask (128 x 64 pixel):
| 111111
|0123456789012345
------------------
0|PAX:aabbccddee
1|PAX:aabbccddee
2|B:a.bcV Sats:ab
3|BLTH:abcde SF:ab
4|WIFI:abcde ch:ab
5|RLIM:abcd abcdKB
6|xxxxxxxxxxxxxxxx
6|20:27:00* 27.Feb
7|yyyyyyyyyyyyyyab
line 6: x = Text for LORA status OR time/date
line 7: y = Text for LMIC status; ab = payload queue
*/
2018-07-15 14:28:05 +02:00
// Basic Config
#include "globals.h"
#include <esp_spi_flash.h> // needed for reading ESP32 chip attributes
HAS_DISPLAY u8x8(MY_OLED_RST, MY_OLED_SCL, MY_OLED_SDA);
2018-07-15 14:28:05 +02:00
2018-07-15 23:40:42 +02:00
// helper string for converting LoRa spread factor values
#if defined(CFG_eu868)
const char lora_datarate[] = {"1211100908077BFSNA"};
#elif defined(CFG_us915)
const char lora_datarate[] = {"100908078CNA121110090807"};
#elif defined(CFG_as923)
const char lora_datarate[] = {"1211100908077BFSNA"};
#elif defined(CFG_au921)
const char lora_datarate[] = {"1211100908078CNA1211109C8C7C"};
#elif defined(CFG_in866)
const char lora_datarate[] = {"121110090807FSNA"};
2018-07-15 23:40:42 +02:00
#endif
// helper arry for converting month values to text
char *printmonth[] = {"xxx", "Jan", "Feb", "Mar", "Apr", "May", "Jun",
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
2018-09-23 22:12:10 +02:00
uint8_t volatile DisplayState = 0;
2018-07-19 21:53:56 +02:00
2018-07-15 14:28:05 +02:00
// 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) {
// show startup screen
2018-07-15 14:28:05 +02:00
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);
2018-12-19 12:32:25 +01:00
delay(1500);
2018-07-15 14:28:05 +02:00
u8x8.clear();
u8x8.setFlipMode(1);
u8x8.setInverseFont(1);
u8x8.draw2x2String(0, 0, Productname);
u8x8.setInverseFont(0);
u8x8.draw2x2String(2, 2, Productname);
2018-12-19 12:32:25 +01:00
delay(1500);
2018-07-15 14:28:05 +02:00
u8x8.setFlipMode(0);
u8x8.clear();
#ifdef DISPLAY_FLIP
u8x8.setFlipMode(1);
#endif
// Display chip information
#ifdef 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.");
#endif // VERBOSE
u8x8.print(Productname);
u8x8.print(" v");
u8x8.println(PROGVERSION);
#ifdef HAS_LORA
u8x8.println("DEVEUI:");
os_getDevEui((u1_t *)buf);
DisplayKey(buf, 8, true);
#endif // HAS_LORA
2018-12-19 12:32:25 +01:00
delay(3000);
2018-07-15 14:28:05 +02:00
u8x8.clear();
u8x8.setPowerSave(!cfg.screenon); // set display off if disabled
u8x8.draw2x2String(0, 0, "PAX:0");
#ifdef 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);
} // init_display
2018-07-22 08:41:41 +02:00
void refreshtheDisplay() {
2018-07-15 14:28:05 +02:00
// block i2c bus access
2019-01-26 12:32:17 +01:00
if (I2C_MUTEX_LOCK()) {
// set display on/off according to current device configuration
if (DisplayState != cfg.screenon) {
DisplayState = cfg.screenon;
u8x8.setPowerSave(!cfg.screenon);
}
// if display is switched off we don't refresh it and save time
if (!DisplayState)
return;
uint8_t msgWaiting;
char buff[16]; // 16 chars line buffer
2019-01-29 09:03:18 +01:00
const char timeNosyncSymbol = '?';
#ifdef HAS_IF482
const char timesyncSymbol = '°';
#else
const char timesyncSymbol = '*';
#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
2018-07-15 14:28:05 +02:00
2018-07-21 21:50:39 +02:00
// update Battery status (line 2)
#ifdef HAS_BATTERY_PROBE
u8x8.setCursor(0, 2);
u8x8.printf("B:%.2fV", batt_voltage / 1000.0);
2018-07-21 21:50:39 +02:00
#endif
// update GPS status (line 2)
2018-07-15 14:28:05 +02:00
#ifdef HAS_GPS
// have we ever got valid gps data?
if (gps.passedChecksum() > 0) {
u8x8.setCursor(9, 2);
if (!gps.location.isValid()) // if no fix then display Sats value inverse
{
u8x8.setInverseFont(1);
u8x8.printf("Sats:%.2d", gps.satellites.value());
u8x8.setInverseFont(0);
} else
u8x8.printf("Sats:%.2d", gps.satellites.value());
}
2018-07-15 14:28:05 +02:00
#endif
// update bluetooth counter + LoRa SF (line 3)
2018-07-15 14:28:05 +02:00
#ifdef BLECOUNTER
u8x8.setCursor(0, 3);
if (cfg.blescan)
u8x8.printf("BLTH:%-5d", macs_ble);
else
u8x8.printf("%s", "BLTH:off");
2018-07-15 14:28:05 +02:00
#endif
#ifdef HAS_LORA
u8x8.setCursor(11, 3);
u8x8.printf("SF:");
if (cfg.adrmode) // if ADR=on then display SF value inverse
u8x8.setInverseFont(1);
u8x8.printf("%c%c", lora_datarate[LMIC.datarate * 2],
lora_datarate[LMIC.datarate * 2 + 1]);
if (cfg.adrmode) // switch off inverse if it was turned on
u8x8.setInverseFont(0);
2018-07-15 14:28:05 +02:00
#endif // HAS_LORA
// update wifi counter + channel display (line 4)
u8x8.setCursor(0, 4);
u8x8.printf("WIFI:%-5d", macs_wifi);
u8x8.setCursor(11, 4);
u8x8.printf("ch:%02d", channel);
2018-07-15 14:28:05 +02:00
// update RSSI limiter status & free memory display (line 5)
u8x8.setCursor(0, 5);
u8x8.printf(!cfg.rssilimit ? "RLIM:off " : "RLIM:%-4d", cfg.rssilimit);
u8x8.setCursor(10, 5);
u8x8.printf("%4dKB", getFreeRAM() / 1024);
2018-07-15 14:28:05 +02:00
#ifdef HAS_LORA
u8x8.setCursor(0, 6);
#ifndef HAS_RTC
// update LoRa status display (line 6)
u8x8.printf("%-16s", display_line6);
#else
// update time/date display (line 6)
2019-01-28 00:38:31 +01:00
time_t t = myTZ.toLocal(now());
2019-01-29 09:03:18 +01:00
char timeState =
timeStatus() == timeSet ? timesyncSymbol : timeNosyncSymbol;
#ifdef RTC_INT // make timestatus symbol blinking
if (second(t) % 2)
timeState = ' ';
#endif // RTC_INT
u8x8.printf("%02d:%02d:%02d%c %2d.%3s", hour(t), minute(t), second(t),
2019-01-29 09:03:18 +01:00
timeState, day(t), printmonth[month(t)]);
#endif // HAS_RTC
// update LMiC event display (line 7)
u8x8.setCursor(0, 7);
u8x8.printf("%-14s", display_line7);
// update LoRa send queue display (line 7)
msgWaiting = uxQueueMessagesWaiting(LoraSendQueue);
if (msgWaiting) {
sprintf(buff, "%2d", msgWaiting);
u8x8.setCursor(14, 7);
u8x8.printf("%-2s", msgWaiting == SEND_QUEUE_SIZE ? "<>" : buff);
} else
u8x8.printf(" ");
2018-08-04 14:37:41 +02:00
2018-07-15 14:28:05 +02:00
#endif // HAS_LORA
2018-08-04 15:27:58 +02:00
2019-01-26 12:32:17 +01:00
I2C_MUTEX_UNLOCK(); // release i2c bus access
}
2018-07-15 14:28:05 +02:00
} // refreshDisplay()
#endif // HAS_DISPLAY