From dc96be25b84b8ba88eb237c93b00807f96db631b Mon Sep 17 00:00:00 2001 From: Siwat Sirichai Date: Thu, 4 Apr 2024 18:03:34 +0700 Subject: [PATCH] update IR Capture --- ESPMegaPRO-IRKit-SDK/.vscode/settings.json | 6 +- ESPMegaPRO-IRKit-SDK/src/main.cpp | 173 +++++++++++++++++++-- 2 files changed, 163 insertions(+), 16 deletions(-) diff --git a/ESPMegaPRO-IRKit-SDK/.vscode/settings.json b/ESPMegaPRO-IRKit-SDK/.vscode/settings.json index 3e5eb95..fe4dc1d 100644 --- a/ESPMegaPRO-IRKit-SDK/.vscode/settings.json +++ b/ESPMegaPRO-IRKit-SDK/.vscode/settings.json @@ -55,5 +55,9 @@ "C_Cpp_Runner.useLeakSanitizer": false, "C_Cpp_Runner.showCompilationTime": false, "C_Cpp_Runner.useLinkTimeOptimization": false, - "C_Cpp_Runner.msvcSecureNoWarnings": false + "C_Cpp_Runner.msvcSecureNoWarnings": false, + "files.associations": { + "istream": "cpp", + "map": "cpp" + } } \ No newline at end of file diff --git a/ESPMegaPRO-IRKit-SDK/src/main.cpp b/ESPMegaPRO-IRKit-SDK/src/main.cpp index 632221b..3b9cf6b 100644 --- a/ESPMegaPRO-IRKit-SDK/src/main.cpp +++ b/ESPMegaPRO-IRKit-SDK/src/main.cpp @@ -10,37 +10,93 @@ * The first dimension is the temperature, the second dimension is the timing */ -#define MIN_TEMP 16 -#define MAX_TEMP 30 +#define min_temp 16 +#define max_temp 32 #define MAX_TIMINGS 1000 // 1000 timings should be enough for any remote #define CAPTURE_TIMEOUT 5 // seconds -uint16_t timings[MAX_TEMP - MIN_TEMP + 1][MAX_TIMINGS] = {0}; -uint16_t timings_count[MAX_TEMP - MIN_TEMP + 1] = {0}; +uint32_t timings[max_temp - min_temp + 1][MAX_TIMINGS] = {0}; +uint16_t timings_count[max_temp - min_temp + 1] = {0}; ESPMegaPRO espmega = ESPMegaPRO(); void beginRoutine() { Serial.println("Beginning IR capture routine"); - for (int i = MIN_TEMP; i <= MAX_TEMP; i++) + for (int i = min_temp; i <= max_temp; i++) { Serial.printf("Please press the button on your remote for %d degrees\n", i); IRReceiver::start_long_receive(); for (int i = 0; i < CAPTURE_TIMEOUT; i++) { Serial.printf("Waiting for IR signal... (%d seconds left)\n", CAPTURE_TIMEOUT - i); + // During this period, if the user press any key, the routine will be restarted + // Unless it is a space bar, which will be used to confirm the timings + if (Serial.available()) + { + char c = Serial.read(); + if (c != ' ') + { + Serial.println("User interrupted, restarting routine..."); + return; + } + } + vTaskDelay(1000 / portTICK_PERIOD_MS); } ir_data_t data = IRReceiver::end_long_receive(); - timings_count[i - MIN_TEMP] = data.size; + // Retry if no data was received + if (data.size == 0) + { + Serial.println("No data received, retrying..."); + i--; + continue; + } + // Remove last timing + data.size--; + Serial.printf("Received timing of size %d\n", data.size); + // Print out the timing array + for (int i = 0; i < data.size; i++) + { + Serial.printf("%u%s", data.data[i], i == data.size - 1 ? "\n" : ", "); + } + // If any timings exceed 20000, print a warning + for (int i = 0; i < data.size; i++) + { + if (data.data[i] > 50000U) + { + Serial.println("WARNING: Timing exceeds 50000, Possible data corruption!"); + break; + } + } + // Ask the user if the timings are correct + Serial.println("Are the timings correct? (y/n)"); + // Flush the serial buffer + while (Serial.available()) + { + Serial.read(); + } + // Wait for user input + while (!Serial.available()) + { + vTaskDelay(100 / portTICK_PERIOD_MS); + } + char c = Serial.read(); + if (c != 'y') + { + Serial.println("Retrying..."); + i--; + continue; + } + // Store the timings count + timings_count[i - min_temp] = data.size; // Copy the timings into the timings array - memcpy(timings[i - MIN_TEMP], data.data, sizeof(uint16_t) * data.size); + memcpy(timings[i - min_temp], data.data, sizeof(uint32_t) * data.size); free(data.data); } Serial.println("Generating C++ code for the timings, please wait..."); // Find the maximum number of timings int max_timings = 0; - for (int i = 0; i < MAX_TEMP - MIN_TEMP + 1; i++) + for (int i = 0; i < max_temp - min_temp + 1; i++) { if (timings_count[i] > max_timings) { @@ -49,27 +105,114 @@ void beginRoutine() } // Print the timings Serial.println("Done!, please copy the following into your main program"); - Serial.printf("uint16_t timings[%d][%d] = {\n", MAX_TEMP - MIN_TEMP + 1, max_timings); - for (int i = 0; i < MAX_TEMP - MIN_TEMP + 1; i++) + Serial.printf("uint16_t timings[%d][%d] = {\n", max_temp - min_temp + 1, max_timings); + for (int i = 0; i < max_temp - min_temp + 1; i++) { Serial.printf(" {"); for (int j = 0; j < timings_count[i]; j++) { - Serial.printf("%d%s", timings[i][j], j == timings_count[i] - 1 ? "" : ", "); + Serial.printf("%u%s", timings[i][j], j == timings_count[i] - 1 ? "" : ", "); } - Serial.println(i == MAX_TEMP - MIN_TEMP ? "}" : "},"); + Serial.println(i == max_temp - min_temp ? "}" : "},"); } Serial.println("};"); Serial.println("Stopping IR capture routine"); + Serial.printf("IR Capture routine finished\n"); } + +void capture_single() +{ + Serial.println("Please press the button on your remote"); + IRReceiver::start_long_receive(); + for (int i = 0; i < CAPTURE_TIMEOUT; i++) + { + Serial.printf("Waiting for IR signal... (%d seconds left)\n", CAPTURE_TIMEOUT - i); + vTaskDelay(1000 / portTICK_PERIOD_MS); + } + ir_data_t data = IRReceiver::end_long_receive(); + // Remove last timing + data.size--; + Serial.printf("Received timing of size %d\n", data.size); + // If any timings exceed 20000, print a warning + for (int i = 0; i < data.size; i++) + { + if (data.data[i] > 50000U) + { + Serial.println("WARNING: Timing exceeds 50000, Possible data corruption!"); + break; + } + } + if (data.size == 0) + { + Serial.println("No data received, retrying..."); + capture_single(); + return; + } + // Print the timings + Serial.println("Done!, please copy the following into your main program"); + Serial.printf("uint32_t timings[%d] = {", data.size); + for (int i = 0; i < data.size; i++) + { + Serial.printf("%u%s", data.data[i], i == data.size - 1 ? "" : ", "); + } + Serial.println("};"); + free(data.data); + Serial.println("Do you want to capture another signal? (y/n)"); + // Flush the serial buffer + while (Serial.available()) + { + Serial.read(); + } + // Wait for user input + while (!Serial.available()) + { + vTaskDelay(100 / portTICK_PERIOD_MS); + } + char c = Serial.read(); + if (c == 'y') + { + capture_single(); + } +} + +void menu_init() +{ + // Print the menu + // The menu will have 2 options, one to start the routine, and one capture a single IR signal + Serial.println("ESPMegaPRO IR Development Kit - IR Capture"); + Serial.println("1. Begin IR Capture Routine"); + Serial.println("2. Capture Single IR Signal"); + Serial.println("Please select an option:"); + // Wait for user input + while (!Serial.available()) + { + vTaskDelay(100 / portTICK_PERIOD_MS); + } + char c = Serial.read(); + // Start the routine + if (c == '1') + { + beginRoutine(); + } + // Capture a single IR signal + else if (c == '2') + { + capture_single(); + } +} + void setup() { - IRReceiver::begin(17); + IRReceiver::begin(36); espmega.begin(); } void loop() { - beginRoutine(); - delay(10000); + menu_init(); + Serial.println("Press any key to return to the main menu"); + while (!Serial.available()) + { + vTaskDelay(100 / portTICK_PERIOD_MS); + } } \ No newline at end of file