181 lines
5.3 KiB
Arduino
181 lines
5.3 KiB
Arduino
#include <WiFi.h>
|
|
#include <esp_now.h>
|
|
#include <Wire.h>
|
|
#include <Adafruit_GFX.h>
|
|
#include <Adafruit_SSD1306.h>
|
|
|
|
// OLED Configuration
|
|
#define SCREEN_WIDTH 128
|
|
#define SCREEN_HEIGHT 64
|
|
#define OLED_RESET -1
|
|
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
|
|
|
|
// Transmitter MAC Address (replace with actual MAC)
|
|
uint8_t transmitterMacAddress[] = {0x5C, 0x01, 0x3B, 0x6B, 0x68, 0x48};
|
|
|
|
// Pin Definitions
|
|
#define MOSFET_PIN 14 // Controls the MOSFET for igniter
|
|
#define CONTINUITY_PIN 15 // Checks igniter continuity
|
|
#define POWER_LED 2 // Indicates power is on
|
|
#define CONNECTION_LED 13 // Indicates connection with transmitter
|
|
#define LAUNCH_LED 4 // Indicates launch sequence active
|
|
#define BUZZER_PIN 5 // Buzzer for pre-launch warning
|
|
|
|
// ESP-NOW Data Structures
|
|
typedef struct {
|
|
bool arm;
|
|
bool launch;
|
|
} CommandMessage;
|
|
|
|
typedef struct {
|
|
bool continuity;
|
|
} StatusMessage;
|
|
|
|
CommandMessage command = {false, false};
|
|
StatusMessage status;
|
|
esp_now_peer_info_t peerInfo;
|
|
unsigned long lastReceivedTime = 0;
|
|
unsigned long lastSentTime = 0;
|
|
unsigned long armTime = 0;
|
|
bool isArmed = false;
|
|
bool isLaunching = false;
|
|
|
|
// Callback for data received from transmitter
|
|
void onDataRecv(const esp_now_recv_info *recvInfo, const uint8_t *incomingData, int len) {
|
|
memcpy(&command, incomingData, sizeof(command));
|
|
lastReceivedTime = millis();
|
|
Serial.println("Command Received: Arm = " + String(command.arm) + ", Launch = " + String(command.launch));
|
|
}
|
|
|
|
void setup() {
|
|
Serial.begin(115200);
|
|
|
|
// Initialize GPIO pins
|
|
pinMode(MOSFET_PIN, OUTPUT);
|
|
pinMode(CONTINUITY_PIN, INPUT);
|
|
pinMode(POWER_LED, OUTPUT);
|
|
pinMode(CONNECTION_LED, OUTPUT);
|
|
pinMode(LAUNCH_LED, OUTPUT);
|
|
pinMode(BUZZER_PIN, OUTPUT);
|
|
digitalWrite(MOSFET_PIN, LOW);
|
|
digitalWrite(POWER_LED, HIGH); // Turn on power LED immediately as system is powered
|
|
digitalWrite(CONNECTION_LED, LOW);
|
|
digitalWrite(LAUNCH_LED, LOW);
|
|
digitalWrite(BUZZER_PIN, LOW); // Ensure buzzer starts off
|
|
|
|
// Initialize OLED
|
|
if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
|
|
Serial.println(F("SSD1306 allocation failed"));
|
|
while (true);
|
|
}
|
|
display.clearDisplay();
|
|
display.setTextSize(1);
|
|
display.setTextColor(SSD1306_WHITE);
|
|
display.setCursor(0, 0);
|
|
display.println(F("System Powered"));
|
|
display.display();
|
|
|
|
// Initialize ESP-NOW
|
|
WiFi.mode(WIFI_STA);
|
|
if (esp_now_init() != ESP_OK) {
|
|
Serial.println("ESP-NOW Init Failed");
|
|
display.clearDisplay();
|
|
display.setCursor(0, 0);
|
|
display.println(F("ESP-NOW Init Failed"));
|
|
display.display();
|
|
while (true);
|
|
}
|
|
|
|
// Register receive callback
|
|
esp_now_register_recv_cb(onDataRecv);
|
|
|
|
// Register transmitter as peer
|
|
memcpy(peerInfo.peer_addr, transmitterMacAddress, 6);
|
|
peerInfo.channel = 0;
|
|
peerInfo.encrypt = false;
|
|
if (esp_now_add_peer(&peerInfo) != ESP_OK) {
|
|
Serial.println("Peer Add Failed");
|
|
display.clearDisplay();
|
|
display.setCursor(0, 0);
|
|
display.println(F("Peer Add Failed"));
|
|
display.display();
|
|
while (true);
|
|
}
|
|
}
|
|
|
|
void loop() {
|
|
// Check continuity
|
|
bool continuity = digitalRead(CONTINUITY_PIN) == HIGH;
|
|
status.continuity = continuity;
|
|
|
|
// Handle arming
|
|
if (command.arm && continuity) {
|
|
isArmed = true;
|
|
armTime = millis();
|
|
} else {
|
|
isArmed = false;
|
|
digitalWrite(MOSFET_PIN, LOW);
|
|
}
|
|
|
|
// Handle launch sequence
|
|
if (isArmed && command.launch && !isLaunching) {
|
|
isLaunching = true;
|
|
digitalWrite(LAUNCH_LED, HIGH); // Launch LED ON
|
|
digitalWrite(BUZZER_PIN, HIGH); // Buzzer ON
|
|
delay(2000); // 2-second buzzer
|
|
digitalWrite(BUZZER_PIN, LOW); // Buzzer OFF
|
|
if (isArmed) { // Check if still armed
|
|
digitalWrite(MOSFET_PIN, HIGH); // Activate igniter
|
|
delay(1000); // 1-second pulse
|
|
digitalWrite(MOSFET_PIN, LOW); // Deactivate igniter
|
|
}
|
|
digitalWrite(LAUNCH_LED, LOW); // Launch LED OFF
|
|
isArmed = false;
|
|
command.launch = false;
|
|
isLaunching = false;
|
|
}
|
|
|
|
// Arming timeout (30 seconds)
|
|
if (isArmed && (millis() - armTime > 30000)) {
|
|
isArmed = false;
|
|
}
|
|
|
|
// Send status to transmitter every 100ms
|
|
if (millis() - lastSentTime >= 100) {
|
|
esp_err_t result = esp_now_send(transmitterMacAddress, (uint8_t *)&status, sizeof(status));
|
|
if (result == ESP_OK) {
|
|
Serial.println("Status Sent: Continuity = " + String(status.continuity));
|
|
} else {
|
|
Serial.println("Status Send Failed");
|
|
}
|
|
lastSentTime = millis();
|
|
}
|
|
|
|
// Update connection LED
|
|
if (millis() - lastReceivedTime < 1000) {
|
|
digitalWrite(CONNECTION_LED, HIGH); // Connected
|
|
} else {
|
|
digitalWrite(CONNECTION_LED, LOW); // Not connected
|
|
}
|
|
|
|
// Update OLED display
|
|
static unsigned long lastUpdateTime = 0;
|
|
if (millis() - lastUpdateTime >= 100) {
|
|
display.clearDisplay();
|
|
display.setCursor(0, 0);
|
|
display.println(F("System Powered"));
|
|
display.print(F("Connection: "));
|
|
display.println((millis() - lastReceivedTime < 1000) ? F("Connected") : F("No Connection"));
|
|
display.print(F("Continuity: "));
|
|
display.println(continuity ? F("OK") : F("Fail"));
|
|
display.print(F("Status: "));
|
|
display.println(isArmed ? F("Armed") : F("Disarmed"));
|
|
if (isLaunching) {
|
|
display.println(F("Igniting..."));
|
|
}
|
|
display.display();
|
|
lastUpdateTime = millis();
|
|
}
|
|
|
|
delay(50); // Loop runs every 50ms
|
|
} |