diff --git a/src/Display.cpp b/src/Display.cpp index dbbf74e..349e3f4 100644 --- a/src/Display.cpp +++ b/src/Display.cpp @@ -1,21 +1,21 @@ +#include "bootScreen.h" #include "Display.h" +#include "IRC.h" +#include "pins.h" +#include "Speaker.h" #include "Storage.h" #include "Utilities.h" -#include "Speaker.h" -#include "pins.h" -#include "bootScreen.h" -#include "IRC.h" -// External variables definitions -bool infoScreen = false; -bool configScreen = false; -bool screenOn = true; -const char* channel = "#comms"; -unsigned long infoScreenStartTime = 0; + +bool infoScreen = false; +bool configScreen = false; +bool screenOn = true; +const char* channel = "#comms"; +unsigned long infoScreenStartTime = 0; unsigned long configScreenStartTime = 0; -unsigned long lastStatusUpdateTime = 0; -unsigned long lastActivityTime = 0; -String inputBuffer = ""; +unsigned long lastStatusUpdateTime = 0; +unsigned long lastActivityTime = 0; +String inputBuffer = ""; std::vector lines; std::vector mentions; @@ -23,11 +23,13 @@ std::map nickColors; TFT_eSPI tft = TFT_eSPI(); + void addLine(String senderNick, String message, String type, bool mention, uint16_t errorColor, uint16_t reasonColor) { if (type != "error" && nickColors.find(senderNick) == nickColors.end()) nickColors[senderNick] = generateRandomColor(); String formattedMessage; + if (type == "join") { formattedMessage = "JOIN " + senderNick + " has joined " + String(channel); } else if (type == "part") { @@ -74,6 +76,7 @@ void addLine(String senderNick, String message, String type, bool mention, uint1 displayLines(); } + int calculateLinesRequired(String message) { int linesRequired = 1; int lineWidth = 0; @@ -103,6 +106,7 @@ int calculateLinesRequired(String message) { return linesRequired; } + void displayCenteredText(String text) { tft.fillScreen(TFT_BLACK); tft.setTextDatum(MC_DATUM); @@ -110,6 +114,7 @@ void displayCenteredText(String text) { tft.drawString(text, SCREEN_WIDTH / 2, (SCREEN_HEIGHT + STATUS_BAR_HEIGHT) / 2); } + void displayInputLine() { tft.fillRect(0, SCREEN_HEIGHT - INPUT_LINE_HEIGHT, SCREEN_WIDTH, INPUT_LINE_HEIGHT, TFT_BLACK); tft.setCursor(0, SCREEN_HEIGHT - INPUT_LINE_HEIGHT); @@ -132,6 +137,7 @@ void displayInputLine() { tft.setTextColor(TFT_WHITE); } + void displayLines() { tft.fillRect(0, STATUS_BAR_HEIGHT, SCREEN_WIDTH, SCREEN_HEIGHT - STATUS_BAR_HEIGHT - INPUT_LINE_HEIGHT, TFT_BLACK); @@ -260,6 +266,7 @@ void displayLines() { displayInputLine(); } + void displayXBM() { tft.fillScreen(TFT_BLACK); @@ -283,10 +290,12 @@ void displayXBM() { } } + uint32_t generateRandomColor() { return tft.color565(random(0, 255), random(0, 255), random(0, 255)); } + uint16_t getColorFromCode(int colorCode) { switch (colorCode) { case 0: return TFT_WHITE; @@ -392,6 +401,7 @@ uint16_t getColorFromCode(int colorCode) { } } + uint16_t getColorFromPercentage(int percentage) { if (percentage > 75) return TFT_GREEN; else if (percentage > 50) return TFT_YELLOW; @@ -399,6 +409,7 @@ uint16_t getColorFromPercentage(int percentage) { else return TFT_RED; } + void handleKeyboardInput(char key) { lastActivityTime = millis(); @@ -450,6 +461,7 @@ void handleKeyboardInput(char key) { } } + void parseAndDisplay(String line) { int firstSpace = line.indexOf(' '); int secondSpace = line.indexOf(' ', firstSpace + 1); @@ -518,6 +530,7 @@ void parseAndDisplay(String line) { } } + int renderFormattedMessage(String message, int cursorY, int lineHeight, bool highlightNick) { uint16_t fgColor = TFT_WHITE; uint16_t bgColor = TFT_BLACK; @@ -618,6 +631,18 @@ int renderFormattedMessage(String message, int cursorY, int lineHeight, bool hig return cursorY; } + +void setupScreen() { + pinMode(TFT_BL, OUTPUT); + digitalWrite(TFT_BL, HIGH); + setBrightness(8); + tft.begin(); + tft.setRotation(1); + tft.invertDisplay(1); + Serial.println("TFT initialized"); +} + + void turnOffScreen() { Serial.println("Screen turned off"); tft.writecommand(TFT_DISPOFF); @@ -626,6 +651,7 @@ void turnOffScreen() { screenOn = false; } + void turnOnScreen() { Serial.println("Screen turned on"); digitalWrite(TFT_BL, HIGH); @@ -634,6 +660,7 @@ void turnOnScreen() { screenOn = true; } + void updateStatusBar() { Serial.println("Updating status bar..."); uint16_t darkerGrey = tft.color565(25, 25, 25); diff --git a/src/Display.h b/src/Display.h index 304b94e..696b62e 100644 --- a/src/Display.h +++ b/src/Display.h @@ -1,28 +1,27 @@ #pragma once -#include #include #include -#include #include -// Constants +#include +#include + #define CHAR_HEIGHT 10 #define LINE_SPACING 0 #define STATUS_BAR_HEIGHT 10 #define INPUT_LINE_HEIGHT (CHAR_HEIGHT + LINE_SPACING) #define MAX_LINES ((SCREEN_HEIGHT - INPUT_LINE_HEIGHT - STATUS_BAR_HEIGHT) / (CHAR_HEIGHT + LINE_SPACING)) -// External variables -extern bool infoScreen; -extern bool configScreen; -extern bool screenOn; -extern const char* channel; +extern bool infoScreen; +extern bool configScreen; +extern bool screenOn; +extern const char* channel; extern unsigned long infoScreenStartTime; extern unsigned long configScreenStartTime; extern unsigned long lastStatusUpdateTime; extern unsigned long lastActivityTime; -extern String inputBuffer; +extern String inputBuffer; extern std::vector lines; extern std::vector mentions; @@ -30,7 +29,6 @@ extern std::map nickColors; extern TFT_eSPI tft; -// Function declarations void addLine(String senderNick, String message, String type, bool mention = false, uint16_t errorColor = TFT_WHITE, uint16_t reasonColor = TFT_WHITE); int calculateLinesRequired(String message); void displayCenteredText(String text); @@ -43,6 +41,7 @@ uint16_t getColorFromPercentage(int percentage); void handleKeyboardInput(char key); void parseAndDisplay(String line); int renderFormattedMessage(String message, int cursorY, int lineHeight, bool highlightNick = false); +void setupScreen(); void turnOffScreen(); void turnOnScreen(); void updateStatusBar(); diff --git a/src/IRC.cpp b/src/IRC.cpp index c74177d..035aef0 100644 --- a/src/IRC.cpp +++ b/src/IRC.cpp @@ -7,6 +7,11 @@ bool readyToJoinChannel = false; WiFiClient* client; +void action(String target, String message) { + sendIRC("PRIVMSG " + String(target) + " :\001ACTION " + message + "\001"); +} + + bool connectToIRC() { if (irc_tls) { Serial.println("Connecting to IRC with TLS: " + String(irc_server) + ":" + String(irc_port)); diff --git a/src/IRC.h b/src/IRC.h index 4479fe8..91cb17f 100644 --- a/src/IRC.h +++ b/src/IRC.h @@ -9,6 +9,7 @@ extern WiFiClient* client; extern unsigned long joinChannelTime; extern bool readyToJoinChannel; +void action(String target, String message); bool connectToIRC(); void handleIRC(); void sendIRC(String command); diff --git a/src/Network.cpp b/src/Network.cpp index 3af164a..3db20ad 100644 --- a/src/Network.cpp +++ b/src/Network.cpp @@ -8,6 +8,7 @@ WireGuard wg; void connectToWiFi(String ssid, String password) { + wifiNetworks.clear(); Serial.println("Connecting to WiFi network: " + ssid); WiFi.begin(ssid.c_str(), password.c_str()); @@ -167,6 +168,14 @@ void handleWiFiSelection(char key) { } +void initializeNetwork() { + WiFi.mode(WIFI_STA); + WiFi.setHostname("acid-drop"); // Turn into a preference + WiFi.onEvent(WiFiEvent); + randomizeMacAddress(); +} + + void randomizeMacAddress() { Serial.println("Current MAC Address: " + WiFi.macAddress()); @@ -178,7 +187,7 @@ void randomizeMacAddress() { if (esp_wifi_set_mac(WIFI_IF_STA, new_mac) == ESP_OK) Serial.println("New MAC Address: " + WiFi.macAddress()); else - Serial.print("Failed to set new MAC Address"); + Serial.println("Failed to set new MAC Address"); } @@ -187,6 +196,8 @@ void scanWiFiNetworks() { displayCenteredText("SCANNING WIFI"); delay(1000); + wifiNetworks.clear(); + int n = WiFi.scanNetworks(); if (n == 0) { diff --git a/src/Network.h b/src/Network.h index 6ec0aeb..81e8aa6 100644 --- a/src/Network.h +++ b/src/Network.h @@ -29,6 +29,7 @@ void displayWiFiNetwork(int index, int displayIndex); String getEncryptionType(wifi_auth_mode_t encryptionType); void handlePasswordInput(char key); void handleWiFiSelection(char key); +void initializeNetwork(); void randomizeMacAddress(); void scanWiFiNetworks(); void updateSelectedNetwork(int delta); diff --git a/src/main.ino b/src/main.ino index 5ee981e..6f9589c 100644 --- a/src/main.ino +++ b/src/main.ino @@ -2,39 +2,39 @@ #include // Local includes -#include "bootScreen.h" -#include "Lora.h" -#include "pins.h" -#include "Storage.h" -#include "Speaker.h" -#include "Utilities.h" #include "Display.h" -#include "Network.h" #include "IRC.h" +#include "Lora.h" +#include "Network.h" +#include "pins.h" +#include "Speaker.h" +#include "Storage.h" +#include "Utilities.h" // Timing constants const unsigned long STATUS_UPDATE_INTERVAL = 15000; // 15 seconds -const unsigned long INACTIVITY_TIMEOUT = 30000; // 30 seconds +const unsigned long INACTIVITY_TIMEOUT = 30000; // 30 seconds // Main functions --------------------------------------------------------------------------------- void setup() { // Initialize serial communication Serial.begin(115200); - - // Wait for the serial monitor to open - //while (!Serial); - Serial.println("Booting device..."); // Give power to the board peripherals pinMode(BOARD_POWERON, OUTPUT); digitalWrite(BOARD_POWERON, HIGH); - // Give power to the screen - pinMode(TFT_BL, OUTPUT); - digitalWrite(TFT_BL, HIGH); - setBrightness(8); // Set the screen brightness to 50%) + // Start the I2C bus for the keyboard + Wire.begin(BOARD_I2C_SDA, BOARD_I2C_SCL); + + // Initialize the display + setupScreen(); + displayXBM(); + + // Load preferences from storage + loadPreferences(); // Give power to the SD card //setupSD(); @@ -42,32 +42,15 @@ void setup() { // Turn on power to the radio //setupRadio(); - - // Start the I2C bus for the keyboard - Wire.begin(BOARD_I2C_SDA, BOARD_I2C_SCL); - // Initialize the screen - tft.begin(); - tft.setRotation(1); - tft.invertDisplay(1); - Serial.println("TFT initialized"); - - // Display the boot screen - displayXBM(); - - // Initialize the preferences - loadPreferences(); + // Setup the WiFi + initializeNetwork(); // Initialize the speaker setupI2S(); // Do we want to keep this open or uninstall after each use to keep resources free? const char* rtttl_boot = "TakeOnMe:d=4,o=4,b=500:8f#5,8f#5,8f#5,8d5,8p,8b,8p,8e5,8p,8e5,8p,8e5,8g#5,8g#5,8a5,8b5,8a5,8a5,8a5,8e5,8p,8d5,8p,8f#5,8p,8f#5,8p,8f#5,8e5,8e5,8f#5,8e5,8f#5,8f#5,8f#5,8d5,8p,8b,8p,8e5,8p,8e5,8p,8e5,8g#5,8g#5,8a5,8b5,8a5,8a5,8a5,8e5,8p,8d5,8p,8f#5,8p,8f#5,8p,8f#5,8e5,8e5"; playRTTTL(rtttl_boot); - // Setup the WiFi - WiFi.mode(WIFI_STA); - WiFi.setHostname("acid-drop"); // Turn into a preference - WiFi.onEvent(WiFiEvent); - randomizeMacAddress(); // Connect to WiFi if credentials are stored, otherwise scan for networks if (wifi_ssid.length() > 0 && wifi_password.length() > 0) {