Control Home Appliances

IA Kit Doc

Internal Memory

Appliance Control

Project

Control Home Appliances

#include <IRremote.hpp>
#include <EEPROM.h>

// Constants
#define IR_RECEIVE_PIN 2
#define IR_SEND_PIN 3
#define SLOT_COUNT 10
#define SLOT_NAME_LENGTH 20
#define RAW_DATA_MAX_LENGTH 200
#define SCALING_FACTOR 50

// Structure to store signal data
struct Signal {
    uint16_t rawData[RAW_DATA_MAX_LENGTH]; // Raw data
    uint16_t rawDataLength;                // Length of raw data
    char name[SLOT_NAME_LENGTH];           // Name of the slot
};

// Global Variables
Signal signals[SLOT_COUNT]; // Array to hold up to 10 signals
int currentSlot = -1;       // Currently selected slot (-1 means no slot selected)
bool receiving = false;     // Flag for receiving process

void setup() {
    // Initialize Serial Monitor
    Serial.begin(9600);
    while (!Serial)
        ; // Wait for Serial Monitor to connect

    // Initialize IR modules
    IrReceiver.begin(IR_RECEIVE_PIN, ENABLE_LED_FEEDBACK);
    IrSender.begin(IR_SEND_PIN);

    // Load signals from EEPROM
    loadSignalsFromEEPROM();

    // Instructions
    Serial.println(F("IR Remote Controller"));
    Serial.println(F("Commands:"));
    Serial.println(F("1-10: Start receiving process for the selected slot"));
    Serial.println(F("C: Check all stored signals"));
    Serial.println(F("S<number>: Send signal from the selected slot"));
    Serial.println(F("<name>: Send signal by slot name"));
    Serial.println(F("D<number>: Delete signal in the selected slot"));
    Serial.println(F("D all: Delete all stored signals"));
}

void loop() {
    if (Serial.available() > 0) {
        String command = Serial.readStringUntil('\n');
        command.trim();
        handleCommand(command);
    }

    // If in receiving mode, listen for IR signals
    if (receiving && IrReceiver.decode()) {
        storeSignal();
    }
}

/**
 * Handle user commands from the Serial Monitor
 */
void handleCommand(String command) {
    if (command.equalsIgnoreCase("C")) {
        checkSignals();
    } else if (command.startsWith("S")) {
        int slot = command.substring(1).toInt() - 1;
        if (slot >= 0 && slot < SLOT_COUNT) {
            sendSignal(slot);
        } else {
            Serial.println(F("Invalid slot number."));
        }
    } else if (command.equalsIgnoreCase("D all")) {
        deleteAllSignals();
    } else if (command.startsWith("D")) {
        int slot = command.substring(1).toInt() - 1;
        if (slot >= 0 && slot < SLOT_COUNT) {
            deleteSignal(slot);
        } else {
            Serial.println(F("Invalid slot number."));
        }
    } else if (command.toInt() >= 1 && command.toInt() <= SLOT_COUNT) {
        currentSlot = command.toInt() - 1;
        startReceiving();
    } else {
        sendSignalByName(command);
    }
}

/**
 * Start receiving process for the current slot
 */
void startReceiving() {
    receiving = true;
    Serial.print(F("Listening for signals on slot "));
    Serial.println(currentSlot + 1);
    Serial.println(F("Press a button on your remote or wait 10 seconds."));

    unsigned long startTime = millis();
    bool signalReceived = false;

    // Listen for a signal or timeout after 10 seconds
    while (millis() - startTime < 10000) {
        if (IrReceiver.decode()) {
            signalReceived = true;
            break;
        }
    }

    if (signalReceived) {
        storeSignal();
    } else {
        Serial.println(F("No signal received. Process ended."));
    }

    receiving = false;
    currentSlot = -1; // Reset current slot
    IrReceiver.resume(); // Clear receiver for next process
}

/**
 * Store received signal in the selected slot
 */
void storeSignal() {
    if (currentSlot < 0 || currentSlot >= SLOT_COUNT) return;

    // Store raw data
    Signal &signal = signals[currentSlot];
    signal.rawDataLength = min(IrReceiver.decodedIRData.rawDataPtr->rawlen - 1, RAW_DATA_MAX_LENGTH); // Prevent overflow
    for (int i = 1; i <= signal.rawDataLength; i++) {
        signal.rawData[i - 1] = IrReceiver.decodedIRData.rawDataPtr->rawbuf[i];
    }

    // Display received raw data
    Serial.print(F("Raw Data (Length: "));
    Serial.print(signal.rawDataLength);
    Serial.println(F("):"));
    for (int i = 0; i < signal.rawDataLength; i++) {
        Serial.print(signal.rawData[i]);
        if (i < signal.rawDataLength - 1) {
            Serial.print(", ");
        }
    }
    Serial.println();

    // Prompt for name
    Serial.println(F("Signal received. Enter a name (max 20 characters):"));
    while (!Serial.available())
        ;
    String name = Serial.readStringUntil('\n');
    name.trim();
    strncpy(signal.name, name.c_str(), SLOT_NAME_LENGTH - 1);
    signal.name[SLOT_NAME_LENGTH - 1] = '\0';

    // Save to EEPROM
    saveSignalsToEEPROM();
    Serial.println(F("Signal stored successfully."));

    // Clear receiver for next process
    IrReceiver.resume();
}

/**
 * Send signal from the specified slot
 */
void sendSignal(int slot) {
    if (signals[slot].rawDataLength == 0) {
        Serial.println(F("Slot is empty."));
        return;
    }

    // Scale and send raw data
    uint16_t scaledData[RAW_DATA_MAX_LENGTH];
    for (int i = 0; i < signals[slot].rawDataLength; i++) {
        scaledData[i] = signals[slot].rawData[i] * SCALING_FACTOR;
    }

    Serial.println(F("Sending raw IR signal..."));
    Serial.print(F("Raw Data: "));
    for (int i = 0; i < signals[slot].rawDataLength; i++) {
        Serial.print(scaledData[i]);
        if (i < signals[slot].rawDataLength - 1) {
            Serial.print(", ");
        }
    }
    Serial.println();

    IrSender.sendRaw(scaledData, signals[slot].rawDataLength, 38);
    Serial.println(F("Signal sent."));
}

/**
 * Send signal by slot name
 */
void sendSignalByName(String name) {
    for (int i = 0; i < SLOT_COUNT; i++) {
        if (String(signals[i].name).equalsIgnoreCase(name)) {
            sendSignal(i);
            return;
        }
    }
    Serial.println(F("No matching signal found."));
}

/**
 * Check all stored signals
 */
void checkSignals() {
    Serial.println(F("Stored Signals:"));
    for (int i = 0; i < SLOT_COUNT; i++) {
        Serial.print(F("Slot "));
        Serial.print(i + 1);
        if (signals[i].rawDataLength > 0) {
            Serial.print(F(": Name: "));
            Serial.println(signals[i].name);
            Serial.print(F("Raw Data (Length: "));
            Serial.print(signals[i].rawDataLength);
            Serial.println(F("):"));
            for (int j = 0; j < signals[i].rawDataLength; j++) {
                Serial.print(signals[i].rawData[j]);
                if (j < signals[i].rawDataLength - 1) {
                    Serial.print(", ");
                }
            }
            Serial.println();
        } else {
            Serial.println(F(": Empty"));
        }
    }
}

/**
 * Delete signal in the specified slot
 */
void deleteSignal(int slot) {
    memset(&signals[slot], 0, sizeof(Signal));
    saveSignalsToEEPROM();
    Serial.print(F("Deleted signal in slot "));
    Serial.println(slot + 1);
}

/**
 * Delete all stored signals
 */
void deleteAllSignals() {
    memset(signals, 0, sizeof(signals));
    saveSignalsToEEPROM();
    Serial.println(F("All signals deleted."));
}


/**
 * Save signals to EEPROM
 */
void saveSignalsToEEPROM() {
    EEPROM.put(0, signals);
    Serial.println(F("Signals saved to EEPROM."));
    Serial.println(F("Saved Signals Overview:"));
    for (int i = 0; i < SLOT_COUNT; i++) {
        Serial.print(F("Slot "));
        Serial.print(i + 1);
        if (signals[i].rawDataLength > 0) {
            Serial.print(F(": Name: "));
            Serial.print(signals[i].name);
            Serial.print(F(", Raw Data Length: "));
            Serial.println(signals[i].rawDataLength);
        } else {
            Serial.println(F(": Empty"));
        }
    }
}

/**
 * Load signals from EEPROM
 */
void loadSignalsFromEEPROM() {
    EEPROM.get(0, signals);

    // Sanity check for each slot
    for (int i = 0; i < SLOT_COUNT; i++) {
        Signal &signal = signals[i];

        // Check if the rawDataLength is valid
        if (signal.rawDataLength > RAW_DATA_MAX_LENGTH) {
            Serial.print(F("Invalid data in slot "));
            Serial.println(i + 1);
            memset(&signals[i], 0, sizeof(Signal)); // Clear the corrupted slot
        }
    }

    Serial.println(F("Signals loaded from EEPROM:"));
    for (int i = 0; i < SLOT_COUNT; i++) {
        Serial.print(F("Slot "));
        Serial.print(i + 1);
        if (signals[i].rawDataLength > 0) {
            Serial.print(F(": Name: "));
            Serial.print(signals[i].name);
            Serial.print(F(", Raw Data Length: "));
            Serial.println(signals[i].rawDataLength);
        } else {
            Serial.println(F(": Empty"));
        }
    }
}

© 2025 INCIPE Academy Limited

Create a free website with Framer, the website builder loved by startups, designers and agencies.