├── temp ├── NTP_RTC_Sync │ ├── .gitignore │ ├── WifiPass.h.config │ ├── README.md │ └── NTP_RTC_Sync.ino ├── SingletonTemplate.cpp.bak ├── RTC_read.cpp.bak └── IRBackup.cpp.bak ├── RTCService.h ├── IRService.h ├── PremiumAlarmClock.ino ├── RTCService.cpp └── IRService.cpp /temp/NTP_RTC_Sync/.gitignore: -------------------------------------------------------------------------------- 1 | *DS_Store 2 | WifiPass.h 3 | -------------------------------------------------------------------------------- /temp/NTP_RTC_Sync/WifiPass.h.config: -------------------------------------------------------------------------------- 1 | const char* ssid = "WIFI_SSID_HERE"; 2 | const char* pass = "WIFI_PASSWORD_HERE"; 3 | -------------------------------------------------------------------------------- /RTCService.h: -------------------------------------------------------------------------------- 1 | #ifndef __RTCService_H__ 2 | #define __RTCService_H__ 3 | 4 | #include "RTClib.h" 5 | 6 | 7 | void RTC_init(); 8 | DateTime RTC_read_time(); 9 | float RTC_read_temp(); 10 | 11 | #endif 12 | -------------------------------------------------------------------------------- /IRService.h: -------------------------------------------------------------------------------- 1 | #ifndef __IRService_H__ 2 | #define __IRService_H__ 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | void IR_init(); 13 | void IR_read(); 14 | 15 | #endif 16 | -------------------------------------------------------------------------------- /PremiumAlarmClock.ino: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "IRService.h" 4 | #include "RTCService.h" 5 | 6 | const uint32_t kBaudRate = 115200; // should not be lower 7 | 8 | void setup() { 9 | #if defined(ESP8266) 10 | Serial.begin(kBaudRate, SERIAL_8N1, SERIAL_TX_ONLY); 11 | #else // ESP8266 12 | Serial.begin(kBaudRate, SERIAL_8N1); 13 | #endif // ESP8266 14 | while (!Serial) delay(50); // wait for serial port to connect 15 | 16 | IR_init(); 17 | RTC_init(); 18 | } 19 | 20 | void loop() { 21 | // put your main code here, to run repeatedly: 22 | RTC_read_time(); 23 | RTC_read_temp(); 24 | IR_read(); 25 | delay(2000); 26 | } 27 | -------------------------------------------------------------------------------- /temp/SingletonTemplate.cpp.bak: -------------------------------------------------------------------------------- 1 | class IRService 2 | { 3 | public: 4 | static IRService &getInstance() 5 | { 6 | static IRService instance; // Guaranteed to be destroyed. 7 | return instance; 8 | } 9 | 10 | private: 11 | IRService() {} // Constructor? (the {} brackets) are needed here. 12 | 13 | public: 14 | IRService(IRService const &) = delete; 15 | void operator=(IRService const &) = delete; 16 | 17 | // Note: Scott Meyers mentions in his Effective Modern 18 | // C++ book, that deleted functions should generally 19 | // be public as it results in better error messages 20 | // due to the compilers behavior to check accessibility 21 | // before deleted status 22 | }; -------------------------------------------------------------------------------- /temp/NTP_RTC_Sync/README.md: -------------------------------------------------------------------------------- 1 | # Sync RTC clock with NTP 2 | 3 | ## Libs 4 | 5 | You must have the libs: 6 | 7 | * [Adafruit RTCLib](https://github.com/adafruit/RTClib) 8 | * [Arduino NTP Client](https://github.com/arduino-libraries/NTPClient) 9 | 10 | You can install from Arduino/ Manage Libraries menu 11 | 12 | ## Wifi 13 | 14 | Copy `WifiPass.h.config` to `WifiPass.h` and change the `ssid` and `password` to your wifi network information. 15 | 16 | ## Parameters 17 | Change the `NTP_SERVER` to a suitable server. 18 | 19 | ```C 20 | #define NTP_SERVER "0.us.pool.ntp.org" 21 | ``` 22 | 23 | Change the GMT time zone `GMT_TIME_ZONE` you can add a signed number 24 | 25 | ```C 26 | #define GMT_TIME_ZONE -7 27 | ``` 28 | 29 | You can force the time sync after the first time changing the `FORCE_RTC_UPDATE` to a random number between 0-255 30 | ```C 31 | #define FORCE_RTC_UPDATE 2 32 | ``` 33 | -------------------------------------------------------------------------------- /RTCService.cpp: -------------------------------------------------------------------------------- 1 | #include "RTCService.h" 2 | 3 | RTC_DS3231 rtc; 4 | 5 | char daysOfTheWeek[7][12] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"}; 6 | 7 | void RTC_init() 8 | { 9 | if (! rtc.begin()) { 10 | Serial.println("Couldn't find RTC"); 11 | Serial.flush(); 12 | abort(); 13 | } 14 | 15 | if (rtc.lostPower()) { 16 | Serial.println("RTC lost power, please set the time!"); 17 | // rtc.adjust(DateTime(F(__DATE__), F(__TIME__))); 18 | } 19 | } 20 | 21 | DateTime RTC_read_time() 22 | { 23 | DateTime now = rtc.now(); 24 | Serial.print(now.year(), DEC); 25 | Serial.print('/'); 26 | Serial.print(now.month(), DEC); 27 | Serial.print('/'); 28 | Serial.print(now.day(), DEC); 29 | Serial.print(" ("); 30 | Serial.print(daysOfTheWeek[now.dayOfTheWeek()]); 31 | Serial.print(") "); 32 | Serial.print(now.hour(), DEC); 33 | Serial.print(':'); 34 | Serial.print(now.minute(), DEC); 35 | Serial.print(':'); 36 | Serial.print(now.second(), DEC); 37 | Serial.println(); 38 | return now; 39 | } 40 | 41 | float RTC_read_temp() 42 | { 43 | float temp = rtc.getTemperature(); 44 | Serial.print("Temperature: "); 45 | Serial.print(temp); 46 | Serial.println(" C"); 47 | return temp; 48 | } 49 | -------------------------------------------------------------------------------- /temp/RTC_read.cpp.bak: -------------------------------------------------------------------------------- 1 | // Date and time functions using a DS3231 RTC connected via I2C and Wire lib 2 | #include "RTClib.h" 3 | 4 | RTC_DS3231 rtc; 5 | 6 | char daysOfTheWeek[7][12] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"}; 7 | 8 | void setup () { 9 | if (! rtc.begin()) { 10 | Serial.println("Couldn't find RTC"); 11 | Serial.flush(); 12 | abort(); 13 | } 14 | 15 | if (rtc.lostPower()) { 16 | Serial.println("RTC lost power, let's set the time!"); 17 | // When time needs to be set on a new device, or after a power loss, the 18 | // following line sets the RTC to the date & time this sketch was compiled 19 | rtc.adjust(DateTime(F(__DATE__), F(__TIME__))); 20 | // This line sets the RTC with an explicit date & time, for example to set 21 | // January 21, 2014 at 3am you would call: 22 | // rtc.adjust(DateTime(2014, 1, 21, 3, 0, 0)); 23 | } 24 | 25 | // When time needs to be re-set on a previously configured device, the 26 | // following line sets the RTC to the date & time this sketch was compiled 27 | // rtc.adjust(DateTime(F(__DATE__), F(__TIME__))); 28 | // This line sets the RTC with an explicit date & time, for example to set 29 | // January 21, 2014 at 3am you would call: 30 | // rtc.adjust(DateTime(2014, 1, 21, 3, 0, 0)); 31 | } 32 | 33 | void loop () { 34 | DateTime now = rtc.now(); 35 | 36 | Serial.print(now.year(), DEC); 37 | Serial.print('/'); 38 | Serial.print(now.month(), DEC); 39 | Serial.print('/'); 40 | Serial.print(now.day(), DEC); 41 | Serial.print(" ("); 42 | Serial.print(daysOfTheWeek[now.dayOfTheWeek()]); 43 | Serial.print(") "); 44 | Serial.print(now.hour(), DEC); 45 | Serial.print(':'); 46 | Serial.print(now.minute(), DEC); 47 | Serial.print(':'); 48 | Serial.print(now.second(), DEC); 49 | Serial.println(); 50 | 51 | Serial.print(" since midnight 1/1/1970 = "); 52 | Serial.print(now.unixtime()); 53 | Serial.print("s = "); 54 | Serial.print(now.unixtime() / 86400L); 55 | Serial.println("d"); 56 | 57 | // calculate a date which is 7 days, 12 hours, 30 minutes, 6 seconds into the future 58 | DateTime future (now + TimeSpan(7,12,30,6)); 59 | 60 | Serial.print(" now + 7d + 12h + 30m + 6s: "); 61 | Serial.print(future.year(), DEC); 62 | Serial.print('/'); 63 | Serial.print(future.month(), DEC); 64 | Serial.print('/'); 65 | Serial.print(future.day(), DEC); 66 | Serial.print(' '); 67 | Serial.print(future.hour(), DEC); 68 | Serial.print(':'); 69 | Serial.print(future.minute(), DEC); 70 | Serial.print(':'); 71 | Serial.print(future.second(), DEC); 72 | Serial.println(); 73 | 74 | 75 | 76 | Serial.println(); 77 | delay(3000); 78 | } 79 | -------------------------------------------------------------------------------- /temp/NTP_RTC_Sync/NTP_RTC_Sync.ino: -------------------------------------------------------------------------------- 1 | #include "WifiPass.h" 2 | #include 3 | #include //NTPClient by Arduino 4 | #include 5 | #include 6 | #include 7 | #include //RTClib by Adafruit 8 | 9 | //closest NTP Server 10 | #define NTP_SERVER "0.us.pool.ntp.org" 11 | 12 | //GMT Time Zone with sign 13 | #define GMT_TIME_ZONE 2 14 | 15 | //Force RTC update and store on EEPROM 16 | //change this to a random number between 0-255 to force time update 17 | #define FORCE_RTC_UPDATE 2 18 | 19 | char daysOfTheWeek[7][12] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"}; 20 | 21 | RTC_DS3231 rtc; 22 | WiFiUDP ntpUDP; 23 | 24 | // You can specify the time server pool and the offset, (in seconds) 25 | // additionaly you can specify the update interval (in milliseconds). 26 | NTPClient timeClient(ntpUDP, NTP_SERVER, GMT_TIME_ZONE * 3600 , 60000); 27 | 28 | int timeUpdated = 0; 29 | 30 | void setup() { 31 | Serial.begin(9600); 32 | EEPROM.begin(4); 33 | 34 | if (!rtc.begin()) { 35 | Serial.println("Couldn't find RTC"); 36 | while (1); 37 | } 38 | 39 | Serial.println("Waiting to Start...."); 40 | delay(5000); 41 | 42 | //Read the EEPROM to check if time has been synced 43 | 44 | byte addvalue = EEPROM.read(timeUpdated); 45 | Serial.print("EEPROM: "); 46 | Serial.print(addvalue); 47 | Serial.print(" == "); 48 | Serial.print(FORCE_RTC_UPDATE); 49 | Serial.println(" ?"); 50 | if (addvalue != FORCE_RTC_UPDATE) { 51 | //if(true == false){ 52 | //time hasn' it been setup 53 | Serial.println("Forcing Time Update"); 54 | syncTime(); 55 | Serial.println("Updating EEPROM.."); 56 | EEPROM.write(timeUpdated, FORCE_RTC_UPDATE); 57 | EEPROM.commit(); 58 | 59 | } else { 60 | Serial.println("Time has been updated before...EEPROM CHECKED"); 61 | Serial.print("EEPROM: "); 62 | Serial.print(addvalue); 63 | Serial.print(" = "); 64 | Serial.print(FORCE_RTC_UPDATE); 65 | Serial.println("!"); 66 | } 67 | 68 | 69 | 70 | } 71 | 72 | void syncTime(void) { 73 | 74 | //Connect to Wifi 75 | //SSID and Password on WifiPass.h file 76 | WiFi.begin(ssid, pass); 77 | Serial.print("Attempting wifi connection"); 78 | while ( WiFi.status() != WL_CONNECTED ) { 79 | delay ( 500 ); 80 | Serial.print ( "." ); 81 | } 82 | 83 | timeClient.begin(); 84 | timeClient.update(); 85 | 86 | long actualTime = timeClient.getEpochTime(); 87 | Serial.print("Internet Epoch Time: "); 88 | Serial.println(actualTime); 89 | rtc.adjust(DateTime(actualTime)); 90 | 91 | 92 | 93 | //Turn Off WIFI after update 94 | WiFi.disconnect(); 95 | WiFi.mode(WIFI_OFF); 96 | WiFi.forceSleepBegin(); 97 | 98 | } 99 | 100 | 101 | void loop () { 102 | DateTime now = rtc.now(); 103 | 104 | Serial.print(now.year(), DEC); 105 | Serial.print('/'); 106 | Serial.print(now.month(), DEC); 107 | Serial.print('/'); 108 | Serial.print(now.day(), DEC); 109 | Serial.print(" ("); 110 | Serial.print(daysOfTheWeek[now.dayOfTheWeek()]); 111 | Serial.print(") "); 112 | Serial.print(now.hour(), DEC); 113 | Serial.print(':'); 114 | Serial.print(now.minute(), DEC); 115 | Serial.print(':'); 116 | Serial.print(now.second(), DEC); 117 | Serial.println(); 118 | 119 | Serial.print(" since midnight 1/1/1970 = "); 120 | Serial.print(now.unixtime()); 121 | Serial.print("s = "); 122 | Serial.print(now.unixtime() / 86400L); 123 | Serial.println("d"); 124 | 125 | // calculate a date which is 7 days and 30 seconds into the future 126 | DateTime future (now + TimeSpan(7, 12, 30, 6)); 127 | 128 | Serial.print(" now + 7d + 30s: "); 129 | Serial.print(future.year(), DEC); 130 | Serial.print('/'); 131 | Serial.print(future.month(), DEC); 132 | Serial.print('/'); 133 | Serial.print(future.day(), DEC); 134 | Serial.print(' '); 135 | Serial.print(future.hour(), DEC); 136 | Serial.print(':'); 137 | Serial.print(future.minute(), DEC); 138 | Serial.print(':'); 139 | Serial.print(future.second(), DEC); 140 | Serial.println(); 141 | 142 | Serial.println(); 143 | delay(1000); 144 | } 145 | -------------------------------------------------------------------------------- /IRService.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * IRremoteESP8266: IRrecvDumpV2 - dump details of IR codes with IRrecv 3 | * An IR detector/demodulator must be connected to the input kRecvPin. 4 | * 5 | * Copyright 2009 Ken Shirriff, http://arcfn.com 6 | * Copyright 2017-2019 David Conran 7 | * 8 | * Example circuit diagram: 9 | * https://github.com/crankyoldgit/IRremoteESP8266/wiki#ir-receiving 10 | * 11 | * Changes: 12 | * Version 1.2 October, 2020 13 | * - Enable easy setting of the decoding tolerance value. 14 | * Version 1.0 October, 2019 15 | * - Internationalisation (i18n) support. 16 | * - Stop displaying the legacy raw timing info. 17 | * Version 0.5 June, 2019 18 | * - Move A/C description to IRac.cpp. 19 | * Version 0.4 July, 2018 20 | * - Minor improvements and more A/C unit support. 21 | * Version 0.3 November, 2017 22 | * - Support for A/C decoding for some protocols. 23 | * Version 0.2 April, 2017 24 | * - Decode from a copy of the data so we can start capturing faster thus 25 | * reduce the likelihood of miscaptures. 26 | * Based on Ken Shirriff's IrsendDemo Version 0.1 July, 2009, 27 | */ 28 | 29 | #include "IRService.h" 30 | 31 | // ==================== start of TUNEABLE PARAMETERS ==================== 32 | // An IR detector/demodulator is connected to GPIO pin 2 33 | // e.g. D5 on a NodeMCU board. 34 | // Note: GPIO 16 won't work on the ESP8266 as it does not have interrupts. 35 | const uint16_t kRecvPin = 2; 36 | 37 | // As this program is a special purpose capture/decoder, let us use a larger 38 | // than normal buffer so we can handle Air Conditioner remote codes. 39 | const uint16_t kCaptureBufferSize = 1024; 40 | 41 | // kTimeout is the Nr. of milli-Seconds of no-more-data before we consider a 42 | // message ended. 43 | // This parameter is an interesting trade-off. The longer the timeout, the more 44 | // complex a message it can capture. e.g. Some device protocols will send 45 | // multiple message packets in quick succession, like Air Conditioner remotes. 46 | // Air Coniditioner protocols often have a considerable gap (20-40+ms) between 47 | // packets. 48 | // The downside of a large timeout value is a lot of less complex protocols 49 | // send multiple messages when the remote's button is held down. The gap between 50 | // them is often also around 20+ms. This can result in the raw data be 2-3+ 51 | // times larger than needed as it has captured 2-3+ messages in a single 52 | // capture. Setting a low timeout value can resolve this. 53 | // So, choosing the best kTimeout value for your use particular case is 54 | // quite nuanced. Good luck and happy hunting. 55 | // NOTE: Don't exceed kMaxTimeoutMs. Typically 130ms. 56 | #if DECODE_AC 57 | // Some A/C units have gaps in their protocols of ~40ms. e.g. Kelvinator 58 | // A value this large may swallow repeats of some protocols 59 | const uint8_t kTimeout = 50; 60 | #else // DECODE_AC 61 | // Suits most messages, while not swallowing many repeats. 62 | const uint8_t kTimeout = 15; 63 | #endif // DECODE_AC 64 | // Alternatives: 65 | // const uint8_t kTimeout = 90; 66 | // Suits messages with big gaps like XMP-1 & some aircon units, but can 67 | // accidentally swallow repeated messages in the rawData[] output. 68 | // 69 | // const uint8_t kTimeout = kMaxTimeoutMs; 70 | // This will set it to our currently allowed maximum. 71 | // Values this high are problematic because it is roughly the typical boundary 72 | // where most messages repeat. 73 | // e.g. It will stop decoding a message and start sending it to serial at 74 | // precisely the time when the next message is likely to be transmitted, 75 | // and may miss it. 76 | 77 | // Set the smallest sized "UNKNOWN" message packets we actually care about. 78 | // This value helps reduce the false-positive detection rate of IR background 79 | // noise as real messages. The chances of background IR noise getting detected 80 | // as a message increases with the length of the kTimeout value. (See above) 81 | // The downside of setting this message too large is you can miss some valid 82 | // short messages for protocols that this library doesn't yet decode. 83 | // 84 | // Set higher if you get lots of random short UNKNOWN messages when nothing 85 | // should be sending a message. 86 | // Set lower if you are sure your setup is working, but it doesn't see messages 87 | // from your device. (e.g. Other IR remotes work.) 88 | // NOTE: Set this value very high to effectively turn off UNKNOWN detection. 89 | const uint16_t kMinUnknownSize = 12; 90 | 91 | // How much percentage lee way do we give to incoming signals in order to match 92 | // it? 93 | // e.g. +/- 25% (default) to an expected value of 500 would mean matching a 94 | // value between 375 & 625 inclusive. 95 | // Note: Default is 25(%). Going to a value >= 50(%) will cause some protocols 96 | // to no longer match correctly. In normal situations you probably do not 97 | // need to adjust this value. Typically that's when the library detects 98 | // your remote's message some of the time, but not all of the time. 99 | const uint8_t kTolerancePercentage = kTolerance; // kTolerance is normally 25% 100 | 101 | // Legacy (No longer supported!) 102 | // 103 | // Change to `true` if you miss/need the old "Raw Timing[]" display. 104 | #define LEGACY_TIMING_INFO false 105 | // ==================== end of TUNEABLE PARAMETERS ==================== 106 | 107 | // Use turn on the save buffer feature for more complete capture coverage. 108 | IRrecv irrecv(kRecvPin, kCaptureBufferSize, kTimeout, true); 109 | decode_results results; // Somewhere to store the results 110 | 111 | // const int RED_LED_PIN = 4; 112 | 113 | 114 | 115 | // This section of code runs only once at start-up. 116 | void IR_init() { 117 | //pinMode(RED_LED_PIN, OUTPUT); 118 | 119 | // Perform a low level sanity checks that the compiler performs bit field 120 | // packing as we expect and Endianness is as we expect. 121 | assert(irutils::lowLevelSanityCheck() == 0); 122 | 123 | Serial.printf("\n" D_STR_IRRECVDUMP_STARTUP "\n", kRecvPin); 124 | #if DECODE_HASH 125 | // Ignore messages with less than minimum on or off pulses. 126 | irrecv.setUnknownThreshold(kMinUnknownSize); 127 | #endif // DECODE_HASH 128 | irrecv.setTolerance(kTolerancePercentage); // Override the default tolerance. 129 | irrecv.enableIRIn(); // Start the receiver 130 | } 131 | 132 | 133 | // bool isRedOn = false; 134 | 135 | 136 | // The repeating section of the code 137 | void IR_read() { 138 | // Check if the IR code has been received. 139 | if (irrecv.decode(&results)) { 140 | 141 | Serial.printf("It is: 0x%08x\n", results.value); // gives 0x00000007 142 | 143 | // if (results.value == 0xFFB04F) { // Key '4' is pressed which belongs to the red LED 144 | // if (isRedOn == true) { // Red LED is on, turn it off and set update corresponding state variable 145 | // digitalWrite(RED_LED_PIN, LOW); 146 | // isRedOn = false; 147 | // } else { // Red LED is off, turn it on and set update corresponding state variable 148 | // digitalWrite(RED_LED_PIN, HIGH); 149 | // isRedOn = true; 150 | // } 151 | // } 152 | 153 | // Display a crude timestamp. 154 | uint32_t now = millis(); 155 | Serial.printf(D_STR_TIMESTAMP " : %06u.%03u\n", now / 1000, now % 1000); 156 | // Check if we got an IR message that was to big for our capture buffer. 157 | if (results.overflow) 158 | Serial.printf(D_WARN_BUFFERFULL "\n", kCaptureBufferSize); 159 | // Display the library version the message was captured with. 160 | Serial.println(D_STR_LIBRARY " : v" _IRREMOTEESP8266_VERSION_ "\n"); 161 | // Display the tolerance percentage if it has been change from the default. 162 | if (kTolerancePercentage != kTolerance) 163 | Serial.printf(D_STR_TOLERANCE " : %d%%\n", kTolerancePercentage); 164 | // Display the basic output of what we found. 165 | Serial.print(resultToHumanReadableBasic(&results)); 166 | // Display any extra A/C info if we have it. 167 | String description = IRAcUtils::resultAcToString(&results); 168 | if (description.length()) Serial.println(D_STR_MESGDESC ": " + description); 169 | yield(); // Feed the WDT as the text output can take a while to print. 170 | #if LEGACY_TIMING_INFO 171 | // Output legacy RAW timing info of the result. 172 | Serial.println(resultToTimingInfo(&results)); 173 | yield(); // Feed the WDT (again) 174 | #endif // LEGACY_TIMING_INFO 175 | // Output the results as source code 176 | Serial.println(resultToSourceCode(&results)); 177 | Serial.println(); // Blank line between entries 178 | yield(); // Feed the WDT (again) 179 | } 180 | } 181 | -------------------------------------------------------------------------------- /temp/IRBackup.cpp.bak: -------------------------------------------------------------------------------- 1 | /* 2 | * IRremoteESP8266: IRrecvDumpV2 - dump details of IR codes with IRrecv 3 | * An IR detector/demodulator must be connected to the input kRecvPin. 4 | * 5 | * Copyright 2009 Ken Shirriff, http://arcfn.com 6 | * Copyright 2017-2019 David Conran 7 | * 8 | * Example circuit diagram: 9 | * https://github.com/crankyoldgit/IRremoteESP8266/wiki#ir-receiving 10 | * 11 | * Changes: 12 | * Version 1.2 October, 2020 13 | * - Enable easy setting of the decoding tolerance value. 14 | * Version 1.0 October, 2019 15 | * - Internationalisation (i18n) support. 16 | * - Stop displaying the legacy raw timing info. 17 | * Version 0.5 June, 2019 18 | * - Move A/C description to IRac.cpp. 19 | * Version 0.4 July, 2018 20 | * - Minor improvements and more A/C unit support. 21 | * Version 0.3 November, 2017 22 | * - Support for A/C decoding for some protocols. 23 | * Version 0.2 April, 2017 24 | * - Decode from a copy of the data so we can start capturing faster thus 25 | * reduce the likelihood of miscaptures. 26 | * Based on Ken Shirriff's IrsendDemo Version 0.1 July, 2009, 27 | */ 28 | 29 | #include 30 | #include 31 | #include 32 | #include 33 | #include 34 | #include 35 | #include 36 | 37 | // ==================== start of TUNEABLE PARAMETERS ==================== 38 | // An IR detector/demodulator is connected to GPIO pin 14 39 | // e.g. D5 on a NodeMCU board. 40 | // Note: GPIO 16 won't work on the ESP8266 as it does not have interrupts. 41 | const uint16_t kRecvPin = 14; 42 | 43 | // The Serial connection baud rate. 44 | // i.e. Status message will be sent to the PC at this baud rate. 45 | // Try to avoid slow speeds like 9600, as you will miss messages and 46 | // cause other problems. 115200 (or faster) is recommended. 47 | // NOTE: Make sure you set your Serial Monitor to the same speed. 48 | const uint32_t kBaudRate = 115200; 49 | 50 | // As this program is a special purpose capture/decoder, let us use a larger 51 | // than normal buffer so we can handle Air Conditioner remote codes. 52 | const uint16_t kCaptureBufferSize = 1024; 53 | 54 | // kTimeout is the Nr. of milli-Seconds of no-more-data before we consider a 55 | // message ended. 56 | // This parameter is an interesting trade-off. The longer the timeout, the more 57 | // complex a message it can capture. e.g. Some device protocols will send 58 | // multiple message packets in quick succession, like Air Conditioner remotes. 59 | // Air Coniditioner protocols often have a considerable gap (20-40+ms) between 60 | // packets. 61 | // The downside of a large timeout value is a lot of less complex protocols 62 | // send multiple messages when the remote's button is held down. The gap between 63 | // them is often also around 20+ms. This can result in the raw data be 2-3+ 64 | // times larger than needed as it has captured 2-3+ messages in a single 65 | // capture. Setting a low timeout value can resolve this. 66 | // So, choosing the best kTimeout value for your use particular case is 67 | // quite nuanced. Good luck and happy hunting. 68 | // NOTE: Don't exceed kMaxTimeoutMs. Typically 130ms. 69 | #if DECODE_AC 70 | // Some A/C units have gaps in their protocols of ~40ms. e.g. Kelvinator 71 | // A value this large may swallow repeats of some protocols 72 | const uint8_t kTimeout = 50; 73 | #else // DECODE_AC 74 | // Suits most messages, while not swallowing many repeats. 75 | const uint8_t kTimeout = 15; 76 | #endif // DECODE_AC 77 | // Alternatives: 78 | // const uint8_t kTimeout = 90; 79 | // Suits messages with big gaps like XMP-1 & some aircon units, but can 80 | // accidentally swallow repeated messages in the rawData[] output. 81 | // 82 | // const uint8_t kTimeout = kMaxTimeoutMs; 83 | // This will set it to our currently allowed maximum. 84 | // Values this high are problematic because it is roughly the typical boundary 85 | // where most messages repeat. 86 | // e.g. It will stop decoding a message and start sending it to serial at 87 | // precisely the time when the next message is likely to be transmitted, 88 | // and may miss it. 89 | 90 | // Set the smallest sized "UNKNOWN" message packets we actually care about. 91 | // This value helps reduce the false-positive detection rate of IR background 92 | // noise as real messages. The chances of background IR noise getting detected 93 | // as a message increases with the length of the kTimeout value. (See above) 94 | // The downside of setting this message too large is you can miss some valid 95 | // short messages for protocols that this library doesn't yet decode. 96 | // 97 | // Set higher if you get lots of random short UNKNOWN messages when nothing 98 | // should be sending a message. 99 | // Set lower if you are sure your setup is working, but it doesn't see messages 100 | // from your device. (e.g. Other IR remotes work.) 101 | // NOTE: Set this value very high to effectively turn off UNKNOWN detection. 102 | const uint16_t kMinUnknownSize = 12; 103 | 104 | // How much percentage lee way do we give to incoming signals in order to match 105 | // it? 106 | // e.g. +/- 25% (default) to an expected value of 500 would mean matching a 107 | // value between 375 & 625 inclusive. 108 | // Note: Default is 25(%). Going to a value >= 50(%) will cause some protocols 109 | // to no longer match correctly. In normal situations you probably do not 110 | // need to adjust this value. Typically that's when the library detects 111 | // your remote's message some of the time, but not all of the time. 112 | const uint8_t kTolerancePercentage = kTolerance; // kTolerance is normally 25% 113 | 114 | // Legacy (No longer supported!) 115 | // 116 | // Change to `true` if you miss/need the old "Raw Timing[]" display. 117 | #define LEGACY_TIMING_INFO false 118 | // ==================== end of TUNEABLE PARAMETERS ==================== 119 | 120 | // Use turn on the save buffer feature for more complete capture coverage. 121 | IRrecv irrecv(kRecvPin, kCaptureBufferSize, kTimeout, true); 122 | decode_results results; // Somewhere to store the results 123 | 124 | const int RED_LED_PIN = 4; 125 | 126 | 127 | 128 | // This section of code runs only once at start-up. 129 | void setup() { 130 | pinMode(RED_LED_PIN, OUTPUT); 131 | 132 | #if defined(ESP8266) 133 | Serial.begin(kBaudRate, SERIAL_8N1, SERIAL_TX_ONLY); 134 | #else // ESP8266 135 | Serial.begin(kBaudRate, SERIAL_8N1); 136 | #endif // ESP8266 137 | while (!Serial) // Wait for the serial connection to be establised. 138 | delay(50); 139 | // Perform a low level sanity checks that the compiler performs bit field 140 | // packing as we expect and Endianness is as we expect. 141 | assert(irutils::lowLevelSanityCheck() == 0); 142 | 143 | Serial.printf("\n" D_STR_IRRECVDUMP_STARTUP "\n", kRecvPin); 144 | #if DECODE_HASH 145 | // Ignore messages with less than minimum on or off pulses. 146 | irrecv.setUnknownThreshold(kMinUnknownSize); 147 | #endif // DECODE_HASH 148 | irrecv.setTolerance(kTolerancePercentage); // Override the default tolerance. 149 | irrecv.enableIRIn(); // Start the receiver 150 | } 151 | 152 | 153 | bool isRedOn = false; 154 | 155 | 156 | // The repeating section of the code 157 | void loop() { 158 | // Check if the IR code has been received. 159 | if (irrecv.decode(&results)) { 160 | 161 | Serial.printf("It is: 0x%08x\n", results.value); // gives 0x00000007 162 | 163 | if (results.value == 0xFFB04F) { // Key '4' is pressed which belongs to the red LED 164 | if (isRedOn == true) { // Red LED is on, turn it off and set update corresponding state variable 165 | digitalWrite(RED_LED_PIN, LOW); 166 | isRedOn = false; 167 | } else { // Red LED is off, turn it on and set update corresponding state variable 168 | digitalWrite(RED_LED_PIN, HIGH); 169 | isRedOn = true; 170 | } 171 | } 172 | 173 | // Display a crude timestamp. 174 | uint32_t now = millis(); 175 | Serial.printf(D_STR_TIMESTAMP " : %06u.%03u\n", now / 1000, now % 1000); 176 | // Check if we got an IR message that was to big for our capture buffer. 177 | if (results.overflow) 178 | Serial.printf(D_WARN_BUFFERFULL "\n", kCaptureBufferSize); 179 | // Display the library version the message was captured with. 180 | Serial.println(D_STR_LIBRARY " : v" _IRREMOTEESP8266_VERSION_ "\n"); 181 | // Display the tolerance percentage if it has been change from the default. 182 | if (kTolerancePercentage != kTolerance) 183 | Serial.printf(D_STR_TOLERANCE " : %d%%\n", kTolerancePercentage); 184 | // Display the basic output of what we found. 185 | Serial.print(resultToHumanReadableBasic(&results)); 186 | // Display any extra A/C info if we have it. 187 | String description = IRAcUtils::resultAcToString(&results); 188 | if (description.length()) Serial.println(D_STR_MESGDESC ": " + description); 189 | yield(); // Feed the WDT as the text output can take a while to print. 190 | #if LEGACY_TIMING_INFO 191 | // Output legacy RAW timing info of the result. 192 | Serial.println(resultToTimingInfo(&results)); 193 | yield(); // Feed the WDT (again) 194 | #endif // LEGACY_TIMING_INFO 195 | // Output the results as source code 196 | Serial.println(resultToSourceCode(&results)); 197 | Serial.println(); // Blank line between entries 198 | yield(); // Feed the WDT (again) 199 | } 200 | } 201 | --------------------------------------------------------------------------------