From ca35121b44ef79cfb07b621b018abd640d6ccf59 Mon Sep 17 00:00:00 2001 From: KD4Z Date: Wed, 5 Sep 2018 16:12:12 -0400 Subject: [PATCH] Add more dynamic variables and fix command manging Add variables for TX Freq (t30), RX Freq (t32), CPU Temp (t20), and Location (t31) to Base MMDVM page. These variables are available with Layout ON7LDS L3 or higher. This allows more dynamic info to be displayed without having to use the optional NextionDriver. Note, this doesn't add touch support. For that, use the NextionDriver. Fixed command mangling occuring during serial writes to Nextion due to no ready-state monitoring of display readiness. Added simple thread sleep to pace the commands as they are sent. Allows the display a chance to process the command before another one is blasted in. Prevents mangling of commands sent before display is ready to accept them. Hardwired to 10 msec--let's see if that's enough. Added setting in mmdvm conf file, Section: [Nextion] Setting: DisplayTempInFahrenheit Value= 0 (default) for C. 1=Fahrenheit This controls the value sent to t20. --- Conf.cpp | 8 +++++ Conf.h | 4 ++- Display.cpp | 21 ++++++++---- Nextion.cpp | 70 ++++++++++++++++++++++++++++++++++------ Nextion.h | 12 +++++-- Nextion_ON7LDS/README-L3 | 11 ++++++- 6 files changed, 105 insertions(+), 21 deletions(-) diff --git a/Conf.cpp b/Conf.cpp index 8629341..9f307e0 100644 --- a/Conf.cpp +++ b/Conf.cpp @@ -228,6 +228,7 @@ m_nextionDisplayClock(false), m_nextionUTC(false), m_nextionIdleBrightness(20U), m_nextionScreenLayout(0U), +m_nextionTempInFahrenheit(false), m_oledType(3U), m_oledBrightness(0U), m_oledInvert(false), @@ -757,6 +758,8 @@ bool CConf::read() m_nextionIdleBrightness = (unsigned int)::atoi(value); else if (::strcmp(key, "ScreenLayout") == 0) m_nextionScreenLayout = (unsigned int)::atoi(value); + else if (::strcmp(key, "DisplayTempInFahrenheit") == 0) + m_nextionTempInFahrenheit = ::atoi(value) == 1; } else if (section == SECTION_OLED) { if (::strcmp(key, "Type") == 0) m_oledType = (unsigned char)::atoi(value); @@ -1676,3 +1679,8 @@ bool CConf::getLCDprocDimOnIdle() const { return m_lcdprocDimOnIdle; } + +bool CConf::getNextionTempInFahrenheit() const +{ + return m_nextionTempInFahrenheit; +} diff --git a/Conf.h b/Conf.h index 8b7d16c..2cc9cb9 100644 --- a/Conf.h +++ b/Conf.h @@ -245,6 +245,7 @@ public: bool getNextionUTC() const; unsigned int getNextionIdleBrightness() const; unsigned int getNextionScreenLayout() const; + bool getNextionTempInFahrenheit() const; // The OLED section unsigned char getOLEDType() const; @@ -453,7 +454,8 @@ private: bool m_nextionUTC; unsigned int m_nextionIdleBrightness; unsigned int m_nextionScreenLayout; - + bool m_nextionTempInFahrenheit; + unsigned char m_oledType; unsigned char m_oledBrightness; bool m_oledInvert; diff --git a/Display.cpp b/Display.cpp index c1faa16..f88ef27 100644 --- a/Display.cpp +++ b/Display.cpp @@ -458,6 +458,7 @@ void CDisplay::writeNXDNRSSIInt(unsigned char rssi) void CDisplay::writeNXDNBERInt(float ber) { } + /* Factory method extracted from MMDVMHost.cpp - BG5HHP */ CDisplay* CDisplay::createDisplay(const CConf& conf, CUMP* ump, CModem* modem) @@ -491,6 +492,9 @@ CDisplay* CDisplay::createDisplay(const CConf& conf, CUMP* ump, CModem* modem) bool utc = conf.getNextionUTC(); unsigned int idleBrightness = conf.getNextionIdleBrightness(); unsigned int screenLayout = conf.getNextionScreenLayout(); + unsigned int txFrequency = conf.getTXFrequency(); + unsigned int rxFrequency = conf.getRXFrequency(); + bool displayTempInF = conf.getNextionTempInFahrenheit(); LogInfo(" Port: %s", port.c_str()); LogInfo(" Brightness: %u", brightness); @@ -498,7 +502,8 @@ CDisplay* CDisplay::createDisplay(const CConf& conf, CUMP* ump, CModem* modem) if (displayClock) LogInfo(" Display UTC: %s", utc ? "yes" : "no"); LogInfo(" Idle Brightness: %u", idleBrightness); - + LogInfo(" Temperature in Fahrenheit: %s ", displayTempInF ? "yes" : "no"); + switch (screenLayout) { case 0U: LogInfo(" Screen Layout: G4KLX (Default)"); @@ -519,18 +524,22 @@ CDisplay* CDisplay::createDisplay(const CConf& conf, CUMP* ump, CModem* modem) if (port == "modem") { ISerialPort* serial = new CModemSerialPort(modem); - display = new CNextion(conf.getCallsign(), dmrid, serial, brightness, displayClock, utc, idleBrightness, screenLayout); + display = new CNextion(conf.getCallsign(), dmrid, serial, brightness, displayClock, utc, idleBrightness, screenLayout, txFrequency, rxFrequency, displayTempInF, conf.getLocation()); } else if (port == "ump") { - if (ump != NULL) - display = new CNextion(conf.getCallsign(), dmrid, ump, brightness, displayClock, utc, idleBrightness, screenLayout); - else + if (ump != NULL) { + display = new CNextion(conf.getCallsign(), dmrid, ump, brightness, displayClock, utc, idleBrightness, screenLayout, txFrequency, rxFrequency, displayTempInF, conf.getLocation()); + } else { + LogInfo(" NullDisplay loaded"); display = new CNullDisplay; + } } else { SERIAL_SPEED baudrate = SERIAL_9600; if (screenLayout==4U) baudrate = SERIAL_115200; + + LogInfo(" Display baudrate: %u ",baudrate); ISerialPort* serial = new CSerialController(port, baudrate); - display = new CNextion(conf.getCallsign(), dmrid, serial, brightness, displayClock, utc, idleBrightness, screenLayout); + display = new CNextion(conf.getCallsign(), dmrid, serial, brightness, displayClock, utc, idleBrightness, screenLayout, txFrequency, rxFrequency, displayTempInF, conf.getLocation()); } } else if (type == "LCDproc") { std::string address = conf.getLCDprocAddress(); diff --git a/Nextion.cpp b/Nextion.cpp index f4853ef..98c396c 100644 --- a/Nextion.cpp +++ b/Nextion.cpp @@ -38,7 +38,7 @@ const unsigned int P25_BER_COUNT = 7U; // 7 * 180ms = 1260ms const unsigned int NXDN_RSSI_COUNT = 28U; // 28 * 40ms = 1120ms const unsigned int NXDN_BER_COUNT = 28U; // 28 * 40ms = 1120ms -CNextion::CNextion(const std::string& callsign, unsigned int dmrid, ISerialPort* serial, unsigned int brightness, bool displayClock, bool utc, unsigned int idleBrightness, unsigned int screenLayout) : +CNextion::CNextion(const std::string& callsign, unsigned int dmrid, ISerialPort* serial, unsigned int brightness, bool displayClock, bool utc, unsigned int idleBrightness, unsigned int screenLayout, unsigned int txFrequency, unsigned int rxFrequency, bool displayTempInF, const std::string& location) : CDisplay(), m_callsign(callsign), m_ipaddress("(ip unknown)"), @@ -58,7 +58,11 @@ m_berAccum2(0.0F), m_rssiCount1(0U), m_rssiCount2(0U), m_berCount1(0U), -m_berCount2(0U) +m_berCount2(0U), +m_txFrequency(txFrequency), +m_rxFrequency(rxFrequency), +m_displayTempInF(displayTempInF), +m_location(location) { assert(serial != NULL); assert(brightness >= 0U && brightness <= 100U); @@ -86,8 +90,14 @@ bool CNextion::open() m_ipaddress = (char*)info; sendCommand("bkcmd=0"); - sendCommandAction(0); + sendCommandAction(0U); + + m_fl_txFrequency = m_txFrequency; + m_fl_txFrequency/=1000000U; + m_fl_rxFrequency = m_rxFrequency; + m_fl_rxFrequency/=1000000U; + setIdle(); return true; @@ -96,23 +106,58 @@ bool CNextion::open() void CNextion::setIdleInt() { + // a few bits borrowed from Lieven De Samblanx ON7LDS, NextionDriver + char command[100U]; + sendCommand("page MMDVM"); sendCommandAction(1U); - char command[100U]; ::sprintf(command, "dim=%u", m_idleBrightness); sendCommand(command); - + ::sprintf(command, "t0.txt=\"%s/%u\"", m_callsign.c_str(), m_dmrid); sendCommand(command); + if (m_screenLayout > 2U) { ::sprintf(command, "t4.txt=\"%s\"", m_callsign.c_str()); sendCommand(command); ::sprintf(command, "t5.txt=\"%u\"", m_dmrid); sendCommand(command); - } - sendCommandAction(17U); + sendCommandAction(17U); + ::sprintf(command, "t30.txt=\"%3.4f\"",m_fl_rxFrequency); // RX freq + sendCommand(command); + sendCommandAction(20U); + + ::sprintf(command, "t32.txt=\"%3.4f\"",m_fl_txFrequency); // TX freq + sendCommand(command); + sendCommandAction(21U); + + FILE *deviceInfoFile; + double val; + //CPU temperature + deviceInfoFile = fopen ("/sys/class/thermal/thermal_zone0/temp", "r"); + if (deviceInfoFile != NULL) { + fscanf (deviceInfoFile, "%lf", &val); + fclose(deviceInfoFile); + val /= 1000; + if( m_displayTempInF){ + val = (1.8 * val) + 32; + ::sprintf(command, "t20.txt=\"%2.1f %cF\"", val, 176); + } else { + ::sprintf(command, "t20.txt=\"%2.1f %cC\"", val, 176); + } + sendCommand(command); + sendCommandAction(22U); + } + + ::sprintf(command, "t31.txt=\"%s\"", m_location.c_str()); // location + sendCommand(command); + sendCommandAction(23U); + } else { + sendCommandAction(17U); + } + sendCommand("t1.txt=\"MMDVM IDLE\""); sendCommandAction(11U); @@ -454,6 +499,7 @@ void CNextion::writeDMRBERInt(unsigned int slotNo, float ber) void CNextion::clearDMRInt(unsigned int slotNo) { + if (slotNo == 1U) { sendCommand("t0.txt=\"1 Listening\""); sendCommandAction(61U); @@ -777,7 +823,8 @@ void CNextion::close() void CNextion::sendCommandAction(unsigned int status) { - if (m_screenLayout<3U) return; + if (m_screenLayout<3U) + return; char text[30U]; ::sprintf(text, "MMDVM.status.val=%d", status); @@ -785,11 +832,14 @@ void CNextion::sendCommandAction(unsigned int status) sendCommand("click S0,1"); } - void CNextion::sendCommand(const char* command) { assert(command != NULL); m_serial->write((unsigned char*)command, (unsigned int)::strlen(command)); m_serial->write((unsigned char*)"\xFF\xFF\xFF", 3U); -} + // Since we just firing commands at the display, and not listening for the response, + // we must add a bit of a delay to allow the display to process the commands, else some are getting mangled. + // 10 ms is just a guess, but seems to be sufficient. + CThread::sleep(10U); + } diff --git a/Nextion.h b/Nextion.h index 7578acf..8c3ccc0 100644 --- a/Nextion.h +++ b/Nextion.h @@ -23,13 +23,13 @@ #include "Defines.h" #include "SerialPort.h" #include "Timer.h" - +#include "Thread.h" #include class CNextion : public CDisplay { public: - CNextion(const std::string& callsign, unsigned int dmrid, ISerialPort* serial, unsigned int brightness, bool displayClock, bool utc, unsigned int idleBrightness, unsigned int screenLayout); + CNextion(const std::string& callsign, unsigned int dmrid, ISerialPort* serial, unsigned int brightness, bool displayClock, bool utc, unsigned int idleBrightness, unsigned int screenLayout, unsigned int txFrequency, unsigned int rxFrequency, bool displayTempInF, const std::string& location); virtual ~CNextion(); virtual bool open(); @@ -97,7 +97,13 @@ private: unsigned int m_rssiCount2; unsigned int m_berCount1; unsigned int m_berCount2; - + unsigned int m_txFrequency; + unsigned int m_rxFrequency; + float m_fl_txFrequency=0; + float m_fl_rxFrequency=0; + bool m_displayTempInF; + std::string m_location; + void sendCommand(const char* command); void sendCommandAction(unsigned int status); }; diff --git a/Nextion_ON7LDS/README-L3 b/Nextion_ON7LDS/README-L3 index 692d3c6..325bf04 100644 --- a/Nextion_ON7LDS/README-L3 +++ b/Nextion_ON7LDS/README-L3 @@ -104,6 +104,10 @@ changed field. 16 : IPaddress 17 : ID/Call (t0 and t4,t5 are sent) 19 : END +20 : RX Frequency +21 : TX Frequency +22 : Temperature +23 : Location 41 : D-Star listening 42 : type/my1/my2 @@ -161,10 +165,15 @@ t0 : owner call & ID / errortext LOCKOUT t1 : status / ERROR t2 : date & time -screenLayout >1 : + +screenLayout >2 : t3 : ip address t4 : owner call t5 : owner ID +t20 : CPU Temperature in C. ( Can be changed to F in mmdmvhost config setting: [NEXTION] Section, Setting=DisplayTempInFahrenheit=1) +t30 : RX Frequency +t31 : Location +t32 : TX Frequency D-Star