2019-03-13 22:08:05 +01:00
|
|
|
#ifdef HAS_DISPLAY
|
2018-07-15 14:28:05 +02:00
|
|
|
|
2019-01-27 21:02:08 +01:00
|
|
|
/*
|
|
|
|
|
|
|
|
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
|
2019-07-15 19:11:01 +02:00
|
|
|
4|WIFI:abcde ch:ab
|
2019-01-27 21:02:08 +01:00
|
|
|
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
|
|
|
|
|
2019-04-02 22:45:16 +02:00
|
|
|
#define DISPLAY_PAGES (4) // number of display pages
|
2019-04-01 18:01:52 +02:00
|
|
|
|
2018-10-21 19:00:20 +02:00
|
|
|
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"};
|
2018-10-22 14:06:47 +02:00
|
|
|
#elif defined(CFG_as923)
|
2018-10-22 13:43:19 +02:00
|
|
|
const char lora_datarate[] = {"1211100908077BFSNA"};
|
2018-10-22 14:06:47 +02:00
|
|
|
#elif defined(CFG_au921)
|
2018-10-22 13:43:19 +02:00
|
|
|
const char lora_datarate[] = {"1211100908078CNA1211109C8C7C"};
|
2018-10-22 14:06:47 +02:00
|
|
|
#elif defined(CFG_in866)
|
2018-10-22 13:43:19 +02:00
|
|
|
const char lora_datarate[] = {"121110090807FSNA"};
|
2018-07-15 23:40:42 +02:00
|
|
|
#endif
|
|
|
|
|
2019-01-27 21:02:08 +01:00
|
|
|
// helper arry for converting month values to text
|
2019-02-04 20:40:46 +01:00
|
|
|
const char *printmonth[] = {"xxx", "Jan", "Feb", "Mar", "Apr", "May", "Jun",
|
|
|
|
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
|
2019-01-27 21:02:08 +01:00
|
|
|
|
2019-04-01 18:01:52 +02:00
|
|
|
uint8_t DisplayIsOn = 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) {
|
2018-10-03 00:25:05 +02:00
|
|
|
|
2019-02-02 10:35:20 +01:00
|
|
|
// block i2c bus access
|
2019-07-23 17:53:20 +02:00
|
|
|
if (!I2C_MUTEX_LOCK())
|
2019-07-27 11:59:24 +02:00
|
|
|
ESP_LOGV(TAG, "[%0.3f] i2c mutex lock failed", millis() / 1000.0);
|
2019-07-23 17:53:20 +02:00
|
|
|
else {
|
2019-02-02 10:35:20 +01:00
|
|
|
// 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();
|
2018-07-15 14:28:05 +02:00
|
|
|
|
|
|
|
#ifdef DISPLAY_FLIP
|
2019-02-02 10:35:20 +01:00
|
|
|
u8x8.setFlipMode(1);
|
2018-07-15 14:28:05 +02:00
|
|
|
#endif
|
|
|
|
|
|
|
|
// Display chip information
|
2019-03-24 01:05:13 +01:00
|
|
|
#if (VERBOSE)
|
2019-02-02 10:35:20 +01:00
|
|
|
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.");
|
2018-07-15 14:28:05 +02:00
|
|
|
#endif // VERBOSE
|
|
|
|
|
2019-02-02 10:35:20 +01:00
|
|
|
u8x8.print(Productname);
|
|
|
|
u8x8.print(" v");
|
|
|
|
u8x8.println(PROGVERSION);
|
2018-07-15 14:28:05 +02:00
|
|
|
|
2019-03-24 01:05:13 +01:00
|
|
|
#if (HAS_LORA)
|
2019-02-02 10:35:20 +01:00
|
|
|
u8x8.println("DEVEUI:");
|
|
|
|
os_getDevEui((u1_t *)buf);
|
|
|
|
DisplayKey(buf, 8, true);
|
|
|
|
delay(3000);
|
2018-07-15 14:28:05 +02:00
|
|
|
#endif // HAS_LORA
|
2019-02-02 10:35:20 +01:00
|
|
|
u8x8.clear();
|
|
|
|
u8x8.setPowerSave(!cfg.screenon); // set display off if disabled
|
|
|
|
u8x8.draw2x2String(0, 0, "PAX:0");
|
2019-03-24 01:05:13 +01:00
|
|
|
#if (BLECOUNTER)
|
2019-02-02 10:35:20 +01:00
|
|
|
u8x8.setCursor(0, 3);
|
|
|
|
u8x8.printf("BLTH:0");
|
2018-07-15 14:28:05 +02:00
|
|
|
#endif
|
2019-02-02 10:35:20 +01:00
|
|
|
u8x8.setCursor(0, 4);
|
|
|
|
u8x8.printf("WIFI:0");
|
|
|
|
u8x8.setCursor(0, 5);
|
|
|
|
u8x8.printf(!cfg.rssilimit ? "RLIM:off " : "RLIM:%d", cfg.rssilimit);
|
|
|
|
|
|
|
|
I2C_MUTEX_UNLOCK(); // release i2c bus access
|
2019-02-22 22:28:35 +01:00
|
|
|
} // mutex
|
2018-07-15 14:28:05 +02:00
|
|
|
} // init_display
|
|
|
|
|
2019-05-31 13:20:11 +02:00
|
|
|
void refreshTheDisplay(bool nextPage) {
|
2018-07-15 14:28:05 +02:00
|
|
|
|
2019-04-01 18:01:52 +02:00
|
|
|
static uint8_t DisplayPage = 0;
|
2019-02-18 21:51:01 +01:00
|
|
|
|
2019-04-01 18:01:52 +02:00
|
|
|
// if display is switched off we don't refresh it to relax cpu
|
|
|
|
if (!DisplayIsOn && (DisplayIsOn == cfg.screenon))
|
|
|
|
return;
|
|
|
|
|
2019-05-31 13:20:11 +02:00
|
|
|
const time_t t =
|
|
|
|
myTZ.toLocal(now()); // note: call now() here *before* locking mutex!
|
|
|
|
|
2018-12-27 17:09:40 +01:00
|
|
|
// block i2c bus access
|
2019-07-23 17:53:20 +02:00
|
|
|
if (!I2C_MUTEX_LOCK())
|
2019-07-27 11:59:24 +02:00
|
|
|
ESP_LOGV(TAG, "[%0.3f] i2c mutex lock failed", millis() / 1000.0);
|
2019-07-23 17:53:20 +02:00
|
|
|
else {
|
2018-12-27 17:09:40 +01:00
|
|
|
// set display on/off according to current device configuration
|
2019-04-01 18:01:52 +02:00
|
|
|
if (DisplayIsOn != cfg.screenon) {
|
|
|
|
DisplayIsOn = cfg.screenon;
|
2018-12-27 17:09:40 +01:00
|
|
|
u8x8.setPowerSave(!cfg.screenon);
|
|
|
|
}
|
|
|
|
|
2019-04-01 18:01:52 +02:00
|
|
|
if (nextPage) {
|
|
|
|
DisplayPage = (DisplayPage >= DISPLAY_PAGES - 1) ? 0 : (DisplayPage + 1);
|
|
|
|
u8x8.clear();
|
2019-02-22 22:28:35 +01:00
|
|
|
}
|
2018-12-27 17:09:40 +01:00
|
|
|
|
2019-04-01 18:01:52 +02:00
|
|
|
draw_page(t, DisplayPage);
|
|
|
|
|
|
|
|
I2C_MUTEX_UNLOCK(); // release i2c bus access
|
|
|
|
|
|
|
|
} // mutex
|
|
|
|
} // refreshDisplay()
|
|
|
|
|
|
|
|
void draw_page(time_t t, uint8_t page) {
|
|
|
|
|
|
|
|
char timeState, buff[16];
|
|
|
|
uint8_t msgWaiting;
|
2019-07-22 22:00:39 +02:00
|
|
|
#if (HAS_GPS)
|
2019-04-01 18:34:57 +02:00
|
|
|
static bool wasnofix = true;
|
2019-07-22 22:00:39 +02:00
|
|
|
#endif
|
2019-04-01 18:01:52 +02:00
|
|
|
|
2019-04-02 22:45:16 +02:00
|
|
|
// 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
|
|
|
|
|
2019-04-01 18:01:52 +02:00
|
|
|
switch (page % DISPLAY_PAGES) {
|
|
|
|
|
|
|
|
// page 0: parameters overview
|
|
|
|
// page 1: time
|
|
|
|
// page 2: GPS
|
|
|
|
// page 3: BME280/680
|
|
|
|
|
|
|
|
case 0:
|
2018-07-15 14:28:05 +02:00
|
|
|
|
2018-07-21 21:50:39 +02:00
|
|
|
// update Battery status (line 2)
|
2019-04-13 19:22:48 +02:00
|
|
|
#ifdef BAT_MEASURE_ADC
|
2018-12-27 17:09:40 +01:00
|
|
|
u8x8.setCursor(0, 2);
|
2019-01-26 13:43:19 +01:00
|
|
|
u8x8.printf("B:%.2fV", batt_voltage / 1000.0);
|
2018-07-21 21:50:39 +02:00
|
|
|
#endif
|
|
|
|
|
|
|
|
// update GPS status (line 2)
|
2019-03-24 01:05:13 +01:00
|
|
|
#if (HAS_GPS)
|
2019-01-27 21:20:09 +01:00
|
|
|
// 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
|
|
|
|
|
2019-01-27 21:20:09 +01:00
|
|
|
// update bluetooth counter + LoRa SF (line 3)
|
2019-03-24 01:05:13 +01:00
|
|
|
#if (BLECOUNTER)
|
2018-12-27 17:09:40 +01:00
|
|
|
u8x8.setCursor(0, 3);
|
|
|
|
if (cfg.blescan)
|
2019-01-27 21:02:08 +01:00
|
|
|
u8x8.printf("BLTH:%-5d", macs_ble);
|
2018-12-27 17:09:40 +01:00
|
|
|
else
|
|
|
|
u8x8.printf("%s", "BLTH:off");
|
2018-07-15 14:28:05 +02:00
|
|
|
#endif
|
|
|
|
|
2019-03-24 01:05:13 +01:00
|
|
|
#if (HAS_LORA)
|
2018-12-27 17:09:40 +01:00
|
|
|
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
|
|
|
|
|
2019-07-15 19:11:01 +02:00
|
|
|
// line 4: update wifi counter + channel display
|
2018-12-27 17:09:40 +01:00
|
|
|
u8x8.setCursor(0, 4);
|
2019-01-27 21:02:08 +01:00
|
|
|
u8x8.printf("WIFI:%-5d", macs_wifi);
|
2019-07-15 19:11:01 +02:00
|
|
|
u8x8.setCursor(11, 4);
|
|
|
|
u8x8.printf("ch:%02d", channel);
|
2018-07-15 14:28:05 +02:00
|
|
|
|
2019-03-24 19:49:44 +01:00
|
|
|
// line 5: update RSSI limiter status & free memory display
|
2018-12-27 17:09:40 +01:00
|
|
|
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
|
|
|
|
2019-03-24 19:49:44 +01:00
|
|
|
// line 6: update time-of-day or LoRa status display
|
2018-12-27 17:09:40 +01:00
|
|
|
u8x8.setCursor(0, 6);
|
2019-03-24 19:49:44 +01:00
|
|
|
#if (TIME_SYNC_INTERVAL)
|
|
|
|
// we want a systime display instead LoRa status
|
2019-02-25 00:26:46 +01:00
|
|
|
timeState = TimePulseTick ? ' ' : timeSetSymbols[timeSource];
|
2019-02-18 21:51:01 +01:00
|
|
|
TimePulseTick = false;
|
2019-03-24 19:49:44 +01:00
|
|
|
// display inverse timeState if clock controller is enabled
|
|
|
|
#if (defined HAS_DCF77) || (defined HAS_IF482)
|
2019-04-01 18:01:52 +02:00
|
|
|
u8x8.printf("%02d:%02d:%02d", hour(t), minute(t), second(t));
|
2019-03-24 19:49:44 +01:00
|
|
|
u8x8.setInverseFont(1);
|
|
|
|
u8x8.printf("%c", timeState);
|
|
|
|
u8x8.setInverseFont(0);
|
|
|
|
u8x8.printf(" %2d.%3s", day(t), printmonth[month(t)]);
|
|
|
|
#else
|
2019-02-22 22:28:35 +01:00
|
|
|
u8x8.printf("%02d:%02d:%02d%c %2d.%3s", hour(t), minute(t), second(t),
|
|
|
|
timeState, day(t), printmonth[month(t)]);
|
2019-03-24 19:49:44 +01:00
|
|
|
#endif // HAS_DCF77 || HAS_IF482
|
|
|
|
|
|
|
|
#else // update LoRa status display
|
|
|
|
#if (HAS_LORA)
|
|
|
|
u8x8.printf("%-16s", display_line6);
|
2019-02-04 20:02:30 +01:00
|
|
|
#endif
|
2018-12-27 17:09:40 +01:00
|
|
|
|
2019-03-24 19:49:44 +01:00
|
|
|
#endif // TIME_SYNC_INTERVAL
|
|
|
|
|
|
|
|
#if (HAS_LORA)
|
|
|
|
// line 7: update LMiC event display
|
2018-12-27 17:09:40 +01:00
|
|
|
u8x8.setCursor(0, 7);
|
|
|
|
u8x8.printf("%-14s", display_line7);
|
|
|
|
|
2019-03-24 19:49:44 +01:00
|
|
|
// update LoRa send queue display
|
2018-12-27 17:09:40 +01:00
|
|
|
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-04-01 18:01:52 +02:00
|
|
|
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);
|
|
|
|
|
|
|
|
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) {
|
2019-04-01 18:34:57 +02:00
|
|
|
// line 5: clear "No fix"
|
|
|
|
if (wasnofix) {
|
|
|
|
snprintf(buff, sizeof(buff), " ");
|
|
|
|
u8x8.draw2x2String(2, 5, buff);
|
|
|
|
wasnofix = false;
|
|
|
|
}
|
2019-04-01 18:01:52 +02:00
|
|
|
// line 3-4: GPS latitude
|
2019-07-16 21:33:50 +02:00
|
|
|
snprintf(buff, sizeof(buff), "%c%07.4f",
|
2019-04-01 18:34:57 +02:00
|
|
|
gps.location.rawLat().negative ? 'S' : 'N', gps.location.lat());
|
2019-04-01 18:01:52 +02:00
|
|
|
u8x8.draw2x2String(0, 3, buff);
|
|
|
|
|
|
|
|
// line 6-7: GPS longitude
|
2019-07-16 21:33:50 +02:00
|
|
|
snprintf(buff, sizeof(buff), "%c%07.4f",
|
2019-04-01 18:34:57 +02:00
|
|
|
gps.location.rawLat().negative ? 'W' : 'E', gps.location.lng());
|
2019-04-01 18:01:52 +02:00
|
|
|
u8x8.draw2x2String(0, 6, buff);
|
2019-04-01 18:34:57 +02:00
|
|
|
|
2019-04-01 18:01:52 +02:00
|
|
|
} else {
|
|
|
|
snprintf(buff, sizeof(buff), "No fix");
|
2019-04-01 18:34:57 +02:00
|
|
|
u8x8.setInverseFont(1);
|
2019-04-01 18:01:52 +02:00
|
|
|
u8x8.draw2x2String(2, 5, buff);
|
2019-04-01 18:34:57 +02:00
|
|
|
u8x8.setInverseFont(0);
|
|
|
|
wasnofix = true;
|
2019-04-01 18:01:52 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
#else
|
|
|
|
snprintf(buff, sizeof(buff), "No GPS");
|
|
|
|
u8x8.draw2x2String(2, 5, buff);
|
|
|
|
#endif
|
|
|
|
|
|
|
|
break; // page2
|
|
|
|
|
2019-04-02 22:45:16 +02:00
|
|
|
case 3:
|
|
|
|
|
|
|
|
#if (HAS_BME)
|
|
|
|
// line 2-3: Temp
|
2019-07-25 23:22:09 +02:00
|
|
|
snprintf(buff, sizeof(buff), "TMP:%-2.1f", bme_status.temperature);
|
2019-04-02 22:45:16 +02:00
|
|
|
u8x8.draw2x2String(0, 2, buff);
|
|
|
|
|
|
|
|
// line 4-5: Hum
|
2019-07-25 23:22:09 +02:00
|
|
|
snprintf(buff, sizeof(buff), "HUM:%-2.1f", bme_status.humidity);
|
2019-04-02 22:45:16 +02:00
|
|
|
u8x8.draw2x2String(0, 4, buff);
|
|
|
|
|
|
|
|
#ifdef HAS_BME680
|
|
|
|
// line 6-7: IAQ
|
2019-07-25 23:22:09 +02:00
|
|
|
snprintf(buff, sizeof(buff), "IAQ:%-3.0f", bme_status.iaq);
|
2019-04-02 22:45:16 +02:00
|
|
|
u8x8.draw2x2String(0, 6, buff);
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#else
|
|
|
|
snprintf(buff, sizeof(buff), "No BME");
|
|
|
|
u8x8.draw2x2String(2, 5, buff);
|
|
|
|
#endif
|
|
|
|
|
|
|
|
break; // page3
|
|
|
|
|
2019-04-01 18:01:52 +02:00
|
|
|
default:
|
|
|
|
break; // default
|
|
|
|
|
|
|
|
} // switch
|
|
|
|
|
|
|
|
} // draw_page
|
2018-07-15 14:28:05 +02:00
|
|
|
|
2019-03-07 15:05:52 +01:00
|
|
|
#endif // HAS_DISPLAY
|