Insert a back channel to Nextion displays running via the modem.

This commit is contained in:
Jonathan Naylor 2024-02-23 15:44:54 +00:00
parent 6dc9122fe4
commit 0e8788bdbe
7 changed files with 151 additions and 26 deletions

View file

@ -326,6 +326,8 @@ m_nextionUTC(false),
m_nextionIdleBrightness(20U), m_nextionIdleBrightness(20U),
m_nextionScreenLayout(0U), m_nextionScreenLayout(0U),
m_nextionTempInFahrenheit(false), m_nextionTempInFahrenheit(false),
m_nextionOutput(false),
m_nextionUDPPort(6759),
m_oledType(3U), m_oledType(3U),
m_oledBrightness(0U), m_oledBrightness(0U),
m_oledInvert(false), m_oledInvert(false),
@ -1118,6 +1120,10 @@ bool CConf::read()
m_nextionScreenLayout = (unsigned int)::strtoul(value, NULL, 0); m_nextionScreenLayout = (unsigned int)::strtoul(value, NULL, 0);
else if (::strcmp(key, "DisplayTempInFahrenheit") == 0) else if (::strcmp(key, "DisplayTempInFahrenheit") == 0)
m_nextionTempInFahrenheit = ::atoi(value) == 1; m_nextionTempInFahrenheit = ::atoi(value) == 1;
else if (::strcmp(key, "NextionOutput") == 0)
m_nextionOutput = ::atoi(value) == 1;
else if (::strcmp(key, "NextionUDPPort") == 0)
m_nextionUDPPort = (unsigned short)::atoi(value);
} else if (section == SECTION_OLED) { } else if (section == SECTION_OLED) {
if (::strcmp(key, "Type") == 0) if (::strcmp(key, "Type") == 0)
m_oledType = (unsigned char)::atoi(value); m_oledType = (unsigned char)::atoi(value);
@ -2457,6 +2463,21 @@ unsigned int CConf::getNextionScreenLayout() const
return m_nextionScreenLayout; return m_nextionScreenLayout;
} }
bool CConf::getNextionTempInFahrenheit() const
{
return m_nextionTempInFahrenheit;
}
bool CConf::getNextionOutput() const
{
return m_nextionOutput;
}
unsigned short CConf::getNextionUDPPort() const
{
return m_nextionUDPPort;
}
unsigned char CConf::getOLEDType() const unsigned char CConf::getOLEDType() const
{ {
return m_oledType; return m_oledType;
@ -2517,11 +2538,6 @@ bool CConf::getLCDprocDimOnIdle() const
return m_lcdprocDimOnIdle; return m_lcdprocDimOnIdle;
} }
bool CConf::getNextionTempInFahrenheit() const
{
return m_nextionTempInFahrenheit;
}
bool CConf::getLockFileEnabled() const bool CConf::getLockFileEnabled() const
{ {
return m_lockFileEnabled; return m_lockFileEnabled;

32
Conf.h
View file

@ -340,13 +340,15 @@ public:
bool getHD44780UTC() const; bool getHD44780UTC() const;
// The Nextion section // The Nextion section
std::string getNextionPort() const; std::string getNextionPort() const;
unsigned int getNextionBrightness() const; unsigned int getNextionBrightness() const;
bool getNextionDisplayClock() const; bool getNextionDisplayClock() const;
bool getNextionUTC() const; bool getNextionUTC() const;
unsigned int getNextionIdleBrightness() const; unsigned int getNextionIdleBrightness() const;
unsigned int getNextionScreenLayout() const; unsigned int getNextionScreenLayout() const;
bool getNextionTempInFahrenheit() const; bool getNextionTempInFahrenheit() const;
bool getNextionOutput() const;
unsigned short getNextionUDPPort() const;
// The OLED section // The OLED section
unsigned char getOLEDType() const; unsigned char getOLEDType() const;
@ -656,13 +658,15 @@ private:
bool m_hd44780DisplayClock; bool m_hd44780DisplayClock;
bool m_hd44780UTC; bool m_hd44780UTC;
std::string m_nextionPort; std::string m_nextionPort;
unsigned int m_nextionBrightness; unsigned int m_nextionBrightness;
bool m_nextionDisplayClock; bool m_nextionDisplayClock;
bool m_nextionUTC; bool m_nextionUTC;
unsigned int m_nextionIdleBrightness; unsigned int m_nextionIdleBrightness;
unsigned int m_nextionScreenLayout; unsigned int m_nextionScreenLayout;
bool m_nextionTempInFahrenheit; bool m_nextionTempInFahrenheit;
bool m_nextionOutput;
unsigned short m_nextionUDPPort;
unsigned char m_oledType; unsigned char m_oledType;
unsigned char m_oledBrightness; unsigned char m_oledBrightness;

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (C) 2016,2017,2018,2020,2021,2023 by Jonathan Naylor G4KLX * Copyright (C) 2016,2017,2018,2020,2021,2023,2024 by Jonathan Naylor G4KLX
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -22,6 +22,7 @@
#include "ModemSerialPort.h" #include "ModemSerialPort.h"
#include "NullDisplay.h" #include "NullDisplay.h"
#include "TFTSurenoo.h" #include "TFTSurenoo.h"
#include "UDPSocket.h"
#include "LCDproc.h" #include "LCDproc.h"
#include "Nextion.h" #include "Nextion.h"
#include "CASTInfo.h" #include "CASTInfo.h"
@ -604,8 +605,35 @@ CDisplay* CDisplay::createDisplay(const CConf& conf, CModem* modem)
} }
if (port == "modem") { if (port == "modem") {
ISerialPort* serial = new IModemSerialPort(modem); CUDPSocket* socket = NULL;
display = new CNextion(conf.getCallsign(), dmrid, serial, brightness, displayClock, utc, idleBrightness, screenLayout, txFrequency, rxFrequency, displayTempInF); struct sockaddr_storage addr;
unsigned int addrLength = 0U;
bool nextionOutput = conf.getNextionOutput();
if (nextionOutput) {
unsigned short nextionUDPPort = conf.getNextionUDPPort();
LogInfo(" Output Port: %u", nextionUDPPort);
CUDPSocket::lookup("127.0.0.1", nextionUDPPort, addr, addrLength);
if (addrLength > 0U) {
socket = new CUDPSocket("127.0.0.1", nextionUDPPort - 1U);
bool ret = socket->open(addr);
if (!ret) {
delete socket;
socket = NULL;
}
}
}
if (socket == NULL) {
ISerialPort* serial = new IModemSerialPort(modem);
display = new CNextion(conf.getCallsign(), dmrid, serial, brightness, displayClock, utc, idleBrightness, screenLayout, txFrequency, rxFrequency, displayTempInF);
} else {
ISerialPort* serial = new IModemSerialPort(modem);
display = new CNextion(conf.getCallsign(), dmrid, serial, brightness, displayClock, utc, idleBrightness, screenLayout, txFrequency, rxFrequency, displayTempInF, socket, addr, addrLength);
}
} else { } else {
unsigned int baudrate = 9600U; unsigned int baudrate = 9600U;
if (screenLayout == 4U) if (screenLayout == 4U)

View file

@ -345,6 +345,9 @@ UTC=0
#Screen Layout: 0=G4KLX 2=ON7LDS #Screen Layout: 0=G4KLX 2=ON7LDS
ScreenLayout=2 ScreenLayout=2
IdleBrightness=20 IdleBrightness=20
# Output data from the Nextion
NextionOutput=0
NextionPort=6759
[OLED] [OLED]
Type=3 Type=3

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (C) 2016,2017,2018,2020,2023 by Jonathan Naylor G4KLX * Copyright (C) 2016,2017,2018,2020,2023,2024 by Jonathan Naylor G4KLX
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -49,6 +49,59 @@ const unsigned int M17_BER_COUNT = 28U; // 28 * 40ms = 1120ms
// 00:low, others:high-speed. bit[2] is overlapped with LAYOUT_COMPAT_MASK. // 00:low, others:high-speed. bit[2] is overlapped with LAYOUT_COMPAT_MASK.
#define LAYOUT_HIGHSPEED (3 << 2) #define LAYOUT_HIGHSPEED (3 << 2)
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, CUDPSocket* socket, struct sockaddr_storage& addr, unsigned int addrLength) :
CDisplay(),
m_callsign(callsign),
m_ipaddress("(ip unknown)"),
m_dmrid(dmrid),
m_serial(serial),
m_brightness(brightness),
m_mode(MODE_IDLE),
m_displayClock(displayClock),
m_utc(utc),
m_idleBrightness(idleBrightness),
m_screenLayout(0),
m_clockDisplayTimer(1000U, 0U, 400U),
m_rssiAccum1(0U),
m_rssiAccum2(0U),
m_berAccum1(0.0F),
m_berAccum2(0.0F),
m_rssiCount1(0U),
m_rssiCount2(0U),
m_berCount1(0U),
m_berCount2(0U),
m_txFrequency(txFrequency),
m_rxFrequency(rxFrequency),
m_fl_txFrequency(0.0F),
m_fl_rxFrequency(0.0F),
m_displayTempInF(displayTempInF),
m_socket(socket),
m_addr(addr),
m_addrLength(addrLength)
{
assert(serial != NULL);
assert(brightness >= 0U && brightness <= 100U);
assert(socket != NULL);
assert(addrLength > 0U);
static const unsigned int feature_set[] = {
0, // 0: G4KLX
0, // 1: (reserved, low speed)
// 2: ON7LDS
LAYOUT_TA_ENABLE | LAYOUT_TA_COLOUR | LAYOUT_TA_FONTSIZE,
LAYOUT_TA_ENABLE | LAYOUT_DIY, // 3: ON7LDS-DIY
LAYOUT_TA_ENABLE | LAYOUT_DIY, // 4: ON7LDS-DIY (high speed)
0, // 5: (reserved, high speed)
0, // 6: (reserved, high speed)
0, // 7: (reserved, high speed)
};
if (screenLayout & ~LAYOUT_COMPAT_MASK)
m_screenLayout = screenLayout & ~LAYOUT_COMPAT_MASK;
else
m_screenLayout = feature_set[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) : 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) :
CDisplay(), CDisplay(),
m_callsign(callsign), m_callsign(callsign),
@ -74,7 +127,10 @@ m_txFrequency(txFrequency),
m_rxFrequency(rxFrequency), m_rxFrequency(rxFrequency),
m_fl_txFrequency(0.0F), m_fl_txFrequency(0.0F),
m_fl_rxFrequency(0.0F), m_fl_rxFrequency(0.0F),
m_displayTempInF(displayTempInF) m_displayTempInF(displayTempInF),
m_socket(NULL),
m_addr(),
m_addrLength(0U)
{ {
assert(serial != NULL); assert(serial != NULL);
assert(brightness >= 0U && brightness <= 100U); assert(brightness >= 0U && brightness <= 100U);
@ -968,12 +1024,25 @@ void CNextion::clockInt(unsigned int ms)
m_clockDisplayTimer.start(); // restart the clock display timer m_clockDisplayTimer.start(); // restart the clock display timer
} }
if (m_socket != NULL) {
unsigned char buffer[200U];
int len = m_serial->read(buffer, 200U);
if (len > 0)
m_socket->write(buffer, len, m_addr, m_addrLength);
}
} }
void CNextion::close() void CNextion::close()
{ {
m_serial->close(); m_serial->close();
delete m_serial; delete m_serial;
if (m_socket != NULL) {
m_socket->close();
delete m_socket;
}
} }
void CNextion::sendCommandAction(unsigned int status) void CNextion::sendCommandAction(unsigned int status)

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (C) 2016,2017,2018,2020,2023 by Jonathan Naylor G4KLX * Copyright (C) 2016,2017,2018,2020,2023,2024 by Jonathan Naylor G4KLX
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -22,6 +22,7 @@
#include "Display.h" #include "Display.h"
#include "Defines.h" #include "Defines.h"
#include "SerialPort.h" #include "SerialPort.h"
#include "UDPSocket.h"
#include "Timer.h" #include "Timer.h"
#include "Thread.h" #include "Thread.h"
#include <string> #include <string>
@ -29,6 +30,7 @@
class CNextion : public CDisplay class CNextion : public CDisplay
{ {
public: public:
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, CUDPSocket* socket, struct sockaddr_storage& addr, unsigned int addrLength);
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); 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);
virtual ~CNextion(); virtual ~CNextion();
@ -107,6 +109,9 @@ private:
double m_fl_txFrequency; double m_fl_txFrequency;
double m_fl_rxFrequency; double m_fl_rxFrequency;
bool m_displayTempInF; bool m_displayTempInF;
CUDPSocket* m_socket;
struct sockaddr_storage m_addr;
unsigned int m_addrLength;
void sendCommand(const char* command); void sendCommand(const char* command);
void sendCommandAction(unsigned int status); void sendCommandAction(unsigned int status);

View file

@ -19,6 +19,6 @@
#if !defined(VERSION_H) #if !defined(VERSION_H)
#define VERSION_H #define VERSION_H
const char* VERSION = "20240207"; const char* VERSION = "20240223";
#endif #endif