From 43a37ee0c0f82af99dd1773b3897a0cd256ffaea Mon Sep 17 00:00:00 2001 From: Florian Ludwig Date: Sun, 21 Apr 2019 18:11:47 +0200 Subject: [PATCH 01/10] add gitlab-ci.yml --- .gitlab-ci.yml | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 .gitlab-ci.yml diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml new file mode 100644 index 00000000..ada4998b --- /dev/null +++ b/.gitlab-ci.yml @@ -0,0 +1,11 @@ +image: python:2.7 + +stages: + - test + +.job_template: &pio_run + script: + - "platformio ci --lib='.' --board=uno --board=teensy31 --board=nodemcuv2 $PLATFORMIO_CI_EXTRA_ARGS" + +before_script: + - "pip install -U platformio" \ No newline at end of file From 45b51441ecdab915fd00c17e5ba067901166ca7a Mon Sep 17 00:00:00 2001 From: Verkehrsrot Date: Fri, 3 May 2019 20:24:42 +0200 Subject: [PATCH 02/10] button handling improvment --- include/button.h | 3 +++ platformio.ini | 3 ++- src/button.cpp | 41 ++++++++++++++++++++++++++++++++++------- src/main.cpp | 42 +++++++++++++++--------------------------- 4 files changed, 54 insertions(+), 35 deletions(-) diff --git a/include/button.h b/include/button.h index b6951ceb..e7799847 100644 --- a/include/button.h +++ b/include/button.h @@ -1,6 +1,9 @@ #ifndef _BUTTON_H #define _BUTTON_H +#include + +void button_init(int pin); void readButton(); #endif \ No newline at end of file diff --git a/platformio.ini b/platformio.ini index 0cd36d90..f2f2a7d9 100644 --- a/platformio.ini +++ b/platformio.ini @@ -31,7 +31,7 @@ description = Paxcounter is a proof-of-concept ESP32 device for metering passeng [common] ; for release_version use max. 10 chars total, use any decimal format like "a.b.c" -release_version = 1.7.55 +release_version = 1.7.6 ; 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 @@ -60,6 +60,7 @@ lib_deps_basic = ArduinoJson@^5.13.1 Timezone@^1.2.2 RTC@^2.3.0 + SimpleButton lib_deps_all = ${common.lib_deps_basic} ${common.lib_deps_lora} diff --git a/src/button.cpp b/src/button.cpp index 68e29d4e..ed34367f 100644 --- a/src/button.cpp +++ b/src/button.cpp @@ -3,17 +3,44 @@ #include "globals.h" #include "button.h" +using namespace simplebutton; + // Local logging tag static const char TAG[] = __FILE__; -void readButton() { - ESP_LOGI(TAG, "Button pressed"); -#ifdef HAS_DISPLAY - refreshtheDisplay(true); // switch to next display page +static Button *b = NULL; + +void button_init(int pin) { +#ifdef BUTTON_PULLDOWN + b = new Button(pin); #else - payload.reset(); - payload.addButton(0x01); - SendPayload(BUTTONPORT, prio_normal); + b = new ButtonPullup(pin); #endif + + // attach events to the button + + b->setOnDoubleClicked([]() {}); + + b->setOnClicked([]() { +#ifdef HAS_DISPLAY + refreshtheDisplay(true); // switch to next display page +#else + payload.reset(); + payload.addButton(0x01); + SendPayload(BUTTONPORT, prio_normal); +#endif + }); + + b->setOnHolding([]() { +#if (HAS_LORA) + cfg.adrmode = !cfg.adrmode; + LMIC_setAdrMode(cfg.adrmode); +#endif + }); + + // attach interrupt to the button + attachInterrupt(digitalPinToInterrupt(pin), ButtonIRQ, CHANGE); } + +void readButton() { b->update(); } #endif \ No newline at end of file diff --git a/src/main.cpp b/src/main.cpp index 96198e4a..965dc442 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -265,20 +265,6 @@ void setup() { esp_coex_prefer_t)ESP_COEX_PREFER_WIFI)); // configure Wifi/BT coexist lib #endif -// initialize button -#ifdef HAS_BUTTON - strcat_P(features, " BTN_"); -#ifdef BUTTON_PULLUP - strcat_P(features, "PU"); - // install button interrupt (pullup mode) - pinMode(HAS_BUTTON, INPUT_PULLUP); -#else - strcat_P(features, "PD"); - // install button interrupt (pulldown mode) - pinMode(HAS_BUTTON, INPUT_PULLDOWN); -#endif // BUTTON_PULLUP -#endif // HAS_BUTTON - // initialize gps #if (HAS_GPS) strcat_P(features, " GPS"); @@ -364,9 +350,6 @@ void setup() { esp_wifi_deinit(); #endif - // show compiled features - ESP_LOGI(TAG, "Features:%s", features); - // start state machine ESP_LOGI(TAG, "Starting Interrupt Handler..."); xTaskCreatePinnedToCore(irqHandler, // task function @@ -410,7 +393,18 @@ void setup() { timerAlarmEnable(displayIRQ); #endif - // gps buffer read interrupt + // initialize button +#ifdef HAS_BUTTON + strcat_P(features, " BTN_"); +#ifdef BUTTON_PULLUP + strcat_P(features, "PU"); +#else + strcat_P(features, "PD"); +#endif // BUTTON_PULLUP + button_init(HAS_BUTTON); +#endif // HAS_BUTTON + + // gps buffer read interrupt #if (HAS_GPS) gpsIRQ = timerBegin(2, 80, true); timerAttachInterrupt(gpsIRQ, &GpsIRQ, true); @@ -422,15 +416,6 @@ void setup() { sendcycler.attach(SENDCYCLE * 2, sendcycle); housekeeper.attach(HOMECYCLE, housekeeping); -// button interrupt -#ifdef HAS_BUTTON -#ifdef BUTTON_PULLUP - attachInterrupt(digitalPinToInterrupt(HAS_BUTTON), ButtonIRQ, RISING); -#else - attachInterrupt(digitalPinToInterrupt(HAS_BUTTON), ButtonIRQ, FALLING); -#endif -#endif // HAS_BUTTON - #if (TIME_SYNC_INTERVAL) #if (!(TIME_SYNC_LORAWAN) && !(TIME_SYNC_LORASERVER) && !defined HAS_GPS && \ @@ -453,6 +438,9 @@ void setup() { #endif // TIME_SYNC_INTERVAL + // show compiled features + ESP_LOGI(TAG, "Features:%s", features); + } // setup() void loop() { From 0060b101df331c3b4fcdae76e6fcb232daa2ea74 Mon Sep 17 00:00:00 2001 From: Alex Goris Date: Sun, 5 May 2019 23:43:18 +0200 Subject: [PATCH 03/10] feat(LED Matrix Display): Added support for a LED Matrix display This commit adds support for a specific LED Matrix display, which can be used to show the number of found devices on a rather large display. We (hackerspace Brixel) used this on the mini Maker Faire Gent 2019 to show the number of found devices throughout the event --- include/globals.h | 6 +- include/irqhandler.h | 5 + include/ledmatrixdisplay.h | 17 + include/ledmatrixfonts.h | 40 ++ platformio.ini | 3 + src/irqhandler.cpp | 17 + src/ledmatrixdisplay.cpp | 135 ++++++ src/ledmatrixfonts.cpp | 903 +++++++++++++++++++++++++++++++++++++ src/main.cpp | 22 +- src/paxcounter.conf | 15 + 10 files changed, 1160 insertions(+), 3 deletions(-) create mode 100644 include/ledmatrixdisplay.h create mode 100644 include/ledmatrixfonts.h create mode 100644 src/ledmatrixdisplay.cpp create mode 100644 src/ledmatrixfonts.cpp diff --git a/include/globals.h b/include/globals.h index 7b427e5a..a3edad17 100644 --- a/include/globals.h +++ b/include/globals.h @@ -113,7 +113,7 @@ extern uint16_t volatile macs_total, macs_wifi, macs_ble, batt_voltage; // display values extern bool volatile TimePulseTick; // 1sec pps flag set by GPS or RTC extern timesource_t timeSource; -extern hw_timer_t *displayIRQ, *ppsIRQ, *gpsIRQ; +extern hw_timer_t *displayIRQ, *matrixDisplayIRQ, *ppsIRQ, *gpsIRQ; extern SemaphoreHandle_t I2Caccess; extern TaskHandle_t irqHandlerTask, ClockTask; extern TimerHandle_t WifiChanTimer; @@ -138,6 +138,10 @@ extern time_t volatile gps_pps_time; #include "display.h" #endif +#ifdef HAS_MATRIX_DISPLAY +#include "ledmatrixdisplay.h" +#endif + #ifdef HAS_BUTTON #include "button.h" #endif diff --git a/include/irqhandler.h b/include/irqhandler.h index 67af99ba..e00d4d12 100644 --- a/include/irqhandler.h +++ b/include/irqhandler.h @@ -3,6 +3,7 @@ #define DISPLAY_IRQ 0x01 #define BUTTON_IRQ 0x02 +#define MATRIX_DISPLAY_IRQ 0x03 #define SENDCYCLE_IRQ 0x04 #define CYCLIC_IRQ 0x08 #define TIMESYNC_IRQ 0x10 @@ -23,6 +24,10 @@ int unmask_user_IRQ(); void IRAM_ATTR DisplayIRQ(); #endif +#ifdef HAS_MATRIX_DISPLAY +void IRAM_ATTR MatrixDisplayIRQ(); +#endif + #ifdef HAS_BUTTON void IRAM_ATTR ButtonIRQ(); #endif diff --git a/include/ledmatrixdisplay.h b/include/ledmatrixdisplay.h new file mode 100644 index 00000000..227f300d --- /dev/null +++ b/include/ledmatrixdisplay.h @@ -0,0 +1,17 @@ +#ifndef _MATRIX_DISPLAY_H +#define _MATRIX_DISPLAY_H + +#include "LEDMatrix.h" +#include "ledmatrixfonts.h" + +extern uint8_t MatrixDisplayIsOn; + +extern LEDMatrix matrix; + +void init_matrix_display(const char *Productname, const char *Version); +void refreshTheMatrixDisplay(void); +void DrawNumber(String strNum, uint8_t iDotPos = 0); +uint8_t GetCharFromFont(char cChar); +uint8_t GetCharWidth(char cChar); + +#endif \ No newline at end of file diff --git a/include/ledmatrixfonts.h b/include/ledmatrixfonts.h new file mode 100644 index 00000000..1539465a --- /dev/null +++ b/include/ledmatrixfonts.h @@ -0,0 +1,40 @@ +// Fonts.h + +#ifndef _FONTS_h +#define _FONTS_h + +#include "Arduino.h" + +struct FONT_CHAR_INFO { + uint8_t width; // width in bits + uint8_t height; + uint16_t offset; // offset of char into char array +}; + +struct FONT_INFO { + uint8_t CharHeight; + char StartChar; + char EndChar; + uint8_t SpaceWidth; + const FONT_CHAR_INFO *Descriptors; + const uint8_t *Bitmap; +}; + +// Font data for Microsoft Sans Serif 11pt +extern const uint8_t arialNarrow_17ptBitmaps[]; + +extern const uint8_t gillSansMTCondensed_18ptBitmaps[]; +extern const FONT_INFO gillSansMTCondensed_18ptFontInfo; +extern const FONT_CHAR_INFO gillSansMTCondensed_18ptDescriptors[]; + +// Font data for Gill Sans MT Condensed 16pt +extern const uint8_t gillSansMTCondensed_16ptBitmaps[]; +extern const FONT_INFO gillSansMTCondensed_16ptFontInfo; +extern const FONT_CHAR_INFO gillSansMTCondensed_16ptDescriptors[]; + +// Font data for Digital-7 18pt +extern const uint8_t digital7_18ptBitmaps[]; +extern const FONT_INFO digital7_18ptFontInfo; +extern const FONT_CHAR_INFO digital7_18ptDescriptors[]; + +#endif \ No newline at end of file diff --git a/platformio.ini b/platformio.ini index 0cd36d90..511be877 100644 --- a/platformio.ini +++ b/platformio.ini @@ -49,6 +49,8 @@ lib_deps_lora = https://github.com/mcci-catena/arduino-lmic.git lib_deps_display = U8g2@>=2.25.7 +lib_deps_matrix_display = + https://github.com/Seeed-Studio/Ultrathin_LED_Matrix.git lib_deps_rgbled = SmartLeds@>=1.1.5 lib_deps_gps = @@ -66,6 +68,7 @@ lib_deps_all = ${common.lib_deps_display} ${common.lib_deps_rgbled} ${common.lib_deps_gps} + ${common.lib_deps_matrix_display} build_flags_basic = -include "src/hal/${PIOENV}.h" -include "src/paxcounter.conf" diff --git a/src/irqhandler.cpp b/src/irqhandler.cpp index 97c026e0..da999da7 100644 --- a/src/irqhandler.cpp +++ b/src/irqhandler.cpp @@ -39,6 +39,12 @@ void irqHandler(void *pvParameters) { refreshtheDisplay(); #endif +// LED Matrix display needs refresh? +#ifdef HAS_MATRIX_DISPLAY + if (InterruptStatus & MATRIX_DISPLAY_IRQ) + refreshTheMatrixDisplay(); +#endif + // gps refresh buffer? #if (HAS_GPS) if (InterruptStatus & GPS_IRQ) @@ -79,6 +85,17 @@ void IRAM_ATTR DisplayIRQ() { } #endif +#ifdef HAS_MATRIX_DISPLAY +void IRAM_ATTR MatrixDisplayIRQ() { + BaseType_t xHigherPriorityTaskWoken = pdFALSE; + + xTaskNotifyFromISR(irqHandlerTask, MATRIX_DISPLAY_IRQ, eSetBits, + &xHigherPriorityTaskWoken); + if (xHigherPriorityTaskWoken) + portYIELD_FROM_ISR(); +} +#endif + #ifdef HAS_BUTTON void IRAM_ATTR ButtonIRQ() { BaseType_t xHigherPriorityTaskWoken = pdFALSE; diff --git a/src/ledmatrixdisplay.cpp b/src/ledmatrixdisplay.cpp new file mode 100644 index 00000000..5c211b40 --- /dev/null +++ b/src/ledmatrixdisplay.cpp @@ -0,0 +1,135 @@ +#ifdef HAS_MATRIX_DISPLAY + +#include "globals.h" + +#define NUMCHARS 5 + +// local Tag for logging +static const char TAG[] = __FILE__; + +uint8_t MatrixDisplayIsOn = 0; +unsigned long ulLastNumMacs = 0; + +LEDMatrix matrix(LED_MATRIX_LA_74138, LED_MATRIX_LB_74138, LED_MATRIX_LC_74138, + LED_MATRIX_LD_74138, LED_MATRIX_EN_74138, LED_MATRIX_DATA_R1, + LED_MATRIX_LATCHPIN, LED_MATRIX_CLOCKPIN); + +// Display Buffer 128 = 64 * 16 / 8 +uint8_t displaybuf[LED_MATRIX_WIDTH * LED_MATRIX_HEIGHT / NUMCHARS]; + +const FONT_INFO *ActiveFontInfo = &digital7_18ptFontInfo; +const uint8_t *iaActiveFont = ActiveFontInfo->Bitmap; +const FONT_CHAR_INFO *ActiveFontCharInfo = ActiveFontInfo->Descriptors; + +void init_matrix_display(const char *Productname, const char *Version) { + ESP_LOGI(TAG, "Initializing LED Matrix display"); + matrix.begin(displaybuf, LED_MATRIX_WIDTH, LED_MATRIX_HEIGHT); + matrix.reverse(); + matrix.clear(); + DrawNumber(String("0")); +} // init_display + +void refreshTheMatrixDisplay() { + + if (ulLastNumMacs != macs.size()) { + ulLastNumMacs = macs.size(); + matrix.clear(); + DrawNumber(String(macs.size())); + ESP_LOGI(TAG, "Setting display to counter: %lu", macs.size()); + } + + matrix.scan(); +} + +// (x, y) top-left position, x should be multiple of 8 +void DrawChar(uint16_t x, uint16_t y, char cChar) { + // Get address of char in font char descriptor from font descriptor + auto CharDescAddress = (cChar - ActiveFontInfo->StartChar); + + // Get offset of char into font bitmap + uint16_t FontBitmapOffset = ActiveFontCharInfo[CharDescAddress].offset; + // Serial.printf("Address of %c is %i, bitmap offset is %u\r\n", cChar, + // CharDescAddress, FontBitmapOffset); + + // Check font height, if it's less than matrix height we need to + // add some empty lines to font does not stick to the top + if (ActiveFontInfo->CharHeight < (LED_MATRIX_HEIGHT - y)) { + uint8_t FillerLines = (LED_MATRIX_HEIGHT - y) - ActiveFontInfo->CharHeight; + if (FillerLines % 2 == 0) { + // Use floor (round down) to get heighest possible divider + // for missing lines + y = floor(FillerLines / 2); + } + } + + int iDst = (x / 8) + (y * 8); + int Shift = x % 8; + // Serial.printf("Got hex '%x'\r\n", pSrc); + for (uint8_t i = 0; i < ActiveFontCharInfo[CharDescAddress].height; i++) { + int iDigitA = iaActiveFont[FontBitmapOffset]; + + int Left = iDigitA >> Shift; + int Right = iDigitA << (8 - Shift); + + displaybuf[iDst] |= Left; + displaybuf[iDst + 1] |= Right; + + if (ActiveFontCharInfo[CharDescAddress].width > 8) { + int iDigitB = iaActiveFont[FontBitmapOffset + 1]; + Left = iDigitB >> Shift; + Right = iDigitB << (8 - Shift); + + displaybuf[iDst + 1] |= Left; + displaybuf[iDst + 2] |= Right; + FontBitmapOffset++; + } + + FontBitmapOffset++; + iDst += 8; + } +} + +void DrawNumber(String strNum, uint8_t iDotPos) { + uint8_t iNumLength = strNum.length(); + uint8_t iDigitPos = 0; + + // Serial.printf("Showing number '%s' (length: %i)\r\n", strNum.c_str(), + // iNumLength); + for (int i = 0; i < iNumLength; i++) { + // Serial.printf("Showing char '%c' at x:%i y:%i\r\n", + // strNum.charAt(i), + // iDigitPos, 0); + DrawChar(iDigitPos, 0, strNum.charAt(i)); + if (i + 1 == iDotPos) { + // matrix.drawRect((iDigitPos * 8) - 1, 15, iDigitPos * 8, + // 16, 1); + iDigitPos = iDigitPos + GetCharWidth(strNum.charAt(i)) + + ActiveFontInfo->SpaceWidth; + DrawChar(iDigitPos, 0, '.'); + iDigitPos = iDigitPos + GetCharWidth('.') + ActiveFontInfo->SpaceWidth; + } else { + iDigitPos = iDigitPos + GetCharWidth(strNum.charAt(i)) + + ActiveFontInfo->SpaceWidth; + } + } +} + +uint8_t GetCharFromFont(char cChar) { + auto cStartChar = ActiveFontInfo->StartChar; + auto iCharLocation = cChar - cStartChar; + auto iCharBitmap = iaActiveFont[iCharLocation]; + + return iCharBitmap; +} + +uint8_t GetCharWidth(char cChar) { + // Get address of char in font char descriptor from font descriptor + auto CharDescAddress = (cChar - ActiveFontInfo->StartChar); + + // Get offset of char into font bitmap + auto CharDescriptor = ActiveFontCharInfo[CharDescAddress]; + // Serial.printf("Char %c is %i wide\r\n", cChar, CharDescriptor.width); + return CharDescriptor.width; +} + +#endif // HAS_MATRIX_DISPLAY \ No newline at end of file diff --git a/src/ledmatrixfonts.cpp b/src/ledmatrixfonts.cpp new file mode 100644 index 00000000..1dfa2158 --- /dev/null +++ b/src/ledmatrixfonts.cpp @@ -0,0 +1,903 @@ +#include "ledmatrixfonts.h" +#include "Arduino.h" +// +// Font data for Arial Narrow 17pt +// + +// Character bitmaps for Arial Narrow 17pt +const uint8_t arialNarrow_17ptBitmaps[] = { + // @0 '-' (10 pixels wide) + 0b00000000, 0b00000000, // + 0b00000000, 0b00000000, // + 0b00000000, 0b00000000, // + 0b00000000, 0b00000000, // + 0b00000000, 0b00000000, // + 0b00000000, 0b00000000, // + 0b00000000, 0b00000000, // + 0b00000000, 0b00000000, // + 0b00000000, 0b00000000, // + 0b00111110, 0b00000000, // ##### + 0b00111110, 0b00000000, // ##### + 0b00000000, 0b00000000, // + 0b00000000, 0b00000000, // + 0b00000000, 0b00000000, // + 0b00000000, 0b00000000, // + 0b00000000, 0b00000000, // + + // @32 '0' (10 pixels wide) + 0b00011110, 0b00000000, // #### + 0b00111111, 0b00000000, // ###### + 0b00110011, 0b00000000, // ## ## + 0b01100001, 0b10000000, // ## ## + 0b01100001, 0b10000000, // ## ## + 0b01100001, 0b10000000, // ## ## + 0b01100001, 0b10000000, // ## ## + 0b01100001, 0b10000000, // ## ## + 0b01100001, 0b10000000, // ## ## + 0b01100001, 0b10000000, // ## ## + 0b01100001, 0b10000000, // ## ## + 0b01100001, 0b10000000, // ## ## + 0b01100001, 0b10000000, // ## ## + 0b00110011, 0b00000000, // ## ## + 0b00111111, 0b00000000, // ###### + 0b00011110, 0b00000000, // #### + + // @64 '1' (10 pixels wide) + 0b00000110, 0b00000000, // ## + 0b00000110, 0b00000000, // ## + 0b00001110, 0b00000000, // ### + 0b00011110, 0b00000000, // #### + 0b00110110, 0b00000000, // ## ## + 0b00100110, 0b00000000, // # ## + 0b00000110, 0b00000000, // ## + 0b00000110, 0b00000000, // ## + 0b00000110, 0b00000000, // ## + 0b00000110, 0b00000000, // ## + 0b00000110, 0b00000000, // ## + 0b00000110, 0b00000000, // ## + 0b00000110, 0b00000000, // ## + 0b00000110, 0b00000000, // ## + 0b00000110, 0b00000000, // ## + 0b00000110, 0b00000000, // ## + + // @96 '2' (10 pixels wide) + 0b00011110, 0b00000000, // #### + 0b00111111, 0b00000000, // ###### + 0b00110011, 0b10000000, // ## ### + 0b01100001, 0b10000000, // ## ## + 0b01100001, 0b10000000, // ## ## + 0b00000001, 0b10000000, // ## + 0b00000001, 0b10000000, // ## + 0b00000011, 0b00000000, // ## + 0b00000111, 0b00000000, // ### + 0b00001110, 0b00000000, // ### + 0b00001100, 0b00000000, // ## + 0b00011000, 0b00000000, // ## + 0b00110000, 0b00000000, // ## + 0b00100000, 0b00000000, // # + 0b01111111, 0b10000000, // ######## + 0b01111111, 0b10000000, // ######## + + // @128 '3' (10 pixels wide) + 0b00011110, 0b00000000, // #### + 0b00111111, 0b00000000, // ###### + 0b01110011, 0b10000000, // ### ### + 0b01100001, 0b10000000, // ## ## + 0b00000001, 0b10000000, // ## + 0b00000011, 0b10000000, // ### + 0b00001111, 0b00000000, // #### + 0b00001110, 0b00000000, // ### + 0b00000011, 0b00000000, // ## + 0b00000001, 0b10000000, // ## + 0b00000001, 0b10000000, // ## + 0b01100001, 0b10000000, // ## ## + 0b01100001, 0b10000000, // ## ## + 0b00110011, 0b10000000, // ## ### + 0b00111111, 0b00000000, // ###### + 0b00011110, 0b00000000, // #### + + // @160 '4' (10 pixels wide) + 0b00000111, 0b00000000, // ### + 0b00000111, 0b00000000, // ### + 0b00001111, 0b00000000, // #### + 0b00001111, 0b00000000, // #### + 0b00011011, 0b00000000, // ## ## + 0b00011011, 0b00000000, // ## ## + 0b00110011, 0b00000000, // ## ## + 0b01100011, 0b00000000, // ## ## + 0b01100011, 0b00000000, // ## ## + 0b11000011, 0b00000000, // ## ## + 0b11111111, 0b11000000, // ########## + 0b11111111, 0b11000000, // ########## + 0b00000011, 0b00000000, // ## + 0b00000011, 0b00000000, // ## + 0b00000011, 0b00000000, // ## + 0b00000011, 0b00000000, // ## + + // @192 '5' (10 pixels wide) + 0b00111111, 0b00000000, // ###### + 0b00111111, 0b00000000, // ###### + 0b00110000, 0b00000000, // ## + 0b00110000, 0b00000000, // ## + 0b01100000, 0b00000000, // ## + 0b01101110, 0b00000000, // ## ### + 0b01111111, 0b00000000, // ####### + 0b01110011, 0b10000000, // ### ### + 0b00000001, 0b10000000, // ## + 0b00000001, 0b10000000, // ## + 0b00000001, 0b10000000, // ## + 0b01100001, 0b10000000, // ## ## + 0b01100001, 0b10000000, // ## ## + 0b00110011, 0b00000000, // ## ## + 0b00111111, 0b00000000, // ###### + 0b00011110, 0b00000000, // #### + + // @224 '6' (10 pixels wide) + 0b00001110, 0b00000000, // ### + 0b00011111, 0b00000000, // ##### + 0b00110011, 0b10000000, // ## ### + 0b00100001, 0b10000000, // # ## + 0b01100000, 0b00000000, // ## + 0b01101110, 0b00000000, // ## ### + 0b01111111, 0b00000000, // ####### + 0b01110011, 0b10000000, // ### ### + 0b01100001, 0b10000000, // ## ## + 0b01100001, 0b10000000, // ## ## + 0b01100001, 0b10000000, // ## ## + 0b01100001, 0b10000000, // ## ## + 0b01100001, 0b10000000, // ## ## + 0b00110011, 0b00000000, // ## ## + 0b00111111, 0b00000000, // ###### + 0b00011110, 0b00000000, // #### + + // @256 '7' (10 pixels wide) + 0b01111111, 0b10000000, // ######## + 0b01111111, 0b10000000, // ######## + 0b00000001, 0b00000000, // # + 0b00000011, 0b00000000, // ## + 0b00000011, 0b00000000, // ## + 0b00000110, 0b00000000, // ## + 0b00000110, 0b00000000, // ## + 0b00000100, 0b00000000, // # + 0b00001100, 0b00000000, // ## + 0b00001100, 0b00000000, // ## + 0b00001100, 0b00000000, // ## + 0b00001100, 0b00000000, // ## + 0b00011000, 0b00000000, // ## + 0b00011000, 0b00000000, // ## + 0b00011000, 0b00000000, // ## + 0b00011000, 0b00000000, // ## + + // @288 '8' (10 pixels wide) + 0b00011110, 0b00000000, // #### + 0b00111111, 0b00000000, // ###### + 0b01110011, 0b10000000, // ### ### + 0b01100001, 0b10000000, // ## ## + 0b01100001, 0b10000000, // ## ## + 0b01110011, 0b10000000, // ### ### + 0b00111111, 0b00000000, // ###### + 0b00111111, 0b00000000, // ###### + 0b00110011, 0b00000000, // ## ## + 0b01100001, 0b10000000, // ## ## + 0b01100001, 0b10000000, // ## ## + 0b01100001, 0b10000000, // ## ## + 0b01100001, 0b10000000, // ## ## + 0b01110011, 0b10000000, // ### ### + 0b00111111, 0b00000000, // ###### + 0b00011110, 0b00000000, // #### + + // @320 '9' (10 pixels wide) + 0b00011110, 0b00000000, // #### + 0b00111111, 0b00000000, // ###### + 0b00110011, 0b00000000, // ## ## + 0b01100001, 0b10000000, // ## ## + 0b01100001, 0b10000000, // ## ## + 0b01100001, 0b10000000, // ## ## + 0b01100001, 0b10000000, // ## ## + 0b01100001, 0b10000000, // ## ## + 0b01110011, 0b10000000, // ### ### + 0b00111111, 0b10000000, // ####### + 0b00011101, 0b10000000, // ### ## + 0b00000001, 0b10000000, // ## + 0b01100001, 0b00000000, // ## # + 0b01110011, 0b00000000, // ### ## + 0b00111110, 0b00000000, // ##### + 0b00011100, 0b00000000, // ### +}; + +// +// Font data for Gill Sans MT Condensed 18pt +// + +// Character bitmaps for Gill Sans MT Condensed 18pt +const uint8_t gillSansMTCondensed_18ptBitmaps[] = { + // @0 '-' (8 pixels wide) + 0b00000000, // + 0b00000000, // + 0b00000000, // + 0b00000000, // + 0b00000000, // + 0b00000000, // + 0b00000000, // + 0b00000000, // + 0b00000000, // + 0b00000000, // + 0b01111100, // ##### + 0b01111100, // ##### + 0b00000000, // + 0b00000000, // + 0b00000000, // + 0b00000000, // + + // @16 '0' (8 pixels wide) + 0b00111100, // #### + 0b01111110, // ###### + 0b01111110, // ###### + 0b11100111, // ### ### + 0b11100111, // ### ### + 0b11100111, // ### ### + 0b11100111, // ### ### + 0b11100111, // ### ### + 0b11100111, // ### ### + 0b11100111, // ### ### + 0b11100111, // ### ### + 0b11100111, // ### ### + 0b11100111, // ### ### + 0b01111110, // ###### + 0b01111110, // ###### + 0b00111100, // #### + + // @32 '1' (8 pixels wide) + 0b00111000, // ### + 0b00111000, // ### + 0b00111000, // ### + 0b00111000, // ### + 0b00111000, // ### + 0b00111000, // ### + 0b00111000, // ### + 0b00111000, // ### + 0b00111000, // ### + 0b00111000, // ### + 0b00111000, // ### + 0b00111000, // ### + 0b00111000, // ### + 0b00111000, // ### + 0b00111000, // ### + 0b00111000, // ### + + // @48 '2' (8 pixels wide) + 0b11111100, // ###### + 0b11111110, // ####### + 0b11001111, // ## #### + 0b00000111, // ### + 0b00000111, // ### + 0b00000111, // ### + 0b00000111, // ### + 0b00000110, // ## + 0b00001110, // ### + 0b00001110, // ### + 0b00011100, // ### + 0b00011100, // ### + 0b00111000, // ### + 0b01110000, // ### + 0b01111111, // ####### + 0b11111111, // ######## + + // @64 '3' (8 pixels wide) + 0b11111000, // ##### + 0b11111100, // ###### + 0b00011110, // #### + 0b00001110, // ### + 0b00001110, // ### + 0b00011100, // ### + 0b00111000, // ### + 0b00111000, // ### + 0b00011100, // ### + 0b00001110, // ### + 0b00001110, // ### + 0b00001110, // ### + 0b00001110, // ### + 0b11011110, // ## #### + 0b11111100, // ###### + 0b11111000, // ##### + + // @80 '4' (8 pixels wide) + 0b00001110, // ### + 0b00001110, // ### + 0b00011110, // #### + 0b00011110, // #### + 0b00111110, // ##### + 0b00111110, // ##### + 0b00111110, // ##### + 0b01101110, // ## ### + 0b01101110, // ## ### + 0b11001110, // ## ### + 0b11001110, // ## ### + 0b11111111, // ######## + 0b00001110, // ### + 0b00001110, // ### + 0b00001110, // ### + 0b00001110, // ### + + // @96 '5' (8 pixels wide) + 0b01111110, // ###### + 0b01111110, // ###### + 0b01110000, // ### + 0b01110000, // ### + 0b01110000, // ### + 0b01110000, // ### + 0b01111000, // #### + 0b01111100, // ##### + 0b00011110, // #### + 0b00001110, // ### + 0b00001110, // ### + 0b00001110, // ### + 0b00001110, // ### + 0b00011100, // ### + 0b11111100, // ###### + 0b11111000, // ##### + + // @112 '6' (8 pixels wide) + 0b00001110, // ### + 0b00011100, // ### + 0b00011100, // ### + 0b00111000, // ### + 0b00111000, // ### + 0b01110000, // ### + 0b01111100, // ##### + 0b11111110, // ####### + 0b11110111, // #### ### + 0b11100111, // ### ### + 0b11100111, // ### ### + 0b11100111, // ### ### + 0b11100111, // ### ### + 0b11111111, // ######## + 0b01111110, // ###### + 0b00111100, // #### + + // @128 '7' (8 pixels wide) + 0b11111111, // ######## + 0b11111111, // ######## + 0b00001110, // ### + 0b00001110, // ### + 0b00001110, // ### + 0b00001110, // ### + 0b00011100, // ### + 0b00011100, // ### + 0b00011100, // ### + 0b00011100, // ### + 0b00111000, // ### + 0b00111000, // ### + 0b00111000, // ### + 0b00110000, // ## + 0b01110000, // ### + 0b01110000, // ### + + // @144 '8' (8 pixels wide) + 0b00111100, // #### + 0b01111110, // ###### + 0b11100111, // ### ### + 0b11100111, // ### ### + 0b11100111, // ### ### + 0b11100111, // ### ### + 0b01111110, // ###### + 0b01111110, // ###### + 0b01111110, // ###### + 0b11100111, // ### ### + 0b11100111, // ### ### + 0b11100111, // ### ### + 0b11100111, // ### ### + 0b11111111, // ######## + 0b01111110, // ###### + 0b00111100, // #### + + // @160 '9' (8 pixels wide) + 0b00111100, // #### + 0b01111110, // ###### + 0b11111111, // ######## + 0b11100111, // ### ### + 0b11100111, // ### ### + 0b11100111, // ### ### + 0b11100111, // ### ### + 0b11101111, // ### #### + 0b01111111, // ####### + 0b00111110, // ##### + 0b00001110, // ### + 0b00011100, // ### + 0b00011100, // ### + 0b00111000, // ### + 0b00111000, // ### + 0b01110000, // ### +}; + +// Character descriptors for Gill Sans MT Condensed 18pt +// { [Char width in bits], [Char height in bits], [Offset into +// gillSansMTCondensed_18ptCharBitmaps in bytes] } +const FONT_CHAR_INFO gillSansMTCondensed_18ptDescriptors[] = { + {8, 16, 0}, // - + {0, 0, 0}, // . + {0, 0, 0}, // / + {8, 16, 16}, // 0 + {8, 16, 32}, // 1 + {8, 16, 48}, // 2 + {8, 16, 64}, // 3 + {8, 16, 80}, // 4 + {8, 16, 96}, // 5 + {8, 16, 112}, // 6 + {8, 16, 128}, // 7 + {8, 16, 144}, // 8 + {8, 16, 160}, // 9 +}; + +// Font information for Gill Sans MT Condensed 18pt +const FONT_INFO gillSansMTCondensed_18ptFontInfo = { + 2, // Character height + '-', // Start character + '9', // End character + 2, // Width, in pixels, of space character + gillSansMTCondensed_18ptDescriptors, + gillSansMTCondensed_18ptBitmaps}; + +// +// Font data for Gill Sans MT Condensed 16pt +// + +// Character bitmaps for Gill Sans MT Condensed 16pt +const uint8_t gillSansMTCondensed_16ptBitmaps[] = { + // @0 '-' (7 pixels wide) + 0b00000000, // + 0b00000000, // + 0b00000000, // + 0b00000000, // + 0b00000000, // + 0b00000000, // + 0b00000000, // + 0b00000000, // + 0b00111110, // ##### + 0b00111110, // ##### + 0b00000000, // + 0b00000000, // + 0b00000000, // + 0b00000000, // + + // @14 '0' (7 pixels wide) + 0b00111000, // ### + 0b01111100, // ##### + 0b11101110, // ### ### + 0b11101110, // ### ### + 0b11101110, // ### ### + 0b11101110, // ### ### + 0b11101110, // ### ### + 0b11101110, // ### ### + 0b11101110, // ### ### + 0b11101110, // ### ### + 0b11101110, // ### ### + 0b11101110, // ### ### + 0b01111100, // ##### + 0b00111000, // ### + + // @28 '1' (7 pixels wide) + 0b00111000, // ### + 0b00111000, // ### + 0b00111000, // ### + 0b00111000, // ### + 0b00111000, // ### + 0b00111000, // ### + 0b00111000, // ### + 0b00111000, // ### + 0b00111000, // ### + 0b00111000, // ### + 0b00111000, // ### + 0b00111000, // ### + 0b00111000, // ### + 0b00111000, // ### + + // @42 '2' (7 pixels wide) + 0b11111000, // ##### + 0b11111100, // ###### + 0b00011110, // #### + 0b00001110, // ### + 0b00001110, // ### + 0b00001110, // ### + 0b00001100, // ## + 0b00011100, // ### + 0b00011100, // ### + 0b00111000, // ### + 0b00111000, // ### + 0b01110000, // ### + 0b01111110, // ###### + 0b11111110, // ####### + + // @56 '3' (7 pixels wide) + 0b11110000, // #### + 0b11111000, // ##### + 0b00011100, // ### + 0b00011100, // ### + 0b00011100, // ### + 0b00011100, // ### + 0b00111000, // ### + 0b00111000, // ### + 0b00011100, // ### + 0b00011100, // ### + 0b00011100, // ### + 0b00011100, // ### + 0b11111000, // ##### + 0b11110000, // #### + + // @70 '4' (7 pixels wide) + 0b00011100, // ### + 0b00011100, // ### + 0b00111100, // #### + 0b00111100, // #### + 0b01111100, // ##### + 0b01111100, // ##### + 0b01111100, // ##### + 0b11011100, // ## ### + 0b11011100, // ## ### + 0b11111110, // ####### + 0b00011100, // ### + 0b00011100, // ### + 0b00011100, // ### + 0b00011100, // ### + + // @84 '5' (7 pixels wide) + 0b01111110, // ###### + 0b01111110, // ###### + 0b01110000, // ### + 0b01110000, // ### + 0b01110000, // ### + 0b01110000, // ### + 0b01111100, // ##### + 0b01111100, // ##### + 0b00011110, // #### + 0b00001110, // ### + 0b00001110, // ### + 0b00011110, // #### + 0b11111100, // ###### + 0b11111000, // ##### + + // @98 '6' (7 pixels wide) + 0b00011100, // ### + 0b00111000, // ### + 0b00111000, // ### + 0b01110000, // ### + 0b01110000, // ### + 0b01111100, // ##### + 0b11111100, // ###### + 0b11101110, // ### ### + 0b11101110, // ### ### + 0b11101110, // ### ### + 0b11101110, // ### ### + 0b11101110, // ### ### + 0b01111100, // ##### + 0b01111000, // #### + + // @112 '7' (7 pixels wide) + 0b11111110, // ####### + 0b11111110, // ####### + 0b00011100, // ### + 0b00011100, // ### + 0b00011100, // ### + 0b00011100, // ### + 0b00011100, // ### + 0b00111000, // ### + 0b00111000, // ### + 0b00111000, // ### + 0b00111000, // ### + 0b01110000, // ### + 0b01110000, // ### + 0b01110000, // ### + + // @126 '8' (7 pixels wide) + 0b01111100, // ##### + 0b01111100, // ##### + 0b11101110, // ### ### + 0b11101110, // ### ### + 0b11101110, // ### ### + 0b11101110, // ### ### + 0b01111100, // ##### + 0b01111100, // ##### + 0b11101110, // ### ### + 0b11101110, // ### ### + 0b11101110, // ### ### + 0b11101110, // ### ### + 0b01111100, // ##### + 0b01111100, // ##### + + // @140 '9' (7 pixels wide) + 0b00111100, // #### + 0b01111100, // ##### + 0b11101110, // ### ### + 0b11101110, // ### ### + 0b11101110, // ### ### + 0b11101110, // ### ### + 0b11101110, // ### ### + 0b01111110, // ###### + 0b01111100, // ##### + 0b00011100, // ### + 0b00011100, // ### + 0b00111000, // ### + 0b00111000, // ### + 0b01110000, // ### +}; + +// Character descriptors for Gill Sans MT Condensed 16pt +// { [Char width in bits], [Char height in bits], [Offset into +// gillSansMTCondensed_16ptCharBitmaps in bytes] } +const FONT_CHAR_INFO gillSansMTCondensed_16ptDescriptors[] = { + {7, 14, 0}, // - + {0, 0, 0}, // . + {0, 0, 0}, // / + {7, 14, 14}, // 0 + {7, 14, 28}, // 1 + {7, 14, 42}, // 2 + {7, 14, 56}, // 3 + {7, 14, 70}, // 4 + {7, 14, 84}, // 5 + {7, 14, 98}, // 6 + {7, 14, 112}, // 7 + {7, 14, 126}, // 8 + {7, 14, 140}, // 9 +}; + +// Font information for Gill Sans MT Condensed 16pt +const FONT_INFO gillSansMTCondensed_16ptFontInfo = { + 2, // Character height + '-', // Start character + '9', // End character + 2, // Width, in pixels, of space character + gillSansMTCondensed_16ptDescriptors, // Character descriptor array + gillSansMTCondensed_16ptBitmaps, // Character bitmap array +}; + +// +// Font data for Digital-7 18pt +// + +// Character bitmaps for Digital-7 18pt +const uint8_t digital7_18ptBitmaps[] = { + // @0 '-' (7 pixels wide) + 0b00000000, // + 0b00000000, // + 0b00000000, // + 0b00000000, // + 0b00000000, // + 0b00000000, // + 0b00000000, // + 0b11111110, // ####### + 0b11111110, // ####### + 0b00000000, // + 0b00000000, // + 0b00000000, // + 0b00000000, // + 0b00000000, // + 0b00000000, // + 0b00000000, // + + // @16 '.' (3 pixels wide) + 0b00000000, // + 0b00000000, // + 0b00000000, // + 0b00000000, // + 0b00000000, // + 0b00000000, // + 0b00000000, // + 0b00000000, // + 0b00000000, // + 0b00000000, // + 0b00000000, // + 0b00000000, // + 0b00000000, // + 0b00000000, // + 0b11100000, // ### + 0b11100000, // ### + + // @32 '0' (11 pixels wide) + 0b00111111, 0b10000000, // ####### + 0b01111111, 0b11000000, // ######### + 0b11100000, 0b11100000, // ### ### + 0b11100000, 0b11100000, // ### ### + 0b11100000, 0b11100000, // ### ### + 0b11100000, 0b11100000, // ### ### + 0b11100000, 0b11100000, // ### ### + 0b11000000, 0b01100000, // ## ## + 0b11000000, 0b01100000, // ## ## + 0b11100000, 0b11100000, // ### ### + 0b11100000, 0b11100000, // ### ### + 0b11100000, 0b11100000, // ### ### + 0b11100000, 0b11100000, // ### ### + 0b11100000, 0b11100000, // ### ### + 0b01111111, 0b11000000, // ######### + 0b00111111, 0b10000000, // ####### + + // @64 '1' (3 pixels wide) + 0b01100000, // ## + 0b11100000, // ### + 0b11100000, // ### + 0b11100000, // ### + 0b11100000, // ### + 0b11100000, // ### + 0b11100000, // ### + 0b01100000, // ## + 0b01100000, // ## + 0b11100000, // ### + 0b11100000, // ### + 0b11100000, // ### + 0b11100000, // ### + 0b11100000, // ### + 0b11100000, // ### + 0b01100000, // ## + + // @80 '2' (11 pixels wide) + 0b11111111, 0b10000000, // ######### + 0b01111111, 0b11000000, // ######### + 0b00000000, 0b11100000, // ### + 0b00000000, 0b11100000, // ### + 0b00000000, 0b11100000, // ### + 0b00000000, 0b11100000, // ### + 0b00000000, 0b11100000, // ### + 0b01111111, 0b11100000, // ########## + 0b11111111, 0b11000000, // ########## + 0b11100000, 0b00000000, // ### + 0b11100000, 0b00000000, // ### + 0b11100000, 0b00000000, // ### + 0b11100000, 0b00000000, // ### + 0b11100000, 0b00000000, // ### + 0b01111111, 0b11000000, // ######### + 0b00111111, 0b11100000, // ######### + + // @112 '3' (10 pixels wide) + 0b11111111, 0b00000000, // ######## + 0b11111111, 0b11000000, // ########## + 0b00000001, 0b11000000, // ### + 0b00000001, 0b11000000, // ### + 0b00000001, 0b11000000, // ### + 0b00000001, 0b11000000, // ### + 0b00000001, 0b11000000, // ### + 0b01111111, 0b11000000, // ######### + 0b01111111, 0b11000000, // ######### + 0b00000001, 0b11000000, // ### + 0b00000001, 0b11000000, // ### + 0b00000001, 0b11000000, // ### + 0b00000001, 0b11000000, // ### + 0b00000001, 0b11000000, // ### + 0b11111111, 0b11000000, // ########## + 0b11111111, 0b00000000, // ######## + + // @144 '4' (11 pixels wide) + 0b11000000, 0b01100000, // ## ## + 0b11100000, 0b11100000, // ### ### + 0b11100000, 0b11100000, // ### ### + 0b11100000, 0b11100000, // ### ### + 0b11100000, 0b11100000, // ### ### + 0b11100000, 0b11100000, // ### ### + 0b11100000, 0b11100000, // ### ### + 0b11111111, 0b11100000, // ########### + 0b01111111, 0b11100000, // ########## + 0b00000000, 0b11100000, // ### + 0b00000000, 0b11100000, // ### + 0b00000000, 0b11100000, // ### + 0b00000000, 0b11100000, // ### + 0b00000000, 0b11100000, // ### + 0b00000000, 0b11100000, // ### + 0b00000000, 0b01100000, // ## + + // @176 '5' (11 pixels wide) + 0b00111111, 0b11000000, // ######## + 0b01111111, 0b10000000, // ######## + 0b11100000, 0b00000000, // ### + 0b11100000, 0b00000000, // ### + 0b11100000, 0b00000000, // ### + 0b11100000, 0b00000000, // ### + 0b11100000, 0b00000000, // ### + 0b11111111, 0b10000000, // ######### + 0b01111111, 0b11100000, // ########## + 0b00000000, 0b11100000, // ### + 0b00000000, 0b11100000, // ### + 0b00000000, 0b11100000, // ### + 0b00000000, 0b11100000, // ### + 0b00000000, 0b11100000, // ### + 0b01111111, 0b11000000, // ######### + 0b11111111, 0b10000000, // ######### + + // @208 '6' (11 pixels wide) + 0b00111111, 0b11000000, // ######## + 0b01111111, 0b10000000, // ######## + 0b11100000, 0b00000000, // ### + 0b11100000, 0b00000000, // ### + 0b11100000, 0b00000000, // ### + 0b11100000, 0b00000000, // ### + 0b11100000, 0b00000000, // ### + 0b11111111, 0b10000000, // ######### + 0b11111111, 0b11100000, // ########### + 0b11100000, 0b11100000, // ### ### + 0b11100000, 0b11100000, // ### ### + 0b11100000, 0b11100000, // ### ### + 0b11100000, 0b11100000, // ### ### + 0b11100000, 0b11100000, // ### ### + 0b11111111, 0b11100000, // ########### + 0b01111111, 0b10000000, // ######## + + // @240 '7' (11 pixels wide) + 0b00111111, 0b10000000, // ####### + 0b01111111, 0b11100000, // ########## + 0b11100000, 0b11100000, // ### ### + 0b11100000, 0b11100000, // ### ### + 0b11100000, 0b11100000, // ### ### + 0b11100000, 0b11100000, // ### ### + 0b11100000, 0b11100000, // ### ### + 0b11000000, 0b01100000, // ## ## + 0b00000000, 0b01100000, // ## + 0b00000000, 0b11100000, // ### + 0b00000000, 0b11100000, // ### + 0b00000000, 0b11100000, // ### + 0b00000000, 0b11100000, // ### + 0b00000000, 0b11100000, // ### + 0b00000000, 0b11100000, // ### + 0b00000000, 0b01100000, // ## + + // @272 '8' (11 pixels wide) + 0b00111111, 0b10000000, // ####### + 0b01111111, 0b11000000, // ######### + 0b11100000, 0b11100000, // ### ### + 0b11100000, 0b11100000, // ### ### + 0b11100000, 0b11100000, // ### ### + 0b11100000, 0b11100000, // ### ### + 0b11100000, 0b11100000, // ### ### + 0b11111111, 0b11100000, // ########### + 0b11111111, 0b11100000, // ########### + 0b11100000, 0b11100000, // ### ### + 0b11100000, 0b11100000, // ### ### + 0b11100000, 0b11100000, // ### ### + 0b11100000, 0b11100000, // ### ### + 0b11100000, 0b11100000, // ### ### + 0b01111111, 0b11000000, // ######### + 0b00111111, 0b10000000, // ####### + + // @304 '9' (11 pixels wide) + 0b00111111, 0b11000000, // ######## + 0b01111111, 0b11100000, // ########## + 0b11100000, 0b11100000, // ### ### + 0b11100000, 0b11100000, // ### ### + 0b11100000, 0b11100000, // ### ### + 0b11100000, 0b11100000, // ### ### + 0b11100000, 0b11100000, // ### ### + 0b11111111, 0b11100000, // ########### + 0b01111111, 0b11100000, // ########## + 0b00000000, 0b11100000, // ### + 0b00000000, 0b11100000, // ### + 0b00000000, 0b11100000, // ### + 0b00000000, 0b11100000, // ### + 0b00000000, 0b11100000, // ### + 0b01111111, 0b11000000, // ######### + 0b11111111, 0b10000000, // ######### +}; + +// Character descriptors for Digital-7 18pt +// { [Char width in bits], [Char height in bits], [Offset into +// digital7_18ptCharBitmaps in bytes] } +const FONT_CHAR_INFO digital7_18ptDescriptors[] = { + {7, 16, 0}, // - + {3, 16, 16}, // . + {0, 0, 0}, // / + {11, 16, 32}, // 0 + {3, 16, 64}, // 1 + {11, 16, 80}, // 2 + {10, 16, 112}, // 3 + {11, 16, 144}, // 4 + {11, 16, 176}, // 5 + {11, 16, 208}, // 6 + {11, 16, 240}, // 7 + {11, 16, 272}, // 8 + {11, 16, 304}, // 9 +}; + +// Font information for Digital-7 18pt +const FONT_INFO digital7_18ptFontInfo = { + 16, // Character height + '-', // Start character + '9', // End character + 2, // Width, in pixels, of space character + digital7_18ptDescriptors, // Character descriptor array + digital7_18ptBitmaps, // Character bitmap array +}; diff --git a/src/main.cpp b/src/main.cpp index 96198e4a..50ecac69 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -85,7 +85,8 @@ uint8_t volatile channel = 0; // channel rotation counter uint16_t volatile macs_total = 0, macs_wifi = 0, macs_ble = 0, batt_voltage = 0; // globals for display -hw_timer_t *ppsIRQ = NULL, *displayIRQ = NULL, *gpsIRQ = NULL; +hw_timer_t *ppsIRQ = NULL, *displayIRQ = NULL, *matrixDisplayIRQ = NULL, + *gpsIRQ = NULL; TaskHandle_t irqHandlerTask = NULL, ClockTask = NULL; SemaphoreHandle_t I2Caccess; @@ -323,6 +324,13 @@ void setup() { init_display(PRODUCTNAME, PROGVERSION); // note: blocking call #endif +// initialize matrix display +#ifdef HAS_MATRIX_DISPLAY + strcat_P(features, " LED_MATRIX"); + MatrixDisplayIsOn = cfg.screenon; + init_matrix_display(PRODUCTNAME, PROGVERSION); // note: blocking call +#endif + // show payload encoder #if PAYLOAD_ENCODER == 1 strcat_P(features, " PLAIN"); @@ -410,7 +418,17 @@ void setup() { timerAlarmEnable(displayIRQ); #endif - // gps buffer read interrupt + // LED Matrix display interrupt +#ifdef HAS_MATRIX_DISPLAY + // https://techtutorialsx.com/2017/10/07/esp32-arduino-timer-interrupts/ + // prescaler 80 -> divides 80 MHz CPU freq to 1 MHz, timer 3, count up + matrixDisplayIRQ = timerBegin(3, 80, true); + timerAttachInterrupt(matrixDisplayIRQ, &MatrixDisplayIRQ, true); + timerAlarmWrite(matrixDisplayIRQ, MATRIX_DISPLAY_SCAN_US, true); + timerAlarmEnable(matrixDisplayIRQ); +#endif + + // gps buffer read interrupt #if (HAS_GPS) gpsIRQ = timerBegin(2, 80, true); timerAttachInterrupt(gpsIRQ, &GpsIRQ, true); diff --git a/src/paxcounter.conf b/src/paxcounter.conf index f042d2cf..f4ec3bfb 100644 --- a/src/paxcounter.conf +++ b/src/paxcounter.conf @@ -110,3 +110,18 @@ // LMIC settings // -> in src/lmic_config.h + +// LED Matrix display settings. Pin numbers work fine for Wemos Lolin32 board (all used pins are on 1 side of the board) +// Note: LED Matrix will only show number of found devices, no other information will be shown for now +//#define HAS_MATRIX_DISPLAY 1 // Uncomment to enable LED matrix display output +#define MATRIX_DISPLAY_SCAN_US 500 // Matrix display scan rate in microseconds (1ms is about 'acceptable') +#define LED_MATRIX_LATCHPIN 13 // Connects to LAT pin on display +#define LED_MATRIX_CLOCKPIN 32 // Connects to CLK pin on display +#define LED_MATRIX_EN_74138 12 // Connects to OE pin on display +#define LED_MATRIX_LA_74138 14 // Connects to LA pin on display +#define LED_MATRIX_LB_74138 27 // Connects to LB pin on display +#define LED_MATRIX_LC_74138 25 // Connects to LC pin on display +#define LED_MATRIX_LD_74138 26 // Connects to LD pin on display +#define LED_MATRIX_DATA_R1 33 // Connects to R1 pin on display +#define LED_MATRIX_WIDTH 64 // Width in pixels (LEDs) of your display +#define LED_MATRIX_HEIGHT 16 // Height in pixels (LEDs ) of your display \ No newline at end of file From 13f89a45e57afeb5c58c5cdc4929022796f915cf Mon Sep 17 00:00:00 2001 From: Alex Goris Date: Mon, 6 May 2019 14:04:46 +0200 Subject: [PATCH 04/10] feat(wemos32oled): Added support for Wemos32 OLED board This commit adds support for what I call the 'Wemos32 OLED' board. It's a Wemos branded board, however it does not appear on Wemos' website. --- platformio.ini | 16 +++++++++++++++ src/hal/wemos32oled.h | 45 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 61 insertions(+) create mode 100644 src/hal/wemos32oled.h diff --git a/platformio.ini b/platformio.ini index 511be877..91466e24 100644 --- a/platformio.ini +++ b/platformio.ini @@ -24,6 +24,7 @@ env_default = generic ;env_default = lolin32litelora ;env_default = lolin32lora ;env_default = lolin32lite +;env_default = wemos32oled ;env_default = octopus32 ;env_default = ecopower, eboxtube, heltec, ttgobeam, lopy4, lopy, ttgov21old, ttgov21new, ttgofox ; @@ -360,6 +361,21 @@ upload_protocol = ${common.upload_protocol} extra_scripts = ${common.extra_scripts} monitor_speed = ${common.monitor_speed} +[env:wemos32oled] +platform = ${common.platform_espressif32} +framework = arduino +board = lolin32 +board_build.partitions = ${common.board_build.partitions} +upload_speed = 921600 +lib_deps = + ${common.lib_deps_basic} + ${common.lib_deps_display} +build_flags = + ${common.build_flags_all} +upload_protocol = ${common.upload_protocol} +extra_scripts = ${common.extra_scripts} +monitor_speed = ${common.monitor_speed} + [env:octopus32] platform = ${common.platform_espressif32} framework = arduino diff --git a/src/hal/wemos32oled.h b/src/hal/wemos32oled.h new file mode 100644 index 00000000..d5c27832 --- /dev/null +++ b/src/hal/wemos32oled.h @@ -0,0 +1,45 @@ +// clang-format off + +#ifndef _WEMOS32OLED_H +#define _WEMOS32OLED_H + +#include + +// Hardware related definitions for TTGO T-Beam board +// (only) for older T-Beam version T22_V05 eternal wiring LORA_IO1 to GPIO33 is needed! +// +// pinouts taken from http://tinymicros.com/wiki/TTGO_T-Beam + +#define HAS_LED NOT_A_PIN // no LED + +//#define HAS_LORA 1 // comment out if device shall not send data via LoRa +//#define CFG_sx1276_radio 1 // HPD13A LoRa SoC +//#define BOARD_HAS_PSRAM // use extra 4MB external RAM +//#define HAS_BUTTON GPIO_NUM_39 // on board button (next to reset) +//#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 + +// GPS settings +//#define HAS_GPS 1 // use on board GPS +//#define GPS_SERIAL 9600, SERIAL_8N1, GPIO_NUM_12, GPIO_NUM_15 // UBlox NEO 6M +//#define GPS_INT GPIO_NUM_34 // 30ns accurary timepulse, to be external wired on pcb: NEO 6M Pin#3 -> GPIO34 + +// enable only if device has these sensors, otherwise comment these lines +// BME680 sensor on I2C bus +//#define HAS_BME 1 // Enable BME sensors in general +//#define HAS_BME680 SDA, SCL +//#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 MY_OLED_SDA (5) +#define MY_OLED_SCL (4) +#define MY_OLED_RST U8X8_PIN_NONE +#define DISPLAY_FLIP 1 // use if display is rotated + +// user defined sensors (if connected) +//#define HAS_SENSORS 1 // comment out if device has user defined sensors + +//#define DISABLE_BROWNOUT 1 // comment out if you want to keep brownout feature + +#endif From 5af7c90d9933a0d8c95d4bf637b910ebd3ab9270 Mon Sep 17 00:00:00 2001 From: Alex Goris Date: Mon, 6 May 2019 14:11:45 +0200 Subject: [PATCH 05/10] docs(README): Updated README: Wemos32 OLED and LED Matrix disp --- README.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index a41e3dcf..910ce69e 100644 --- a/README.md +++ b/README.md @@ -39,7 +39,7 @@ LoLin32lite + [LoraNode32-Lite shield](https://github.com/hallard/LoLin32-Lite-L *SPI only*: - Pyom: WiPy -- WeMos: LoLin32, LoLin32 Lite, WeMos D32 +- WeMos: LoLin32, LoLin32 Lite, WeMos D32, [Wemos32 Oled](https://www.instructables.com/id/ESP32-With-Integrated-OLED-WEMOSLolin-Getting-Star/) - Generic ESP32 Depending on board hardware following features are supported: @@ -54,6 +54,7 @@ Depending on board hardware following features are supported: - Real Time Clock (Maxim DS3231 I2C) - IF482 (serial) and DCF77 (gpio) time telegram generator - Switch external power / battery +- 64x16 pixel LED Matrix display (similar to [this model](https://www.instructables.com/id/64x16-RED-LED-Marquee/)) Target platform must be selected in [platformio.ini](https://github.com/cyberman54/ESP32-Paxcounter/blob/master/platformio.ini).
Hardware dependent settings (pinout etc.) are stored in board files in /hal directory. If you want to use a ESP32 board which is not yet supported, use hal file generic.h and tailor pin mappings to your needs. Pull requests for new boards welcome.
@@ -153,7 +154,7 @@ Output of user sensor data can be switched by user remote control command 0x13 s Output of sensor and peripheral data is internally switched by a bitmask register. Default mask (0xFF) can be tailored by editing *cfg.payloadmask* initialization value in [*configmanager.cpp*](src/configmanager.cpp) following this scheme: | Bit | Sensordata | -|-----|---------------| +| --- | ------------- | | 0 | GPS | | 1 | Beacon alarm | | 2 | BME280/680 | From f1fe7453d8c70c8d0583e54a9801f44050bcc4d3 Mon Sep 17 00:00:00 2001 From: Verkehrsrot Date: Tue, 7 May 2019 11:16:52 +0200 Subject: [PATCH 06/10] Delete .gitlab-ci.yml This was an accidential commit. --- .gitlab-ci.yml | 11 ----------- 1 file changed, 11 deletions(-) delete mode 100644 .gitlab-ci.yml diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml deleted file mode 100644 index ada4998b..00000000 --- a/.gitlab-ci.yml +++ /dev/null @@ -1,11 +0,0 @@ -image: python:2.7 - -stages: - - test - -.job_template: &pio_run - script: - - "platformio ci --lib='.' --board=uno --board=teensy31 --board=nodemcuv2 $PLATFORMIO_CI_EXTRA_ARGS" - -before_script: - - "pip install -U platformio" \ No newline at end of file From 19849c4eea37af415fddc78fef672135ca08b56f Mon Sep 17 00:00:00 2001 From: Verkehrsrot Date: Tue, 7 May 2019 21:17:06 +0200 Subject: [PATCH 07/10] v1.7.61 (LED matrix support) --- include/irqhandler.h | 18 +++++++++--------- include/ledmatrixdisplay.h | 2 -- platformio.ini | 8 ++++---- src/ledmatrixdisplay.cpp | 11 ++++++++++- src/main.cpp | 2 +- 5 files changed, 24 insertions(+), 17 deletions(-) diff --git a/include/irqhandler.h b/include/irqhandler.h index e00d4d12..db5dd2f1 100644 --- a/include/irqhandler.h +++ b/include/irqhandler.h @@ -1,15 +1,15 @@ #ifndef _IRQHANDLER_H #define _IRQHANDLER_H -#define DISPLAY_IRQ 0x01 -#define BUTTON_IRQ 0x02 -#define MATRIX_DISPLAY_IRQ 0x03 -#define SENDCYCLE_IRQ 0x04 -#define CYCLIC_IRQ 0x08 -#define TIMESYNC_IRQ 0x10 -#define MASK_IRQ 0x20 -#define UNMASK_IRQ 0x40 -#define GPS_IRQ 0x80 +#define DISPLAY_IRQ 0x001 +#define BUTTON_IRQ 0x002 +#define SENDCYCLE_IRQ 0x004 +#define CYCLIC_IRQ 0x008 +#define TIMESYNC_IRQ 0x010 +#define MASK_IRQ 0x020 +#define UNMASK_IRQ 0x040 +#define GPS_IRQ 0x080 +#define MATRIX_DISPLAY_IRQ 0x100 #include "globals.h" #include "cyclic.h" diff --git a/include/ledmatrixdisplay.h b/include/ledmatrixdisplay.h index 227f300d..824ce9f1 100644 --- a/include/ledmatrixdisplay.h +++ b/include/ledmatrixdisplay.h @@ -4,8 +4,6 @@ #include "LEDMatrix.h" #include "ledmatrixfonts.h" -extern uint8_t MatrixDisplayIsOn; - extern LEDMatrix matrix; void init_matrix_display(const char *Productname, const char *Version); diff --git a/platformio.ini b/platformio.ini index 940b7a4b..8d8636e4 100644 --- a/platformio.ini +++ b/platformio.ini @@ -6,7 +6,7 @@ ; ---> SELECT TARGET PLATFORM HERE! <--- [platformio] -env_default = generic +;env_default = generic ;env_default = ebox ;env_default = eboxtube ;env_default = ecopower @@ -24,7 +24,7 @@ env_default = generic ;env_default = lolin32litelora ;env_default = lolin32lora ;env_default = lolin32lite -;env_default = wemos32oled +env_default = wemos32oled ;env_default = octopus32 ;env_default = ecopower, eboxtube, heltec, ttgobeam, lopy4, lopy, ttgov21old, ttgov21new, ttgofox ; @@ -32,7 +32,7 @@ description = Paxcounter is a proof-of-concept ESP32 device for metering passeng [common] ; for release_version use max. 10 chars total, use any decimal format like "a.b.c" -release_version = 1.7.6 +release_version = 1.7.61 ; 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 @@ -70,7 +70,6 @@ lib_deps_all = ${common.lib_deps_display} ${common.lib_deps_rgbled} ${common.lib_deps_gps} - ${common.lib_deps_matrix_display} build_flags_basic = -include "src/hal/${PIOENV}.h" -include "src/paxcounter.conf" @@ -371,6 +370,7 @@ upload_speed = 921600 lib_deps = ${common.lib_deps_basic} ${common.lib_deps_display} + ${common.lib_deps_matrix_display} build_flags = ${common.build_flags_all} upload_protocol = ${common.upload_protocol} diff --git a/src/ledmatrixdisplay.cpp b/src/ledmatrixdisplay.cpp index 5c211b40..6a4f39d4 100644 --- a/src/ledmatrixdisplay.cpp +++ b/src/ledmatrixdisplay.cpp @@ -8,7 +8,7 @@ static const char TAG[] = __FILE__; uint8_t MatrixDisplayIsOn = 0; -unsigned long ulLastNumMacs = 0; +static unsigned long ulLastNumMacs = 0; LEDMatrix matrix(LED_MATRIX_LA_74138, LED_MATRIX_LB_74138, LED_MATRIX_LC_74138, LED_MATRIX_LD_74138, LED_MATRIX_EN_74138, LED_MATRIX_DATA_R1, @@ -31,6 +31,15 @@ void init_matrix_display(const char *Productname, const char *Version) { void refreshTheMatrixDisplay() { + // if Matrixdisplay is switched off we don't refresh it to relax cpu + if (!MatrixDisplayIsOn && (MatrixDisplayIsOn == cfg.screenon)) + return; + + // set display on/off according to current device configuration + if (MatrixDisplayIsOn != cfg.screenon) { + MatrixDisplayIsOn = cfg.screenon; + } + if (ulLastNumMacs != macs.size()) { ulLastNumMacs = macs.size(); matrix.clear(); diff --git a/src/main.cpp b/src/main.cpp index d2d4c4ca..a26379fc 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -52,7 +52,7 @@ So don't do it if you do not own a digital oscilloscope. 0 displayIRQ -> display refresh -> 40ms (DISPLAYREFRESH_MS) 1 ppsIRQ -> pps clock irq -> 1sec 2 gpsIRQ -> gps store data -> 300ms -3 unused +3 MatrixDisplayIRQ -> matrix mux cycle -> 0,5ms (MATRIX_DISPLAY_SCAN_US) // Interrupt routines From 49e7b22ad3938ad77f33647a3ca5c8659976e328 Mon Sep 17 00:00:00 2001 From: Verkehrsrot Date: Thu, 9 May 2019 22:12:32 +0200 Subject: [PATCH 08/10] ledmatrixdisplay.h: bugfix --- include/ledmatrixdisplay.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/ledmatrixdisplay.h b/include/ledmatrixdisplay.h index 824ce9f1..5c44676a 100644 --- a/include/ledmatrixdisplay.h +++ b/include/ledmatrixdisplay.h @@ -4,6 +4,8 @@ #include "LEDMatrix.h" #include "ledmatrixfonts.h" +extern uint8_t MatrixDisplayIsOn = 0; + extern LEDMatrix matrix; void init_matrix_display(const char *Productname, const char *Version); From fdd0faf7c1fccf5e11bf480256521dedec33f081 Mon Sep 17 00:00:00 2001 From: cyberman54 Date: Sun, 19 May 2019 17:11:29 +0200 Subject: [PATCH 09/10] ecopower.h: bugfix RTC power on --- src/hal/ecopower.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/hal/ecopower.h b/src/hal/ecopower.h index 2c6fbc1a..0a9d30af 100644 --- a/src/hal/ecopower.h +++ b/src/hal/ecopower.h @@ -14,9 +14,9 @@ //#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% -#define BAT_MEASURE_EN EXT_POWER_SW // Turn power on for messurement +//#define BAT_MEASURE_EN EXT_POWER_SW // Turn power on for measurement -#define EXT_POWER_SW 15 // Switch VDD on pin JP10 +#define EXT_POWER_SW 15 // Switch VDD on pin JP10, needed for RTC DS3231 #define EXT_POWER_ON 0 #define EXT_POWER_OFF 1 From 5c9cf136f0c22313c81afac00e596e8bc25c97fa Mon Sep 17 00:00:00 2001 From: michatrautweiler Date: Fri, 24 May 2019 10:19:34 +0200 Subject: [PATCH 10/10] return decoded value in any case Fix plain decoder for TTN: Decoded value was not returned except for last case. --- src/TTN/plain_decoder.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/TTN/plain_decoder.js b/src/TTN/plain_decoder.js index d87fcb9e..96655ee7 100644 --- a/src/TTN/plain_decoder.js +++ b/src/TTN/plain_decoder.js @@ -81,7 +81,6 @@ function Decoder(bytes, port) { decoded.time = ((bytes[i++] << 24) | (bytes[i++] << 16) | (bytes[i++] << 8) | bytes[i++]); decoded.timestatus = bytes[i++]; } - return decoded; } - + return decoded; }