Archives
Trending
Support
Login
clear text
XML
Django
JavaScript
MATLAB
C
C++
C#
Python
SQL
Shell
Bash
Markdown
YAML
JSON
HTML
CSS
PHP
Java
Ruby
Go
Rust
Swift
Kotlin
Arduino
TypeScript
Perl
Autohotkey
Lua
SQF
R
Scala
Haskell
Groovy
Dart
Clojure
VB.NET
Objective-C
PowerShell
Bash
CoffeeScript
Verilog
/********* Pleasedontcode.com ********** Pleasedontcode thanks you for automatic code generation! Enjoy your code! - Terms and Conditions: You have a non-exclusive, revocable, worldwide, royalty-free license for personal and commercial use. Attribution is optional; modifications are allowed, but you're responsible for code maintenance. We're not liable for any loss or damage. For full terms, please visit pleasedontcode.com/termsandconditions. - Project: # Relay Controller - Source Code NOT compiled for: ESP8266 NodeMCU V1.0 - Source Code created on: 2026-02-05 14:55:51 ********* Pleasedontcode.com **********/ /****** SYSTEM REQUIREMENTS *****/ /****** SYSTEM REQUIREMENT 1 *****/ /* add i2c gpio expander PCF8574 */ /****** END SYSTEM REQUIREMENTS *****/ #include "PCF8574.h" #include "Relay.h" #include "VoiceAssistant.h" // Create PCF8574 instance with default I2C address 0x20 // Address range: 0x20 to 0x27 depending on A0, A1, A2 pins PCF8574 expander(0x20); // Create Relay instance for managing 8 relays Relay relayController(&expander, 8); // Create VoiceAssistant instance VoiceAssistant* voiceAssistant = nullptr; // WiFi Configuration // IMPORTANT: Replace these with your actual WiFi credentials const char* WIFI_SSID = "YourWiFiSSID"; const char* WIFI_PASSWORD = "YourWiFiPassword"; // Google Cloud Speech-to-Text API Configuration // IMPORTANT: Replace these with your actual Google Cloud credentials const char* GOOGLE_API_KEY = "YOUR_GOOGLE_CLOUD_API_KEY_HERE"; const char* GOOGLE_PROJECT_ID = "YOUR_GOOGLE_PROJECT_ID_HERE"; // Serial command buffer String commandBuffer = ""; // Timestamp for periodic status monitoring unsigned long lastStatusTime = 0; unsigned long statusInterval = 5000; // Print status every 5 seconds // Voice command request flag volatile bool voiceCommandRequested = false; unsigned long voiceCommandRequestTime = 0; const unsigned long voiceCommandDebounce = 1000; // Debounce time for voice command requests // Relay state change log struct RelayLog { uint32_t timestamp; uint8_t relayNum; bool state; // true = ON, false = OFF char action[20]; }; // Log buffer for relay state changes (last 10 changes) RelayLog relayLogs[10]; uint8_t logIndex = 0; /****** FUNCTION PROTOTYPES *****/ void setup(void); void loop(void); void processSerialCommand(String command); void handleRelayCommand(String command); void printAvailableCommands(void); void logRelayStateChange(uint8_t relayNum, bool newState, const char* action); void printRelayLogs(void); void printRelayStatusMonitoring(void); void processVoiceCommand(void); void initializeVoiceAssistant(void); void setup(void) { // Initialize Serial communication Serial.begin(115200); delay(100); Serial.println("\n\n================================================"); Serial.println(" PCF8574 I2C GPIO Expander with Relays "); Serial.println(" + Voice Assistant Support "); Serial.println("================================================"); Serial.println(); // Initialize PCF8574 with I2C address 0x20 // Using default ESP8266 pins: SDA=4 (D2), SCL=5 (D1) Serial.println("Initializing PCF8574 I2C GPIO Expander..."); if (expander.begin()) { Serial.println("[SUCCESS] PCF8574 initialized successfully!"); Serial.print("[INFO] I2C Address: 0x"); Serial.println(0x20, HEX); Serial.println("[INFO] I2C Pins: SDA=4 (D2), SCL=5 (D1)"); // Initialize all relay pins to HIGH (default/inactive state) expander.writePort(0xFF); Serial.println("[INFO] All relay pins set to HIGH (inactive)"); delay(500); // Initialize Relay controller Serial.println(); Serial.println("Initializing Relay Controller..."); relayController.init(); Serial.println(); Serial.println("[SUCCESS] System fully initialized and ready!"); Serial.println(); // Initialize Voice Assistant with WiFi and Google Cloud API delay(1000); Serial.println(); initializeVoiceAssistant(); delay(1000); // Print help information printAvailableCommands(); // Initialize log timestamps lastStatusTime = millis(); } else { Serial.println("[ERROR] Failed to initialize PCF8574!"); Serial.println("[ERROR] Please check:"); Serial.println(" - I2C connections (SDA=D2/GPIO4, SCL=D1/GPIO5)"); Serial.println(" - PCF8574 I2C address (default 0x20, check A0/A1/A2 pins)"); Serial.println(" - PCF8574 power supply (VCC and GND)"); Serial.println(); Serial.println("System will continue but relay control may not work."); } delay(1000); } void loop(void) { // Check for serial commands if (Serial.available()) { char inChar = Serial.read(); // Handle enter key (carriage return or newline) if (inChar == '\r' || inChar == '\n') { if (commandBuffer.length() > 0) { Serial.println(); // Echo newline Serial.print("[COMMAND] "); Serial.println(commandBuffer); processSerialCommand(commandBuffer); commandBuffer = ""; // Clear buffer } } // Handle backspace else if (inChar == '\b') { if (commandBuffer.length() > 0) { commandBuffer.remove(commandBuffer.length() - 1); Serial.print(inChar); // Echo backspace } } // Add character to buffer else if (inChar >= 32 && inChar <= 126) { // Printable ASCII characters commandBuffer += inChar; Serial.print(inChar); // Echo character } } // Check if voice command was requested via serial if (voiceCommandRequested && (millis() - voiceCommandRequestTime >= voiceCommandDebounce)) { voiceCommandRequested = false; processVoiceCommand(); } // Periodic status monitoring and logging if (millis() - lastStatusTime >= statusInterval) { lastStatusTime = millis(); printRelayStatusMonitoring(); } // Small delay to prevent watchdog timeout delay(10); } // Initialize VoiceAssistant with WiFi and Google Cloud API credentials void initializeVoiceAssistant(void) { Serial.println("=== Initializing Voice Assistant System ==="); // Create VoiceAssistant instance voiceAssistant = new VoiceAssistant(&relayController); if (voiceAssistant == nullptr) { Serial.println("[ERROR] Failed to allocate memory for VoiceAssistant!"); return; } // Begin voice assistant initialization with WiFi and API credentials if (voiceAssistant->begin(WIFI_SSID, WIFI_PASSWORD, GOOGLE_API_KEY, GOOGLE_PROJECT_ID)) { Serial.println("[SUCCESS] Voice Assistant initialized successfully!"); // Configure audio settings (16kHz, Mono, 16-bit, 10 second timeout) voiceAssistant->setAudioConfig(16000, 1, 16, 10000); // Print voice assistant status voiceAssistant->printStatus(); voiceAssistant->printConfiguration(); Serial.println("=== Voice Assistant Ready ==="); Serial.println("[INFO] Voice commands are now available!"); Serial.println("[INFO] Type 'voice' command to process voice commands"); Serial.println("[INFO] Type 'vtest
' to test voice parsing"); Serial.println(); } else { Serial.println("[ERROR] Failed to initialize Voice Assistant!"); Serial.println("[ERROR] WiFi connection failed or API credentials invalid"); Serial.println("[INFO] System will continue with relay control only"); // Clean up on failure delete voiceAssistant; voiceAssistant = nullptr; } Serial.println("========================================"); Serial.println(); } // Process voice command from microphone void processVoiceCommand(void) { if (voiceAssistant == nullptr) { Serial.println("[ERROR] Voice Assistant not initialized!"); return; } if (!voiceAssistant->isInitialized()) { Serial.println("[ERROR] Voice Assistant not ready!"); return; } Serial.println(); Serial.println("================================================"); Serial.println(" Starting Voice Command Processing "); Serial.println("================================================"); // Process voice command from microphone VoiceCommandResult result = voiceAssistant->processVoiceCommand(); Serial.println(); Serial.print("[VOICE] Processing Result: "); switch(result) { case VOICE_CMD_SUCCESS: Serial.println("SUCCESS"); Serial.println("[VOICE] Command executed successfully!"); break; case VOICE_CMD_WIFI_NOT_CONNECTED: Serial.println("ERROR - WiFi Not Connected"); Serial.println("[VOICE] Attempting to reconnect to WiFi..."); voiceAssistant->reconnectWiFi(); break; case VOICE_CMD_API_ERROR: Serial.println("ERROR - Google Cloud API Error"); Serial.println("[VOICE] Failed to communicate with Google Cloud Speech-to-Text API"); break; case VOICE_CMD_AUDIO_CAPTURE_FAILED: Serial.println("ERROR - Audio Capture Failed"); Serial.println("[VOICE] Failed to capture audio from microphone"); break; case VOICE_CMD_PARSE_FAILED: Serial.println("ERROR - Command Parse Failed"); Serial.println("[VOICE] Could not parse the recognized speech into a valid command"); break; case VOICE_CMD_INVALID_RELAY: Serial.println("ERROR - Invalid Relay Number"); Serial.println("[VOICE] The recognized relay number is out of range (0-7)"); break; case VOICE_CMD_TIMEOUT: Serial.println("ERROR - Command Timeout"); Serial.println("[VOICE] Voice command processing timed out"); break; case VOICE_CMD_BUSY: Serial.println("ERROR - System Busy"); Serial.println("[VOICE] Voice Assistant is currently busy processing a command"); break; default: Serial.println("UNKNOWN ERROR"); break; } Serial.println(); Serial.println("================================================"); Serial.println(); // Print current relay status relayController.printStatus(); // Print voice command log voiceAssistant->printVoiceCommandLog(); } // Process serial commands from user void processSerialCommand(String command) { // Convert to lowercase for case-insensitive handling command.toLowerCase(); // Trim whitespace command.trim(); // Empty command if (command.length() == 0) { return; } // Help command if (command == "help" || command == "?") { printAvailableCommands(); return; } // Status command - print current relay states if (command == "status" || command == "s") { Serial.println(); relayController.printStatus(); Serial.println(); return; } // Logs command - print relay change logs if (command == "logs" || command == "l") { Serial.println(); printRelayLogs(); Serial.println(); return; } // Clear logs command if (command == "clrlogs" || command == "cl") { logIndex = 0; Serial.println("[INFO] Relay logs cleared"); Serial.println(); return; } // Voice Assistant commands if (voiceAssistant != nullptr) { // Voice command - process audio from microphone if (command == "voice" || command == "v") { voiceCommandRequested = true; voiceCommandRequestTime = millis(); return; } // Voice test command - test voice parsing with a string if (command.startsWith("vtest ")) { String testCommand = command.substring(6); testCommand.trim(); if (testCommand.length() > 0) { Serial.println(); Serial.println("=== Testing Voice Command Parsing ==="); Serial.print("[VOICE] Test command: "); Serial.println(testCommand); VoiceCommandResult result = voiceAssistant->executeCommandFromString(testCommand); Serial.println(); Serial.print("[VOICE] Parse result: "); switch(result) { case VOICE_CMD_SUCCESS: Serial.println("SUCCESS"); break; case VOICE_CMD_PARSE_FAILED: Serial.println("PARSE FAILED"); break; case VOICE_CMD_INVALID_RELAY: Serial.println("INVALID RELAY"); break; default: Serial.println("ERROR"); break; } Serial.println("[VOICE] ===================================="); Serial.println(); relayController.printStatus(); } else { Serial.println("[ERROR] Please provide a test command. Usage: vtest
"); } return; } // Voice command log command if (command == "vlogs" || command == "vl") { voiceAssistant->printVoiceCommandLog(); return; } // Clear voice command logs if (command == "vclrlogs" || command == "vcl") { voiceAssistant->clearVoiceCommandLog(); Serial.println(); return; } // Voice assistant status command if (command == "vstatus" || command == "vs") { voiceAssistant->printStatus(); return; } // Voice assistant configuration command if (command == "vconfig" || command == "vc") { voiceAssistant->printConfiguration(); return; } } // Turn off all relays if (command == "alloff" || command == "off") { Serial.println(); relayController.turnOffAll(); logRelayStateChange(255, false, "ALL OFF"); relayController.printStatus(); Serial.println(); return; } // Test mode - cycle through all relays if (command == "test" || command == "t") { Serial.println(); Serial.println("[TEST] Starting relay test sequence..."); Serial.println("[TEST] Turning ON each relay for 1 second..."); Serial.println(); for (uint8_t i = 0; i < 8; i++) { Serial.print("[TEST] Testing Relay "); Serial.println(i); relayController.turnOn(i); delay(1000); relayController.turnOff(i); delay(200); } Serial.println(); Serial.println("[TEST] Relay test sequence completed!"); Serial.println(); return; } // Relay control commands if (command.startsWith("on ") || command.startsWith("off ") || command.startsWith("toggle ") || command.startsWith("tog ")) { handleRelayCommand(command); return; } // Check for single digit commands (quick on/off) if (command.length() == 1 && isDigit(command[0])) { uint8_t relayNum = command[0] - '0'; if (relayNum < 8) { Serial.println(); relayController.toggle(relayNum); logRelayStateChange(relayNum, relayController.getState(relayNum), "TOGGLE"); relayController.printStatus(); Serial.println(); return; } } // Unknown command Serial.println("[ERROR] Unknown command. Type 'help' for available commands."); Serial.println(); } // Handle relay-specific commands (on/off/toggle) void handleRelayCommand(String command) { String action = ""; uint8_t relayNum = 255; Serial.println(); // Parse "on" commands if (command.startsWith("on ")) { action = "ON"; command = command.substring(3); command.trim(); if (command.length() > 0 && isDigit(command[0])) { relayNum = command[0] - '0'; } } // Parse "off" commands else if (command.startsWith("off ")) { action = "OFF"; command = command.substring(4); command.trim(); if (command.length() > 0 && isDigit(command[0])) { relayNum = command[0] - '0'; } } // Parse "toggle" or "tog" commands else if (command.startsWith("toggle ")) { action = "TOGGLE"; command = command.substring(7); command.trim(); if (command.length() > 0 && isDigit(command[0])) { relayNum = command[0] - '0'; } } else if (command.startsWith("tog ")) { action = "TOGGLE"; command = command.substring(4); command.trim(); if (command.length() > 0 && isDigit(command[0])) { relayNum = command[0] - '0'; } } // Execute command if relay number is valid if (relayNum < 8) { if (action == "ON") { relayController.turnOn(relayNum); logRelayStateChange(relayNum, true, "ON"); } else if (action == "OFF") { relayController.turnOff(relayNum); logRelayStateChange(relayNum, false, "OFF"); } else if (action == "TOGGLE") { relayController.toggle(relayNum); logRelayStateChange(relayNum, relayController.getState(relayNum), "TOGGLE"); } relayController.printStatus(); } else { Serial.print("[ERROR] Invalid relay number. Use 0-7. Got: "); Serial.println(command); } Serial.println(); } // Print available commands void printAvailableCommands(void) { Serial.println(); Serial.println("================================================"); Serial.println(" Available Serial Commands "); Serial.println("================================================"); Serial.println(); Serial.println("Relay Control Commands:"); Serial.println(" on
- Turn ON relay n (0-7)"); Serial.println(" off
- Turn OFF relay n (0-7)"); Serial.println(" toggle
- Toggle relay n (0-7)"); Serial.println(" tog
- Toggle relay n (0-7) [shorthand]"); Serial.println("
- Quick toggle relay n (0-7)"); Serial.println(" alloff - Turn OFF all relays"); Serial.println(" off - Turn OFF all relays [shorthand]"); Serial.println(); Serial.println("Voice Assistant Commands (requires WiFi & API credentials):"); Serial.println(" voice, v - Process voice command from microphone"); Serial.println(" vtest
- Test voice parsing with command string"); Serial.println(" vlogs, vl - Display voice command logs"); Serial.println(" vclrlogs,vc - Clear voice command logs"); Serial.println(" vstatus, vs - Display voice assistant status"); Serial.println(" vconfig, vc - Display voice assistant configuration"); Serial.println(); Serial.println("System Commands:"); Serial.println(" status, s - Display current relay status"); Serial.println(" logs, l - Display relay change log"); Serial.println(" clrlogs, cl - Clear relay change log"); Serial.println(" test, t - Run relay test sequence"); Serial.println(" help, ? - Display this help message"); Serial.println(); Serial.println("Example: Type 'on 0' to turn ON relay 0"); Serial.println("Example: Type 'vtest turn on relay 3' to test voice parsing"); Serial.println("================================================"); Serial.println(); } // Log relay state changes void logRelayStateChange(uint8_t relayNum, bool newState, const char* action) { // Special handling for "ALL OFF" action if (relayNum == 255) { // Log all relays being turned off for (uint8_t i = 0; i < 8; i++) { RelayLog& log = relayLogs[logIndex % 10]; log.timestamp = millis(); log.relayNum = i; log.state = false; strncpy(log.action, action, sizeof(log.action) - 1); log.action[sizeof(log.action) - 1] = '\0'; logIndex++; } } else { RelayLog& log = relayLogs[logIndex % 10]; log.timestamp = millis(); log.relayNum = relayNum; log.state = newState; strncpy(log.action, action, sizeof(log.action) - 1); log.action[sizeof(log.action) - 1] = '\0'; logIndex++; } } // Print relay state change logs void printRelayLogs(void) { Serial.println("=== Relay Change Log (Last 10 changes) ==="); if (logIndex == 0) { Serial.println("No relay changes recorded yet."); } else { // Calculate start index for circular buffer uint8_t startIdx = (logIndex >= 10) ? (logIndex % 10) : 0; uint8_t count = (logIndex >= 10) ? 10 : logIndex; for (uint8_t i = 0; i < count; i++) { uint8_t idx = (startIdx + i) % 10; RelayLog& log = relayLogs[idx]; Serial.print("["); Serial.print(log.timestamp / 1000); Serial.print("s] Relay "); Serial.print(log.relayNum); Serial.print(": "); Serial.print(log.state ? "ON" : "OFF"); Serial.print(" ("); Serial.print(log.action); Serial.println(")"); } } Serial.println("==========================================="); } // Print relay status monitoring with periodic updates void printRelayStatusMonitoring(void) { // Calculate uptime uint32_t uptimeSeconds = millis() / 1000; uint8_t hours = uptimeSeconds / 3600; uint8_t minutes = (uptimeSeconds % 3600) / 60; uint8_t seconds = uptimeSeconds % 60; Serial.println(); Serial.println("--------- Relay Status Monitor (Periodic) --------"); Serial.print("Uptime: "); if (hours < 10) Serial.print("0"); Serial.print(hours); Serial.print(":"); if (minutes < 10) Serial.print("0"); Serial.print(minutes); Serial.print(":"); if (seconds < 10) Serial.print("0"); Serial.println(seconds); // Print all relay states Serial.println("Current Relay States:"); for (uint8_t i = 0; i < 8; i++) { Serial.print(" Relay "); Serial.print(i); Serial.print(": "); Serial.println(relayController.getState(i) ? "ON " : "OFF"); } // Print number of logged changes Serial.print("Total logged relay changes: "); Serial.println(logIndex); // Print voice assistant status if available if (voiceAssistant != nullptr && voiceAssistant->isInitialized()) { Serial.print("Voice Assistant WiFi: "); Serial.println(voiceAssistant->isWiFiConnected() ? "CONNECTED" : "DISCONNECTED"); Serial.print("Voice Commands Logged: "); Serial.println(voiceAssistant->getCommandLogCount()); // Attempt to reconnect WiFi if disconnected if (!voiceAssistant->isWiFiConnected()) { Serial.println("[INFO] Attempting WiFi reconnection..."); voiceAssistant->reconnectWiFi(); } } Serial.println("--------------------------------------------------"); Serial.println(); } /* END CODE */
Mark as private (unlisted)
for 30 minutes
for 6 hours
for 1 day
for 1 week
for 1 month
for 1 year
everlasting (like CCCP)