Updates to LCD firmware and service

This commit is contained in:
NinjaPug
2025-03-28 15:19:09 -04:00
parent 8d005b665b
commit b5d6d9481f
5 changed files with 115 additions and 5623 deletions

View File

@@ -1,60 +0,0 @@
#include <Wire.h>
#include <LiquidCrystal_PCF8574.h>
#define I2C_ADDR 0x27 // I2C address of the LCD module
#define SDA_PIN 8 // ESP32-C3 SuperMini SDA
#define SCL_PIN 9 // ESP32-C3 SuperMini SCL
LiquidCrystal_PCF8574 lcd(I2C_ADDR);
void setup() {
Serial.begin(115200); // USB/UART Serial for PC communication
Wire.begin(SDA_PIN, SCL_PIN); // Set I2C pins
// Initialize LCD
lcd.begin(16, 2);
lcd.setBacklight(255);
lcd.clear();
lcd.setCursor(2, 0);
lcd.print("ThermalTake");
lcd.setCursor(3, 1);
lcd.print("Tower 300");
Serial.println("ESP32-C3 SuperMini Ready");
}
void loop() {
if (Serial.available()) {
String command = Serial.readStringUntil('\n'); // Read input from PC
command.trim();
if (command.startsWith("CMD:LCD,")) {
handleLCDCommand(command);
} else if (command == "CMD:GET_LCD_TYPE") {
Serial.println("LCD_TYPE:1602A");
}
}
}
// Parse and execute LCD update command
void handleLCDCommand(String command) {
command.replace("CMD:LCD,", ""); // Remove the command header
int commaIndex = command.indexOf(',');
if (commaIndex == -1) return; // Invalid format
String lineNumber = command.substring(0, commaIndex);
String text = command.substring(commaIndex + 1);
int line = lineNumber.toInt();
if (line >= 0 && line < 2) { // Only two lines (0 and 1)
lcd.setCursor(0, line);
lcd.print(" "); // Clear line
lcd.setCursor(0, line);
lcd.print(text);
Serial.println("LCD Updated");
} else {
Serial.println("ERROR: Invalid LCD Line");
}
}

View File

@@ -37,7 +37,7 @@ namespace PCPalConfigurator
private static string GetConfigPath()
{
string folder = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "ESP32Display");
string folder = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "PCPal");
Directory.CreateDirectory(folder);
return Path.Combine(folder, "config.json");
}

View File

@@ -38,32 +38,53 @@ namespace PCPalService
{
Log("ESP32 Background Service Starting...");
try
while (!stoppingToken.IsCancellationRequested)
{
string portName = AutoDetectESP32();
if (portName == null)
try
{
Log("ESP32-C3 not found. Service stopping...");
throw new Exception("ESP32 not detected.");
if (!File.Exists(ConfigFile))
{
Log("Config file not found. Retrying in 5 seconds...");
await Task.Delay(5000, stoppingToken);
continue;
}
var config = LoadConfig();
if (serialPort == null || !serialPort.IsOpen)
{
string portName = AutoDetectESP32();
if (portName != null)
{
serialPort = new SerialPort(portName, 115200);
serialPort.Open();
Log($"Connected to ESP32-C3 on {portName}");
}
else
{
Log("ESP32-C3 not found. Retrying in 5 seconds...");
await Task.Delay(5000, stoppingToken);
continue;
}
}
string line1 = GetLCDContent(config.Line1Selection, config.Line1CustomText, config.Line1PostText);
string line2 = GetLCDContent(config.Line2Selection, config.Line2CustomText, config.Line2PostText);
SendCommand($"CMD:LCD,0,{line1}");
SendCommand($"CMD:LCD,1,{line2}");
}
catch (Exception ex)
{
Log($"Error in service loop: {ex.Message}");
}
serialPort = new SerialPort(portName, 115200);
serialPort.Open();
Log($"Connected to ESP32-C3 on {portName}");
await Task.Delay(5000, stoppingToken);
}
while (!stoppingToken.IsCancellationRequested)
{
UpdateLCD();
await Task.Delay(5000, stoppingToken);
}
}
catch (Exception ex)
{
Log($"Fatal Error: {ex.Message}");
Environment.Exit(1); // Force exit, triggering restart
}
serialPort?.Close();
}
private string AutoDetectESP32()
{
foreach (string port in SerialPort.GetPortNames())

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,74 @@
#include <Wire.h>
#include <LiquidCrystal_PCF8574.h>
LiquidCrystal_PCF8574 lcd(0x27); // I2C address for 1602A LCD
unsigned long lastMessageTime = 0;
const unsigned long timeoutDuration = 10000;
enum DisplayState { SPLASH, WAITING, ACTIVE };
DisplayState state = SPLASH;
unsigned long splashStartTime;
void setup() {
Wire.begin(8, 9); // SDA = GPIO 8, SCL = GPIO 9 (XIAO ESP32-C3)
lcd.begin(16, 2);
lcd.setBacklight(255);
Serial.begin(115200);
showSplashScreen();
splashStartTime = millis();
}
void loop() {
// Transition from splash to waiting after 5 seconds
if (state == SPLASH && millis() - splashStartTime >= 5000) {
showWaitingScreen();
state = WAITING;
}
// Process incoming commands from the PC
if (Serial.available()) {
String command = Serial.readStringUntil('\n');
command.trim();
if (command == "CMD:GET_LCD_TYPE") {
Serial.println("LCD_TYPE:1602A");
}
else if (command.startsWith("CMD:LCD,")) {
int line = command.charAt(8) - '0';
String text = command.substring(10);
text = text.substring(0, (text.length() < 16 ? text.length() : 16));
lcd.setCursor(0, line);
lcd.print(" "); // Clear line
lcd.setCursor(0, line);
lcd.print(text);
state = ACTIVE;
lastMessageTime = millis();
}
}
// If no message for a while, return to "waiting" screen
if (state == ACTIVE && millis() - lastMessageTime > timeoutDuration) {
showWaitingScreen();
state = WAITING;
}
}
void showSplashScreen() {
lcd.clear();
lcd.setCursor(2, 0);
lcd.print("Thermaltake");
lcd.setCursor(3, 1);
lcd.print("Tower 300");
}
void showWaitingScreen() {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Waiting for");
lcd.setCursor(0, 1);
lcd.print("connection...");
}