Skip to content
Merged
101 changes: 99 additions & 2 deletions Firmware/GPAD_API/GPAD_API/GPAD_API.ino
Original file line number Diff line number Diff line change
Expand Up @@ -349,14 +349,111 @@ bool readMacAddress(uint8_t *baseMac)
}
}

String jsonEscape(const String &raw)
{
String escaped;
escaped.reserve(raw.length() + 8);
for (size_t i = 0; i < raw.length(); i++)
{
const char c = raw.charAt(i);
if (c == '\\' || c == '"')
{
escaped += '\\';
}
escaped += c;
}
return escaped;
}

String uptimeString()
{
const uint32_t totalSeconds = millis() / 1000;
const uint32_t hours = totalSeconds / 3600;
const uint32_t minutes = (totalSeconds % 3600) / 60;
const uint32_t seconds = totalSeconds % 60;
return String(hours) + "h " + String(minutes) + "m " + String(seconds) + "s";
}

String currentUrl()
{
IPAddress ip = wifiManager.getAddress();
if (ip == INADDR_NONE)
{
return String("-");
}
return "http://" + ip.toString();
}

String templateProcessor(const String &var)
{
if (var == "SERIAL")
{
return String(macAddressString);
}
if (var == "URL")
{
return currentUrl();
}
if (var == "IP")
{
return wifiManager.getAddress().toString();
}
if (var == "MAC")
{
return String(macAddressString);
}
if (var == "RSSI")
{
return String(WiFi.RSSI()) + " dBm";
}
if (var == "UPTIME")
{
return uptimeString();
}
if (var == "MQTT")
{
return client.connected() ? String("connected") : String("disconnected");
}
if (var == "QR")
{
return "/favicon.png";
}
return WifiOTA::processor(var);
}

// Elegant OTA Setup

void setupOTA()
{

// Route for root / web page
server.on("/", HTTP_GET, [](AsyncWebServerRequest *request)
{ request->send(LittleFS, "/index.html", "text/html", false, WifiOTA::processor); });
{ request->send(LittleFS, "/index.html", "text/html", false, templateProcessor); });

server.on("/lcd", HTTP_GET, [](AsyncWebServerRequest *request)
{
String payload = "{\"lines\":[\"";
payload += jsonEscape(lcd.line(0));
payload += "\",\"";
payload += jsonEscape(lcd.line(1));
payload += "\",\"";
payload += jsonEscape(lcd.line(2));
payload += "\",\"";
payload += jsonEscape(lcd.line(3));
payload += "\"]}";
request->send(200, "application/json", payload); });

server.on("/status", HTTP_GET, [](AsyncWebServerRequest *request)
{
String payload = "{";
payload += "\"ip\":\"" + jsonEscape(wifiManager.getAddress().toString()) + "\",";
payload += "\"mac\":\"" + jsonEscape(String(macAddressString)) + "\",";
payload += "\"rssi\":\"" + String(WiFi.RSSI()) + " dBm\",";
payload += "\"uptime\":\"" + jsonEscape(uptimeString()) + "\",";
payload += "\"mqtt\":\"" + String(client.connected() ? "connected" : "disconnected") + "\",";
payload += "\"url\":\"" + jsonEscape(currentUrl()) + "\"";
payload += "}";
request->send(200, "application/json", payload); });

server.serveStatic("/", LittleFS, "/");

Expand All @@ -376,7 +473,7 @@ void setup()
}
serialSplash();
// We call this a second time to get the MAC on the screen
//clearLCD();
// clearLCD();

// Set LED pins as outputs
#if defined(LED_D9)
Expand Down
10 changes: 8 additions & 2 deletions Firmware/GPAD_API/GPAD_API/GPAD_HAL.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,9 @@ extern PubSubClient client;
// #include <LiquidCrystal_I2C.h>

// https://github.com/johnrickman/LiquidCrystal_I2C
LiquidCrystal_I2C lcd(LCD_ADDRESS, 20, 4);

LiquidCrystal_I2C Real_lcd(LCD_ADDRESS, 20, 4);
LCDWrapper lcd;

#include "DFPlayer.h"

Expand Down Expand Up @@ -333,9 +335,13 @@ void GPAD_HAL_setup(Stream *serialport, wifi_mode_t wifiMode, IPAddress &deviceI
// Setup the SWITCH_ENCODER
// Print instructions on DEBUG serial port

lcd.init(&Real_lcd);
local_ptr_to_serial = serialport;
Wire.begin();
lcd.init();

Real_lcd.init();


#if (DEBUG > 0)
serialport->println(F("Clear LCD"));
#endif
Expand Down
114 changes: 113 additions & 1 deletion Firmware/GPAD_API/GPAD_API/GPAD_HAL.h
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,117 @@ namespace gpad_hal
const GPAD_API gpadApi = GPAD_API(SemanticVersion(API_MAJOR_VERSION, API_MINOR_VERSION, API_PATCH_VERSION));
}



class LCDWrapper : public Print
{
public :
static const uint8_t LCD_COLS = 20;
static const uint8_t LCD_ROWS = 4;

LCDWrapper() : _LCD(nullptr), _cursorCol(0), _cursorRow(0)
{
resetMirror();
}

virtual size_t write(uint8_t b) override
{
if (_LCD == nullptr)
{
return 0;
}

if (b == '\r')
{
return 1;
}

if (b == '\n')
{
_cursorCol = 0;
_cursorRow = (_cursorRow + 1) % LCD_ROWS;
return 1;
}

_LCD->write(b);
if (_cursorRow < LCD_ROWS && _cursorCol < LCD_COLS)
{
_lcdMirror[_cursorRow][_cursorCol] = static_cast<char>(b);
}

if (_cursorCol < LCD_COLS)
{
_cursorCol++;
}

return 1;
}
void init(LiquidCrystal_I2C* _lcd)
{
_LCD = _lcd;
resetMirror();
}
void init()
{
_LCD->init();
resetMirror();
}
void clear(){
_LCD->clear();
resetMirror();
}
void backlight(){
_LCD->backlight();
}
void noBacklight(){
_LCD->noBacklight();
}
void setCursor(int16_t col, int16_t row){
_LCD->setCursor(col, row);
_cursorCol = constrain(col, 0, LCD_COLS - 1);
_cursorRow = constrain(row, 0, LCD_ROWS - 1);
}
void noBlink(){
_LCD->noBlink();
}
void blink(){
_LCD->blink();
}
void cursor(){
_LCD->cursor();
}
void noCursor(){
_LCD->noCursor();
}
String line(uint8_t row) const
{
if (row >= LCD_ROWS)
{
return String("");
}
return String(_lcdMirror[row]);
}
private:
void resetMirror()
{
for (uint8_t row = 0; row < LCD_ROWS; row++)
{
for (uint8_t col = 0; col < LCD_COLS; col++)
{
_lcdMirror[row][col] = ' ';
}
_lcdMirror[row][LCD_COLS] = '\0';
}
_cursorCol = 0;
_cursorRow = 0;
}

LiquidCrystal_I2C* _LCD;
char _lcdMirror[LCD_ROWS][LCD_COLS + 1];
uint8_t _cursorCol;
uint8_t _cursorRow;
};

// SPI Functions....
void setup_spi();
void receive_byte(byte c);
Expand All @@ -185,5 +296,6 @@ void interpretBuffer(char *buf, int rlen, Stream *serialport, PubSubClient *clie
void GPAD_HAL_setup(Stream *serialport, wifi_mode_t wifiMode, IPAddress &deviceIp);
void GPAD_HAL_loop();

extern LiquidCrystal_I2C lcd;
extern LiquidCrystal_I2C Real_lcd;
extern LCDWrapper lcd;
#endif
7 changes: 4 additions & 3 deletions Firmware/GPAD_API/GPAD_API/RickmanLiquidCrystal_I2C.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,17 @@

#include <Wire.h>
// #include <LiquidCrystal_PCF8574.h>
#include <LiquidCrystal_I2C.h>
// #include <LiquidCrystal_I2C.h>
#include "GPAD_HAL.h"

namespace Menu
{

class lcdOut : public cursorOut
{
public:
LiquidCrystal_I2C *device;
inline lcdOut(LiquidCrystal_I2C *o, idx_t *t, panelsList &p, menuOut::styles s = menuOut::minimalRedraw)
LCDWrapper *device;
inline lcdOut(LCDWrapper *o, idx_t *t, panelsList &p, menuOut::styles s = menuOut::minimalRedraw)
: cursorOut(t, p, s), device(o) {}
size_t write(uint8_t ch) override { return device->write(ch); }
void clear() override
Expand Down
Loading