Add main ESP32 firmware with Bluetooth control
This commit is contained in:
240
esp32_bluetooth_relay/esp32_bluetooth_relay.ino
Normal file
240
esp32_bluetooth_relay/esp32_bluetooth_relay.ino
Normal file
@@ -0,0 +1,240 @@
|
||||
/*
|
||||
* ESP32 8-Channel Bluetooth Relay Controller
|
||||
*
|
||||
* Features:
|
||||
* - Control 8 relays via Bluetooth Serial
|
||||
* - Individual relay on/off control
|
||||
* - All relays on/off commands
|
||||
* - Status query for all relays
|
||||
* - Toggle individual relays
|
||||
* - Persistent state (remembers relay states on reboot)
|
||||
*
|
||||
* Commands:
|
||||
* - ON1-8: Turn on relay 1-8
|
||||
* - OFF1-8: Turn off relay 1-8
|
||||
* - TOGGLE1-8: Toggle relay 1-8
|
||||
* - ALL_ON: Turn all relays on
|
||||
* - ALL_OFF: Turn all relays off
|
||||
* - STATUS: Get status of all relays
|
||||
* - HELP: Show available commands
|
||||
*/
|
||||
|
||||
#include "BluetoothSerial.h"
|
||||
#include <Preferences.h>
|
||||
|
||||
// Check if Bluetooth is enabled
|
||||
#if !defined(CONFIG_BT_ENABLED) || !defined(CONFIG_BLUEDROID_ENABLED)
|
||||
#error Bluetooth is not enabled! Please run `make menuconfig` to enable it
|
||||
#endif
|
||||
|
||||
// Bluetooth Serial object
|
||||
BluetoothSerial SerialBT;
|
||||
|
||||
// Preferences for persistent storage
|
||||
Preferences preferences;
|
||||
|
||||
// Define relay pins (adjust these based on your ESP32 board)
|
||||
const int relayPins[8] = {13, 12, 14, 27, 26, 25, 33, 32};
|
||||
|
||||
// Relay states (true = ON, false = OFF)
|
||||
bool relayStates[8] = {false, false, false, false, false, false, false, false};
|
||||
|
||||
// Relay names for easier identification
|
||||
const char* relayNames[8] = {
|
||||
"Relay 1", "Relay 2", "Relay 3", "Relay 4",
|
||||
"Relay 5", "Relay 6", "Relay 7", "Relay 8"
|
||||
};
|
||||
|
||||
// Device name for Bluetooth
|
||||
const char* deviceName = "ESP32-Relay-8CH";
|
||||
|
||||
// Command buffer
|
||||
String commandBuffer = "";
|
||||
|
||||
void setup() {
|
||||
// Initialize serial for debugging
|
||||
Serial.begin(115200);
|
||||
Serial.println("\nESP32 8-Channel Bluetooth Relay Controller");
|
||||
Serial.println("==========================================");
|
||||
|
||||
// Initialize preferences
|
||||
preferences.begin("relay-states", false);
|
||||
|
||||
// Initialize relay pins
|
||||
for (int i = 0; i < 8; i++) {
|
||||
pinMode(relayPins[i], OUTPUT);
|
||||
|
||||
// Load saved state from preferences
|
||||
relayStates[i] = preferences.getBool(String("relay" + String(i)).c_str(), false);
|
||||
|
||||
// Set initial state (relays are typically active LOW)
|
||||
digitalWrite(relayPins[i], relayStates[i] ? LOW : HIGH);
|
||||
|
||||
Serial.printf("Pin %d (%s): %s\n", relayPins[i], relayNames[i],
|
||||
relayStates[i] ? "ON" : "OFF");
|
||||
}
|
||||
|
||||
// Initialize Bluetooth Serial
|
||||
if(!SerialBT.begin(deviceName)) {
|
||||
Serial.println("Bluetooth initialization failed!");
|
||||
while(1);
|
||||
}
|
||||
|
||||
Serial.printf("\nBluetooth device \"%s\" is ready to pair!\n", deviceName);
|
||||
Serial.println("Waiting for Bluetooth connection...\n");
|
||||
|
||||
// Print available commands
|
||||
printHelp();
|
||||
}
|
||||
|
||||
void loop() {
|
||||
// Check for Bluetooth data
|
||||
while (SerialBT.available()) {
|
||||
char inChar = (char)SerialBT.read();
|
||||
|
||||
// Add character to buffer
|
||||
if (inChar == '\n' || inChar == '\r') {
|
||||
// Process command when newline is received
|
||||
if (commandBuffer.length() > 0) {
|
||||
processCommand(commandBuffer);
|
||||
commandBuffer = "";
|
||||
}
|
||||
} else {
|
||||
commandBuffer += inChar;
|
||||
}
|
||||
}
|
||||
|
||||
// Small delay to prevent watchdog issues
|
||||
delay(10);
|
||||
}
|
||||
|
||||
void processCommand(String command) {
|
||||
command.trim();
|
||||
command.toUpperCase();
|
||||
|
||||
Serial.printf("Received command: %s\n", command.c_str());
|
||||
|
||||
// ON commands (ON1 through ON8)
|
||||
if (command.startsWith("ON") && command.length() == 3) {
|
||||
int relayNum = command.charAt(2) - '0';
|
||||
if (relayNum >= 1 && relayNum <= 8) {
|
||||
setRelay(relayNum - 1, true);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// OFF commands (OFF1 through OFF8)
|
||||
if (command.startsWith("OFF") && command.length() == 4) {
|
||||
int relayNum = command.charAt(3) - '0';
|
||||
if (relayNum >= 1 && relayNum <= 8) {
|
||||
setRelay(relayNum - 1, false);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// TOGGLE commands (TOGGLE1 through TOGGLE8)
|
||||
if (command.startsWith("TOGGLE") && command.length() == 7) {
|
||||
int relayNum = command.charAt(6) - '0';
|
||||
if (relayNum >= 1 && relayNum <= 8) {
|
||||
toggleRelay(relayNum - 1);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// ALL_ON command
|
||||
if (command == "ALL_ON" || command == "ALLON") {
|
||||
setAllRelays(true);
|
||||
return;
|
||||
}
|
||||
|
||||
// ALL_OFF command
|
||||
if (command == "ALL_OFF" || command == "ALLOFF") {
|
||||
setAllRelays(false);
|
||||
return;
|
||||
}
|
||||
|
||||
// STATUS command
|
||||
if (command == "STATUS" || command == "STATE") {
|
||||
sendStatus();
|
||||
return;
|
||||
}
|
||||
|
||||
// HELP command
|
||||
if (command == "HELP" || command == "?") {
|
||||
printHelp();
|
||||
return;
|
||||
}
|
||||
|
||||
// Unknown command
|
||||
SerialBT.println("ERROR: Unknown command");
|
||||
Serial.println("ERROR: Unknown command");
|
||||
SerialBT.println("Type HELP for available commands");
|
||||
}
|
||||
|
||||
void setRelay(int relayIndex, bool state) {
|
||||
if (relayIndex < 0 || relayIndex >= 8) return;
|
||||
|
||||
relayStates[relayIndex] = state;
|
||||
|
||||
// Relays are typically active LOW (relay on when pin is LOW)
|
||||
digitalWrite(relayPins[relayIndex], state ? LOW : HIGH);
|
||||
|
||||
// Save state to preferences
|
||||
preferences.putBool(String("relay" + String(relayIndex)).c_str(), state);
|
||||
|
||||
// Send confirmation
|
||||
String response = String(relayNames[relayIndex]) + " is now " +
|
||||
(state ? "ON" : "OFF");
|
||||
SerialBT.println(response);
|
||||
Serial.println(response);
|
||||
}
|
||||
|
||||
void toggleRelay(int relayIndex) {
|
||||
if (relayIndex < 0 || relayIndex >= 8) return;
|
||||
|
||||
setRelay(relayIndex, !relayStates[relayIndex]);
|
||||
}
|
||||
|
||||
void setAllRelays(bool state) {
|
||||
for (int i = 0; i < 8; i++) {
|
||||
relayStates[i] = state;
|
||||
digitalWrite(relayPins[i], state ? LOW : HIGH);
|
||||
preferences.putBool(String("relay" + String(i)).c_str(), state);
|
||||
}
|
||||
|
||||
String response = "All relays turned " + String(state ? "ON" : "OFF");
|
||||
SerialBT.println(response);
|
||||
Serial.println(response);
|
||||
}
|
||||
|
||||
void sendStatus() {
|
||||
SerialBT.println("=== Relay Status ===");
|
||||
Serial.println("=== Relay Status ===");
|
||||
|
||||
for (int i = 0; i < 8; i++) {
|
||||
String status = String(relayNames[i]) + ": " +
|
||||
(relayStates[i] ? "ON" : "OFF");
|
||||
SerialBT.println(status);
|
||||
Serial.println(status);
|
||||
}
|
||||
|
||||
SerialBT.println("===================");
|
||||
Serial.println("===================");
|
||||
}
|
||||
|
||||
void printHelp() {
|
||||
const char* helpText = R"(
|
||||
=== Available Commands ===
|
||||
ON1-8 : Turn on relay 1-8 (e.g., ON1, ON5)
|
||||
OFF1-8 : Turn off relay 1-8 (e.g., OFF1, OFF8)
|
||||
TOGGLE1-8 : Toggle relay 1-8 (e.g., TOGGLE1)
|
||||
ALL_ON : Turn all relays on
|
||||
ALL_OFF : Turn all relays off
|
||||
STATUS : Get current status of all relays
|
||||
HELP : Show this help message
|
||||
==========================
|
||||
)";
|
||||
|
||||
SerialBT.print(helpText);
|
||||
Serial.print(helpText);
|
||||
}
|
||||
Reference in New Issue
Block a user