From 23a2f243c9ee8739273e23a2a6d97f358ee4bb65 Mon Sep 17 00:00:00 2001 From: Siwat Sirichai Date: Wed, 10 Jan 2024 17:10:51 +0700 Subject: [PATCH] IR Recieve --- .vscode/launch.json | 4 +- ESPMegaPRO-IRKit-SDK/.vscode/settings.json | 59 +++++++++++++++++++ .../lib/ESPMegaPRO/IRBlaster.cpp | 39 ++++++++++++ .../lib/ESPMegaPRO/IRBlaster.hpp | 16 +++++ .../lib/ESPMegaPRO/IRReceiver.cpp | 45 ++++++++++++++ .../lib/ESPMegaPRO/IRReceiver.hpp | 26 ++++++++ .../src/{main.cpp => main.cpp.disabled} | 2 +- ESPMegaPRO-OS-SDK/src/rmt_demo.cpp | 27 +++++++++ 8 files changed, 215 insertions(+), 3 deletions(-) create mode 100644 ESPMegaPRO-IRKit-SDK/.vscode/settings.json create mode 100644 ESPMegaPRO-OS-SDK/lib/ESPMegaPRO/IRBlaster.cpp create mode 100644 ESPMegaPRO-OS-SDK/lib/ESPMegaPRO/IRBlaster.hpp create mode 100644 ESPMegaPRO-OS-SDK/lib/ESPMegaPRO/IRReceiver.cpp create mode 100644 ESPMegaPRO-OS-SDK/lib/ESPMegaPRO/IRReceiver.hpp rename ESPMegaPRO-OS-SDK/src/{main.cpp => main.cpp.disabled} (99%) create mode 100644 ESPMegaPRO-OS-SDK/src/rmt_demo.cpp diff --git a/.vscode/launch.json b/.vscode/launch.json index 2f014ea..7c46088 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -8,8 +8,8 @@ "args": [], "stopAtEntry": false, "externalConsole": true, - "cwd": ".", - "program": "build/Debug/outDebug", + "cwd": "d:/Git/ESPMegaPRO-v3-SDK/ESPMegaPRO-OS-SDK/src", + "program": "d:/Git/ESPMegaPRO-v3-SDK/ESPMegaPRO-OS-SDK/src/build/Debug/outDebug", "MIMode": "gdb", "miDebuggerPath": "gdb", "setupCommands": [ diff --git a/ESPMegaPRO-IRKit-SDK/.vscode/settings.json b/ESPMegaPRO-IRKit-SDK/.vscode/settings.json new file mode 100644 index 0000000..3e5eb95 --- /dev/null +++ b/ESPMegaPRO-IRKit-SDK/.vscode/settings.json @@ -0,0 +1,59 @@ +{ + "C_Cpp_Runner.cCompilerPath": "gcc", + "C_Cpp_Runner.cppCompilerPath": "g++", + "C_Cpp_Runner.debuggerPath": "gdb", + "C_Cpp_Runner.cStandard": "", + "C_Cpp_Runner.cppStandard": "", + "C_Cpp_Runner.msvcBatchPath": "", + "C_Cpp_Runner.useMsvc": false, + "C_Cpp_Runner.warnings": [ + "-Wall", + "-Wextra", + "-Wpedantic", + "-Wshadow", + "-Wformat=2", + "-Wcast-align", + "-Wconversion", + "-Wsign-conversion", + "-Wnull-dereference" + ], + "C_Cpp_Runner.msvcWarnings": [ + "/W4", + "/permissive-", + "/w14242", + "/w14287", + "/w14296", + "/w14311", + "/w14826", + "/w44062", + "/w44242", + "/w14905", + "/w14906", + "/w14263", + "/w44265", + "/w14928" + ], + "C_Cpp_Runner.enableWarnings": true, + "C_Cpp_Runner.warningsAsError": false, + "C_Cpp_Runner.compilerArgs": [], + "C_Cpp_Runner.linkerArgs": [], + "C_Cpp_Runner.includePaths": [], + "C_Cpp_Runner.includeSearch": [ + "*", + "**/*" + ], + "C_Cpp_Runner.excludeSearch": [ + "**/build", + "**/build/**", + "**/.*", + "**/.*/**", + "**/.vscode", + "**/.vscode/**" + ], + "C_Cpp_Runner.useAddressSanitizer": false, + "C_Cpp_Runner.useUndefinedSanitizer": false, + "C_Cpp_Runner.useLeakSanitizer": false, + "C_Cpp_Runner.showCompilationTime": false, + "C_Cpp_Runner.useLinkTimeOptimization": false, + "C_Cpp_Runner.msvcSecureNoWarnings": false +} \ No newline at end of file diff --git a/ESPMegaPRO-OS-SDK/lib/ESPMegaPRO/IRBlaster.cpp b/ESPMegaPRO-OS-SDK/lib/ESPMegaPRO/IRBlaster.cpp new file mode 100644 index 0000000..35848c1 --- /dev/null +++ b/ESPMegaPRO-OS-SDK/lib/ESPMegaPRO/IRBlaster.cpp @@ -0,0 +1,39 @@ +#include + +void IRBlaster::send(uint16_t *data, size_t size) +{ + rmt_item32_t *items = new rmt_item32_t[size]; + for (size_t i = 0; i < size; i++) + { + items[i].duration0 = data[i] * 10; + items[i].level0 = 1; + items[i].duration1 = data[i] * 10; + items[i].level1 = 0; + } + ESP_ERROR_CHECK(rmt_write_items(channel, items, size, true)); + delete[] items; +} + +IRBlaster::IRBlaster(uint8_t pin, rmt_channel_t channel) +{ + this->channel = channel; + rmt_config_t config; + config.rmt_mode = RMT_MODE_TX; + config.channel = channel; + config.gpio_num = gpio_num_t(pin); + config.mem_block_num = 1; + config.tx_config.loop_en = false; + config.tx_config.carrier_en = false; + config.tx_config.idle_output_en = true; + config.tx_config.idle_level = RMT_IDLE_LEVEL_LOW; + config.tx_config.carrier_freq_hz = 38000; + config.tx_config.carrier_level = RMT_CARRIER_LEVEL_HIGH; + config.clk_div = 80; + ESP_ERROR_CHECK(rmt_config(&config)); + ESP_ERROR_CHECK(rmt_driver_install(channel, 0, 0)); +} + +IRBlaster::IRBlaster(uint8_t pin) +{ + IRBlaster(pin, RMT_CHANNEL_0); +} \ No newline at end of file diff --git a/ESPMegaPRO-OS-SDK/lib/ESPMegaPRO/IRBlaster.hpp b/ESPMegaPRO-OS-SDK/lib/ESPMegaPRO/IRBlaster.hpp new file mode 100644 index 0000000..8b58850 --- /dev/null +++ b/ESPMegaPRO-OS-SDK/lib/ESPMegaPRO/IRBlaster.hpp @@ -0,0 +1,16 @@ +#include +class IRBlaster +{ + public: + IRBlaster(uint8_t pin, rmt_channel_t channel); + IRBlaster(uint8_t pin); + /*** + * @brief Send an array of IR codes + * + * @param data Array of IR codes, each code is a 16 bit integer representing the number of 10us ticks + * @param size Size of the array + */ + void send(uint16_t *data, size_t size); + private: + rmt_channel_t channel; +}; \ No newline at end of file diff --git a/ESPMegaPRO-OS-SDK/lib/ESPMegaPRO/IRReceiver.cpp b/ESPMegaPRO-OS-SDK/lib/ESPMegaPRO/IRReceiver.cpp new file mode 100644 index 0000000..8d0d688 --- /dev/null +++ b/ESPMegaPRO-OS-SDK/lib/ESPMegaPRO/IRReceiver.cpp @@ -0,0 +1,45 @@ +#include +#include + +volatile unsigned int IRReceiver::irBufferPtr = 0; +volatile unsigned int IRReceiver::irBuffer[1000]; +uint8_t IRReceiver::pin; + +void IRReceiver::begin(uint8_t pin) { + IRReceiver::pin = pin; + IRReceiver::irBufferPtr = 0; +} + +void IRReceiver::start_long_receive() { + irBufferPtr = 0; + attachInterrupt(digitalPinToInterrupt(pin), IRReceiver::handleInterrupt, CHANGE); +} + +ir_data_t IRReceiver::end_long_receive() { + detachInterrupt(digitalPinToInterrupt(pin)); + // The data in the array is the time between each transition, so we need to convert it to the time of each transition + ir_data_t data; + const size_t size = irBufferPtr-1; + Serial.println("Allocating memory"); + data.data = (unsigned int*)calloc(size, sizeof(unsigned int)); + if (data.data == nullptr) { + Serial.println("Failed to allocate memory"); + data.size = 0; + return data; + } + Serial.println("Copying data"); + // The data in the array is the time between each transition, so we need to convert it to the time of each transition + for (size_t i = 1; i <= size; i++) { + Serial.printf("Copying data at index %d\n", i); + data.data[i-1] = irBuffer[i] - irBuffer[i-1]; + } + //memcpy(data.data, (const unsigned int*)irBuffer, (size)*sizeof(unsigned int)); + Serial.println("Done"); + data.size = irBufferPtr; + return data; +} + +void IRAM_ATTR IRReceiver::handleInterrupt() { + if (irBufferPtr > 1000) return; //full buffer = bad data + irBuffer[irBufferPtr++] = micros(); //just continually record the time-stamp of signal transitions +} \ No newline at end of file diff --git a/ESPMegaPRO-OS-SDK/lib/ESPMegaPRO/IRReceiver.hpp b/ESPMegaPRO-OS-SDK/lib/ESPMegaPRO/IRReceiver.hpp new file mode 100644 index 0000000..d280fd0 --- /dev/null +++ b/ESPMegaPRO-OS-SDK/lib/ESPMegaPRO/IRReceiver.hpp @@ -0,0 +1,26 @@ +#pragma once +#include +#include +#include + +struct ir_data_t { + unsigned int *data; + size_t size; +}; + +/** + * @brief Class for receiving IR signals + * + * @warning Only one IRReceiver can be used at a time +*/ +class IRReceiver { + public: + static void begin(uint8_t pin); + static void start_long_receive(); + static ir_data_t end_long_receive(); + private: + static uint8_t pin; + static void IRAM_ATTR handleInterrupt(); + static volatile unsigned int irBuffer[1000]; //stores timings - volatile because changed by ISR + static volatile unsigned int irBufferPtr; //Pointer thru irBuffer - volatile because changed by ISR +}; \ No newline at end of file diff --git a/ESPMegaPRO-OS-SDK/src/main.cpp b/ESPMegaPRO-OS-SDK/src/main.cpp.disabled similarity index 99% rename from ESPMegaPRO-OS-SDK/src/main.cpp rename to ESPMegaPRO-OS-SDK/src/main.cpp.disabled index 64bda7c..3c24d60 100644 --- a/ESPMegaPRO-OS-SDK/src/main.cpp +++ b/ESPMegaPRO-OS-SDK/src/main.cpp.disabled @@ -8,7 +8,7 @@ // #define WRITE_DEFAULT_NETCONF #define CLIMATE_CARD_ENABLE #define MQTT_CARD_REGISTER -//#define DISPLAY_ENABLE +#define DISPLAY_ENABLE #define WEB_SERVER_ENABLE // Demo PLC firmware using the ESPMegaPRO OOP library diff --git a/ESPMegaPRO-OS-SDK/src/rmt_demo.cpp b/ESPMegaPRO-OS-SDK/src/rmt_demo.cpp new file mode 100644 index 0000000..463f84c --- /dev/null +++ b/ESPMegaPRO-OS-SDK/src/rmt_demo.cpp @@ -0,0 +1,27 @@ +#include +#include +#include + +ESPMegaPRO espmega = ESPMegaPRO(); +IRBlaster irBlaster = IRBlaster(14); + +void setup() { + espmega.begin(); + IRReceiver::begin(15); + uint16_t data[] = {100, 200, 300, 400, 500}; + irBlaster.send(data, 5); +} + +void loop() { + Serial.println("Starting long receive"); + IRReceiver::start_long_receive(); + delay(5000); + Serial.println("Ending long receive"); + ir_data_t data = IRReceiver::end_long_receive(); + Serial.printf("Recived %d data points\n", data.size); + for (size_t i = 0; i < data.size; i++) { + Serial.print(data.data[i]); + Serial.print(i == data.size-1 ? "\n" : ", "); + } + free(data.data); +} \ No newline at end of file