From c6175fbd992ac335c7ff8ef64f50e35dc2c53e23 Mon Sep 17 00:00:00 2001 From: Drath Date: Fri, 3 Oct 2025 15:54:58 +0200 Subject: [PATCH] more flexible, slight sanity fixes --- include/LCDDisplay.hpp | 18 +++++++++------- src/LCDDisplay.cpp | 47 ++++++++++++++++++++++++++++-------------- 2 files changed, 42 insertions(+), 23 deletions(-) diff --git a/include/LCDDisplay.hpp b/include/LCDDisplay.hpp index b93973f..cc3850e 100644 --- a/include/LCDDisplay.hpp +++ b/include/LCDDisplay.hpp @@ -1,6 +1,9 @@ #ifndef LCDDISPLAY_HPP #define LCDDISPLAY_HPP +#define LCD_LINES 4 +#define LCD_COLS 40 + #include #include #include @@ -9,29 +12,30 @@ class LCDDisplay { private: uint8_t _lcd; - char writebuf[4 * 40 + 8]; // 4x40 chars + 2x4 setcursor commands - void writeStr(std::string str); // do not use - void writeLines(std::array lines); // do not use + char writebuf[LCD_LINES * LCD_COLS + 8]; // 4x40 chars + 2x4 setcursor commands + static constexpr bool dualDisp = (LCD_LINES * LCD_COLS > 80); // is it dual display device or not, evauluated from the size at compile time + void writeLines(std::array lines); // do not use public: LCDDisplay(std::string dev, uint32_t baud = 0010002); // from termios-baud.h, B115200 ~LCDDisplay(); - // custom char array - char cc[8] = {'\0', '\1', '\2', '\3', '\4', '\5', '\6', '\7'}; - void clear(); - void setContrast(uint8_t contrast); void setBacklight(bool enabled); void setBacklight(uint8_t brightness); void setCursor(uint8_t row, uint8_t col); void setCustomChar(uint8_t index, std::array cchar); + void writeStr(std::string str); + void writeStr(uint8_t row, uint8_t col, std::string str); void writeBuf(uint8_t row, uint8_t col, std::string str); void clearBuf(); void flushBuf(); + // returns custom char no. c, small enough to define in header + constexpr char cc(uint8_t c) { return c % 8; } + char bar(uint8_t char_id, double value); }; diff --git a/src/LCDDisplay.cpp b/src/LCDDisplay.cpp index 537d76e..fdf6b9a 100644 --- a/src/LCDDisplay.cpp +++ b/src/LCDDisplay.cpp @@ -28,7 +28,16 @@ LCDDisplay::LCDDisplay(std::string dev, uint32_t baud) { tcflush(lcd, TCIFLUSH); tcsetattr(lcd, TCSANOW, &term); _lcd = lcd; - clearBuf(); // init linebuf to spaces + + // init linebuf to spaces + clearBuf(); + + // disable underline and block cursor + uint8_t cmdbuf[] = {254, 75, 254, 84}; + write(_lcd, &cmdbuf, 4); + + // clear display and set cursor home + clear(); } LCDDisplay::~LCDDisplay() { @@ -53,11 +62,11 @@ void LCDDisplay::setBacklight(bool enabled) { write(_lcd, &cmdbuf, enabled ? 3 : 2); } -/* doesnt quite work yet, need to look up matrix orbital spec */ +/* still doesnt work? */ void LCDDisplay::setBacklight(uint8_t brightness) { std::println("[LCDDisplay::setBacklight] Set backlight brightness to {}", brightness); - uint8_t cmdbuf[] = {254, (uint8_t)(brightness ? 66 : 70), brightness}; - write(_lcd, &cmdbuf, brightness ? 3 : 2); + uint8_t cmdbuf[] = {254, (uint8_t)(brightness ? 66 : 70), 255, brightness}; // 3rd char is timer, 4th is brightness + write(_lcd, &cmdbuf, brightness ? 4 : 2); } void LCDDisplay::setCursor(uint8_t row, uint8_t col) { @@ -72,44 +81,50 @@ void LCDDisplay::setCustomChar(uint8_t index, std::array cchar) { write(_lcd, &cmdbuf, 11); } +/* immediately writes string to the lcd at current cursor pos */ void LCDDisplay::writeStr(std::string str) { write(_lcd, str.c_str(), str.size()); } +/* immediately writes string to the lcd at given cursor pos */ +void LCDDisplay::writeStr(uint8_t row, uint8_t col, std::string str) { + setCursor(row, col); + writeStr(str); +} + void LCDDisplay::writeLines(std::array lines) { for (auto& line : lines) { - if (line.size() > 40) { + if (line.size() > LCD_COLS) { std::println("[LCDDisplay::writeLines] Line {} too long! ({} chars)", line, line.size()); continue; } - line.insert(line.end(), 40 - line.size(), ' '); + line.insert(line.end(), LCD_COLS - line.size(), ' '); } - setCursor(0, 0); - writeStr(lines[0] + lines[1]); - setCursor(2, 0); - writeStr(lines[2] + lines[3]); + writeStr(0, 0, lines[0] + lines[1]); + writeStr(2, 0, lines[2] + lines[3]); } /* writes string to write buffer at calculated pos */ void LCDDisplay::writeBuf(uint8_t row, uint8_t col, std::string str) { size_t len = std::min(str.size(), sizeof(writebuf) - col); - uint8_t pos = 4 + col + (40 * (row % 2)); // skip 4 bytes to leave room for set cursor command - if (row >= 2) pos += 84; // if we're writing to disp2, skip another 4 bytes for set cursor command and 2*40 bytes of disp 1 + uint8_t pos = 4 + col + (LCD_COLS * (row % 2)); // skip 4 bytes to leave room for set cursor command + if (row >= 2) pos += 2 * LCD_COLS + 4; // if we're writing to disp2, skip another 4 bytes for set cursor command and 2*40 bytes of disp 1 std::memcpy(&writebuf[pos], str.c_str(), len); } +/* initializes the write buffer to spaces */ void LCDDisplay::clearBuf() { std::memset(writebuf, ' ', sizeof(writebuf)); } -/* hyper optimized buffer flush command, writes whole disp with a single write */ +/* flushes writebuffer to lcd, hyperoptmized, flushes buffer and commands in a single write operation */ void LCDDisplay::flushBuf() { // we could skip all of this and set it in constructor if we were extra sure the lines wont ever exceed 40 chars constexpr uint8_t setDisp[] = {254, 71, 1, 1}; // set cursor to char 1, line 1 std::memcpy(&writebuf[0], setDisp, 4); - std::memcpy(&writebuf[84], setDisp, 4); - writebuf[87] = 3; // overwrite set cursor c1 l1 to c1 l3 + std::memcpy(&writebuf[2 * LCD_COLS + 4], setDisp, 4); + writebuf[2 * LCD_COLS + 7] = 3; // overwrite set cursor c1 l1 to c1 l3 write(_lcd, writebuf, sizeof(writebuf)); } @@ -120,5 +135,5 @@ char LCDDisplay::bar(uint8_t char_id, double value) { for (uint8_t i = 0; i < (1.0 - value) * 8; i++) b[i] = 0; setCustomChar(char_id, b); - return cc[char_id]; + return cc(char_id); } \ No newline at end of file