ESP32-PaxCounter/src/ledmatrixdisplay.cpp

167 lines
4.9 KiB
C++

#ifdef HAS_MATRIX_DISPLAY
#include "globals.h"
#define NUMCHARS 5
#define MATRIX_DISPLAY_PAGES (2) // number of display pages
// local Tag for logging
static const char TAG[] = __FILE__;
uint8_t MatrixDisplayIsOn = 0;
static unsigned long ulLastNumMacs = 0;
static time_t ulLastTime = myTZ.toLocal(now());
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];
// --- SELECT YOUR FONT HERE ---
const FONT_INFO *ActiveFontInfo = &digital7_18ptFontInfo;
// const FONT_INFO *ActiveFontInfo = &arialNarrow_17ptFontInfo;
// const FONT_INFO *ActiveFontInfo = &gillSansMTCondensed_18ptFontInfo;
// const FONT_INFO *ActiveFontInfo = &gillSansMTCondensed_16ptFontInfo;
const uint8_t *iaActiveFont = ActiveFontInfo->Bitmap;
const FONT_CHAR_INFO *ActiveFontCharInfo = ActiveFontInfo->Descriptors;
void init_matrix_display(bool reverse) {
ESP_LOGI(TAG, "Initializing LED Matrix display");
matrix.begin(displaybuf, LED_MATRIX_WIDTH, LED_MATRIX_HEIGHT);
if (reverse)
matrix.reverse();
matrix.clear();
DrawNumber(String("0"));
} // init_display
void refreshTheMatrixDisplay(bool nextPage) {
static uint8_t DisplayPage = 0;
char buff[16];
// 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 (nextPage) {
DisplayPage =
(DisplayPage >= MATRIX_DISPLAY_PAGES - 1) ? 0 : (DisplayPage + 1);
matrix.clear();
}
switch (DisplayPage % MATRIX_DISPLAY_PAGES) {
// page 0: pax
// page 1: time
case 0:
if (ulLastNumMacs != macs.size()) {
ulLastNumMacs = macs.size();
matrix.clear();
DrawNumber(String(ulLastNumMacs));
}
break;
case 1:
const time_t t = myTZ.toLocal(now());
if (ulLastTime != t) {
ulLastTime = t;
matrix.clear();
snprintf(buff, sizeof(buff), "%02d:%02d:%02d", hour(t), minute(t),
second(t));
DrawNumber(String(buff));
}
break;
} // switch page
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;
// 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;
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;
for (int i = 0; i < iNumLength; i++) {
DrawChar(iDigitPos, 0, strNum.charAt(i));
if (i + 1 == iDotPos) {
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];
return CharDescriptor.width;
}
#endif // HAS_MATRIX_DISPLAY