Updates to LCD firmware and service
This commit is contained in:
@@ -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");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
|
||||
@@ -38,32 +38,53 @@ namespace PCPalService
|
||||
{
|
||||
Log("ESP32 Background Service Starting...");
|
||||
|
||||
while (!stoppingToken.IsCancellationRequested)
|
||||
{
|
||||
try
|
||||
{
|
||||
string portName = AutoDetectESP32();
|
||||
if (portName == null)
|
||||
if (!File.Exists(ConfigFile))
|
||||
{
|
||||
Log("ESP32-C3 not found. Service stopping...");
|
||||
throw new Exception("ESP32 not detected.");
|
||||
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}");
|
||||
|
||||
while (!stoppingToken.IsCancellationRequested)
|
||||
{
|
||||
UpdateLCD();
|
||||
await Task.Delay(5000, stoppingToken);
|
||||
}
|
||||
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($"Fatal Error: {ex.Message}");
|
||||
Environment.Exit(1); // Force exit, triggering restart
|
||||
Log($"Error in service loop: {ex.Message}");
|
||||
}
|
||||
|
||||
await Task.Delay(5000, stoppingToken);
|
||||
}
|
||||
|
||||
serialPort?.Close();
|
||||
}
|
||||
|
||||
|
||||
private string AutoDetectESP32()
|
||||
{
|
||||
foreach (string port in SerialPort.GetPortNames())
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
74
PCPal_ESP32C3_Firmware/PCPal_ESP32C3_Firmware.ino
Normal file
74
PCPal_ESP32C3_Firmware/PCPal_ESP32C3_Firmware.ino
Normal 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...");
|
||||
}
|
||||
Reference in New Issue
Block a user