From fa8caf8c922937ca3d2d92f7536519f108ae7fe5 Mon Sep 17 00:00:00 2001 From: Tony Corbett G0WFV Date: Sat, 4 Jun 2016 15:22:39 +0100 Subject: [PATCH] Implement scrolling of long src and dest on HD44780/Adafruit LCDs Also tidyed up my comments and cleared lines where I've left old code commented out and the new code has proved to work just fine! --- HD44780.cpp | 105 ++++++++++++++++++++++++++++++++++------------------ HD44780.h | 2 + 2 files changed, 70 insertions(+), 37 deletions(-) diff --git a/HD44780.cpp b/HD44780.cpp index 339a3c8..610bcc9 100644 --- a/HD44780.cpp +++ b/HD44780.cpp @@ -53,10 +53,12 @@ m_pwmDim(pwmDim), m_displayClock(displayClock), m_utc(utc), m_duplex(duplex), -//m_duplex(true), // uncomment to force duplex display for testing! +//m_duplex(true), // uncomment to force duplex display for testing! m_fd(-1), m_dmr(false), -m_clockDisplayTimer(1000U, 0U, 75U) // Update the clock display every 75ms +m_clockDisplayTimer(1000U, 0U, 75U), // Update the clock display every 75ms +m_scrollTimer1(1000U, 0U, 250U), // Scroll speed for slot 1 - every 250ms +m_scrollTimer2(1000U, 0U, 250U) // Scroll speed for slot 2 - every 250ms { assert(rows > 1U); assert(cols > 15U); @@ -293,7 +295,7 @@ void CHD44780::adafruitLCDColour(ADAFRUIT_COLOUR colour) void CHD44780::setIdleInt() { - m_clockDisplayTimer.start(); // Start the clock display in IDLE only + m_clockDisplayTimer.start(); // Start the clock display in IDLE only ::lcdClear(m_fd); #ifdef ADAFRUIT_DISPLAY @@ -321,7 +323,7 @@ void CHD44780::setIdleInt() ::lcdPutchar(m_fd, 4); ::lcdPutchar(m_fd, 2); ::lcdPosition(m_fd, m_cols - 4, m_rows - 1); - ::lcdPuts(m_fd, "Idle"); // Gets overwritten by clock on 2 line screen + ::lcdPuts(m_fd, "Idle"); // Gets overwritten by clock on 2 line screen m_dmr = false; } @@ -334,7 +336,9 @@ void CHD44780::setErrorInt(const char* text) adafruitLCDColour(AC_RED); #endif - m_clockDisplayTimer.stop(); // Stop the clock display + m_clockDisplayTimer.stop(); // Stop the clock display + m_scrollTimer1.stop(); // Stop the scroll timer on slot 1 + m_scrollTimer2.stop(); // Stop the scroll timer on slot 2 ::lcdClear(m_fd); if (m_pwm) { @@ -363,7 +367,9 @@ void CHD44780::setLockoutInt() adafruitLCDColour(AC_RED); #endif - m_clockDisplayTimer.stop(); // Stop the clock display + m_clockDisplayTimer.stop(); // Stop the clock display + m_scrollTimer1.stop(); // Stop the scroll timer on slot 1 + m_scrollTimer2.stop(); // Stop the scroll timer on slot 2 ::lcdClear(m_fd); if (m_pwm) { @@ -398,7 +404,7 @@ void CHD44780::writeDStarInt(const char* my1, const char* my2, const char* your, adafruitLCDColour(AC_RED); #endif - m_clockDisplayTimer.stop(); // Stop the clock display + m_clockDisplayTimer.stop(); // Stop the clock display ::lcdClear(m_fd); if (m_pwm) { @@ -412,12 +418,10 @@ void CHD44780::writeDStarInt(const char* my1, const char* my2, const char* your, ::lcdPuts(m_fd, "D-Star"); if (m_rows == 2U && m_cols == 16U) { -// char buffer[16U]; ::sprintf(m_buffer1, "%s %.8s/%.4s", type, my1, my2); ::lcdPosition(m_fd, 0, 1); ::lcdPrintf(m_fd, "%.*s", m_cols, m_buffer1); } else if (m_rows == 4U && m_cols == 16U) { -// char buffer[16U]; ::sprintf(m_buffer1, "%s %.8s/%.4s", type, my1, my2); ::lcdPosition(m_fd, 0, 1); ::lcdPrintf(m_fd, "%.*s", m_cols, m_buffer1); @@ -462,7 +466,7 @@ void CHD44780::clearDStarInt() adafruitLCDColour(AC_PURPLE); #endif - m_clockDisplayTimer.stop(); // Stop the clock display + m_clockDisplayTimer.stop(); // Stop the clock display if (m_rows == 2U && m_cols == 16U) { ::lcdPosition(m_fd, 0, 1); @@ -487,11 +491,10 @@ void CHD44780::clearDStarInt() void CHD44780::writeDMRInt(unsigned int slotNo, const std::string& src, bool group, const std::string& dst, const char* type) { -// char buffer[128]; // force 128 char buffer - we're never getting that far but stops us overflowing it! assert(type != NULL); if (!m_dmr) { - m_clockDisplayTimer.stop(); // Stop the clock display + m_clockDisplayTimer.stop(); // Stop the clock display ::lcdClear(m_fd); #ifdef ADAFRUIT_DISPLAY @@ -536,31 +539,37 @@ void CHD44780::writeDMRInt(unsigned int slotNo, const std::string& src, bool gro if (slotNo == 1U) { ::lcdPosition(m_fd, 0, (m_rows / 2) - 1); ::lcdPuts(m_fd, "1 "); - ::sprintf(m_buffer1, "%s > %s%s", src.c_str(), dst.c_str(), DEADSPACE); + ::sprintf(m_buffer2, "%s > %s%s ", src.c_str(), group ? "TG" : "", dst.c_str()); ::lcdPrintf(m_fd, "%.*s", m_cols - 2U, m_buffer1); - if (m_cols > 16) { - ::lcdCharDef(m_fd, 6, group ? tgChar : privChar); - ::lcdCharDef(m_fd, 5, strcmp(type, "R") == 0 ? rfChar : ipChar); - ::lcdPosition(m_fd, m_cols - 3U, (m_rows / 2) - 1); - ::lcdPuts(m_fd, " "); - ::lcdPutchar(m_fd, 6); - ::lcdPutchar(m_fd, 5); + // Start the scroll timer on slot 1 if text in m_buffer1 will not fit in the space available + if (strlen(m_buffer1) - 5 > m_cols - 5 ) { + m_scrollTimer1.start(); } + + ::lcdCharDef(m_fd, 6, group ? tgChar : privChar); + ::lcdCharDef(m_fd, 5, strcmp(type, "R") == 0 ? rfChar : ipChar); + ::lcdPosition(m_fd, m_cols - 3U, (m_rows / 2) - 1); + ::lcdPuts(m_fd, " "); + ::lcdPutchar(m_fd, 6); + ::lcdPutchar(m_fd, 5); } else { ::lcdPosition(m_fd, 0, (m_rows / 2)); ::lcdPuts(m_fd, "2 "); - ::sprintf(m_buffer2, "%s > %s%s", src.c_str(), dst.c_str(), DEADSPACE); + ::sprintf(m_buffer2, "%s > %s%s ", src.c_str(), group ? "TG" : "", dst.c_str()); ::lcdPrintf(m_fd, "%.*s", m_cols - 2U, m_buffer2); - if (m_cols > 16) { - ::lcdCharDef(m_fd, 6, group ? tgChar : privChar); - ::lcdCharDef(m_fd, 5, strcmp(type, "R") == 0 ? rfChar : ipChar); - ::lcdPosition(m_fd, m_cols - 3U, (m_rows / 2)); - ::lcdPuts(m_fd, " "); - ::lcdPutchar(m_fd, 6); - ::lcdPutchar(m_fd, 5); + // Start the scroll timer on slot 2 if text in m_buffer2 will not fit in the space available + if (strlen(m_buffer2) - 5 > m_cols - 5 ) { + m_scrollTimer2.start(); } + + ::lcdCharDef(m_fd, 6, group ? tgChar : privChar); + ::lcdCharDef(m_fd, 5, strcmp(type, "R") == 0 ? rfChar : ipChar); + ::lcdPosition(m_fd, m_cols - 3U, (m_rows / 2)); + ::lcdPuts(m_fd, " "); + ::lcdPutchar(m_fd, 6); + ::lcdPutchar(m_fd, 5); } } else { ::lcdPosition(m_fd, 0, (m_rows / 2) - 1); @@ -584,13 +593,14 @@ void CHD44780::writeDMRInt(unsigned int slotNo, const std::string& src, bool gro void CHD44780::clearDMRInt(unsigned int slotNo) { -// char buffer[128]; // force 128 char buffer - we're never getting that far but stops us overflowing it! - #ifdef ADAFRUIT_DISPLAY adafruitLCDColour(AC_PURPLE); #endif - m_clockDisplayTimer.stop(); // Stop the clock display + m_clockDisplayTimer.stop(); // Stop the clock display + m_scrollTimer1.stop(); // Stop the scroll timer on slot 1 + m_scrollTimer2.stop(); // Stop the scroll timer on slot 2 + if (m_duplex) { if (slotNo == 1U) { ::lcdPosition(m_fd, 0, 0); @@ -619,7 +629,7 @@ void CHD44780::writeFusionInt(const char* source, const char* dest, const char* adafruitLCDColour(AC_RED); #endif - m_clockDisplayTimer.stop(); // Stop the clock display + m_clockDisplayTimer.stop(); // Stop the clock display ::lcdClear(m_fd); if (m_pwm) { @@ -672,7 +682,7 @@ void CHD44780::clearFusionInt() adafruitLCDColour(AC_PURPLE); #endif - m_clockDisplayTimer.stop(); // Stop the clock display + m_clockDisplayTimer.stop(); // Stop the clock display if (m_rows == 2U && m_cols == 16U) { ::lcdPosition(m_fd, 0, 1); @@ -697,14 +707,17 @@ void CHD44780::clearFusionInt() void CHD44780::clockInt(unsigned int ms) { - // Update the clock display in IDLE mode every 75ms m_clockDisplayTimer.clock(ms); + m_scrollTimer1.clock(ms); + m_scrollTimer2.clock(ms); + + // Idle clock display if (m_displayClock && m_clockDisplayTimer.isRunning() && m_clockDisplayTimer.hasExpired()) { time_t currentTime; struct tm *Time; - time(¤tTime); // Get the current time + time(¤tTime); - if (m_utc){ + if (m_utc) { Time = gmtime(¤tTime); } else { Time = localtime(¤tTime); @@ -728,7 +741,25 @@ void CHD44780::clockInt(unsigned int ms) ::lcdPosition(m_fd, (m_cols - 8) / 2, m_rows == 2 ? 0 : 1); ::lcdPrintf(m_fd, "%02d/%02d/%2d", Day, Month, Year%100); } - m_clockDisplayTimer.start(); // restart the clock display timer + m_clockDisplayTimer.start(); + } + + // Slot 1 scrolling + if (m_scrollTimer1.isRunning() && m_scrollTimer1.hasExpired()) { + strncat(m_buffer1, m_buffer1, 1); // Move the first character to the end of the buffer + memmove(m_buffer1, m_buffer1 + 1, strlen(m_buffer1)); // Strip the first character + ::lcdPosition(m_fd, 2, (m_rows / 2) - 1); // Position on the LCD + ::lcdPrintf(m_fd, "%.*s", m_cols - 5U, m_buffer1); // Print it out + m_scrollTimer1.start(); // Restart the scroll timer + } + + // Slot 2 scrolling + if (m_scrollTimer2.isRunning() && m_scrollTimer2.hasExpired()) { + strncat(m_buffer2, m_buffer2, 1); + memmove(m_buffer2, m_buffer2 + 1, strlen(m_buffer2)); + ::lcdPosition(m_fd, 2, (m_rows / 2)); + ::lcdPrintf(m_fd, "%.*s", m_cols - 5U, m_buffer2); + m_scrollTimer2.start(); } } diff --git a/HD44780.h b/HD44780.h index a776413..2a803de 100644 --- a/HD44780.h +++ b/HD44780.h @@ -97,6 +97,8 @@ private: int m_fd; bool m_dmr; CTimer m_clockDisplayTimer; + CTimer m_scrollTimer1; + CTimer m_scrollTimer2; #ifdef ADAFRUIT_DISPLAY void adafruitLCDSetup();