数码之家

 找回密码
 立即注册
搜索
查看: 4766|回复: 12

[外设] 基于ESP8266的红外学习型遥控器,可Blinker远程、定时控制空调,软硬件开源

[复制链接]
发表于 2021-9-4 17:08:19 | 显示全部楼层 |阅读模式

爱科技、爱创意、爱折腾、爱极致,我们都是技术控

您需要 登录 才可以下载或查看,没有账号?立即注册

x
本帖最后由 胡奚曷 于 2021-9-4 18:36 编辑

1.前言宿舍有空调,但没有遥控器

小米8手机不支持红外遥控器,只能外接USB的红外发射器
操作起来比较繁琐,因此想着DIY一个
2.硬件
由于手上有现成ESP8266 ESP-12F,38K红外接收头,红外二极管,做一个不费钱
咸鱼上6.8的艾韵的我也看了,买6个才包邮,用不上那么多,就没买


硬件设计如图,注意用AM2320的话,DATA引脚要上拉5.1K的电阻,否则不识别(图上没有,我是外挂的电阻)
DTH11可以不用上拉电阻
未命名1630743393.png
兼容USB C接口
未命名1630743421.png
打样回来
未命名1630743739.png
贴片焊接
未命名1630743636.png
全部焊好的样子
未命名1630743646.png 未命名1630743654.png
用法,接上适配器,插墙上,LED对着空调即可

未命名1630743671.png
3.软件
软件参考了阳阳学编程的思路
目录结构如图
未命名1630744184.png
文件名:IRremote.ino
代码:注意AM2320的话选dht.setup(5, DHTesp::DHT22);
  1. #define BLINKER_WIFI
  2. #define BLINKER_MIOT_OUTLET

  3. #include <Blinker.h>
  4. #include "Button.h"
  5. #include "DHTesp.h"
  6. #include "Blwifi.h"
  7. #include <IRsend.h>
  8. #include <IRrecv.h>
  9. #include <IRremoteESP8266.h>
  10. #include <IRutils.h>
  11. #include <LittleFS.h>
  12. #include <FS.h>

  13. // The GPIO an IR detector/demodulator is connected to. Recommended: 14
  14. // Note: GPIO 16 won't work on the ESP8266 as it does not have interrupts.
  15. const uint16_t kRecvPin = 14;
  16. // GPIO to use to control the IR LED circuit. Recommended: 4
  17. const uint16_t kIrLedPin = 4;
  18. // As this program is a special purpose capture/resender, let's use a larger
  19. // than expected buffer so we can handle very large IR messages.
  20. const uint16_t kCaptureBufferSize = 1024;  // 1024 == ~511 bits
  21. // kFrequency is the modulation frequency all UNKNOWN messages will be sent at.
  22. const uint16_t kFrequency = 38000;  // in Hz. e.g. 38kHz.
  23. // kTimeout is the Nr. of milli-Seconds of no-more-data before we consider a
  24. // message ended.
  25. const uint8_t kTimeout = 50;  // Milli-Seconds

  26. // The IR transmitter.
  27. IRsend irsend(kIrLedPin);
  28. // The IR receiver.
  29. IRrecv irrecv(kRecvPin, kCaptureBufferSize, kTimeout, false);
  30. // Somewhere to store the captured message.
  31. decode_results results;

  32. const uint8_t ir_num = 10;
  33. const uint16_t ir_maxLength = 511;
  34. struct IrCodeSave
  35. {
  36.   uint16_t ir_code[ir_num][ir_maxLength];
  37.   uint16_t ir_size[ir_num];
  38. };
  39. IrCodeSave irInfo;

  40. BlinkerButton &GetBlButton(const uint32_t id);

  41. BlinkerNumber Temperature("num-tmp");
  42. BlinkerNumber Humidity("num-hum");
  43. DHTesp dht;

  44. bool learn = false;
  45. uint32_t learnID = 0;
  46. String btColor[ir_num]={"#ff0000","#0000FF","#FFB90F","#274e13","#274e13","#ff0000","#0000FF","#FFB90F","#274e13","#274e13"};

  47. bool loadConfig(FS *fs)
  48. {
  49.   if (!fs->begin())
  50.   {
  51.     Serial.println("Unable to begin(), aborting");
  52.     return false;
  53.   }
  54.   Serial.println("Reading file, may take a while...");
  55.   long start = millis();
  56.   File f = fs->open("/irconfig.bin", "r");
  57.   if (!f)
  58.   {
  59.     Serial.println("Unable to open file for reading, aborting");
  60.     return false;
  61.   }
  62.   f.read((uint8_t*)&irInfo, sizeof(IrCodeSave));
  63.   f.close();
  64.   long stop = millis();
  65.   Serial.printf("==> Time to write  chunks = %ld milliseconds\n", stop - start);
  66.   return true;
  67. }

  68. bool saveConfig(FS *fs)
  69. {
  70.   if (!fs->begin())
  71.   {
  72.     Serial.println("Unable to begin(), aborting");
  73.     return false;
  74.   }
  75.   Serial.println("Creating file, may take a while...");
  76.   long start = millis();
  77.   File f = fs->open("/irconfig.bin", "w");
  78.   if (!f)
  79.   {
  80.     Serial.println("Unable to open file for writing, aborting");
  81.     return false;
  82.   }
  83.   f.write((char*)&irInfo, sizeof(IrCodeSave));
  84.   f.close();
  85.   long stop = millis();
  86.   Serial.printf("==> Time to write  chunks = %ld milliseconds\n", stop - start);
  87.   return true;
  88. }

  89. uint32_t ir_rcv_delay = 0;
  90. void ir_loop()
  91. {
  92.   if (irrecv.decode(&results))
  93.   {
  94.     if(ir_rcv_delay < millis())
  95.     {
  96.       ir_rcv_delay = millis()+1000;
  97.       uint16_t *raw_array = resultToRawArray(&results);
  98.       uint16_t size = getCorrectedRawLength(&results);
  99.       BLINKER_LOG("IR size: ", size);
  100.       if(size <= ir_maxLength && learn)
  101.       {
  102.         for(int i=0;i<size;i++)
  103.         {
  104.           irInfo.ir_code[learnID][i]=raw_array[i];
  105.         }
  106.         irInfo.ir_size[learnID]=size;
  107.       }
  108.       
  109.     }
  110.     String basic = resultToHumanReadableBasic(&results);
  111.     basic.replace(" ","");
  112.     Serial.print(basic.c_str());
  113.     irrecv.resume();
  114.   }
  115. }

  116. void mbt_callback(uint32_t btID)
  117. {
  118.   BLINKER_LOG("long press ", btID);
  119.   if(learn == false)
  120.   {
  121.     learn = true;
  122.     GetBlButton(btID).color("#DCDCDC");
  123.     GetBlButton(btID).print("");
  124.     learnID = btID;
  125.   }
  126.   else
  127.   {
  128.     if(learnID == btID)
  129.     {
  130.       learn = false;
  131.       GetBlButton(btID).color(btColor[btID]);
  132.       GetBlButton(btID).print("");
  133.       saveConfig(&LittleFS);
  134.     }
  135.   }
  136. }
  137. // 新建组件对象
  138. #define Button_Callback_Def(index,name)         \
  139.   BlinkerButton Bt##index(name);                \
  140.   Button mbt##index(mbt_callback,index,3000);   \
  141.   void button_callback##index(const String & state) \
  142.   {                                                 \
  143.     BLINKER_LOG("get button state: ", state);       \
  144.     mbt##index.KeyEvent(state);                     \
  145.     if(state == "tap")                              \
  146.     {                                               \
  147.       irsend.sendRaw(irInfo.ir_code[index], irInfo.ir_size[index], kFrequency); \
  148.     }                                               \
  149.   }                                                

  150. #define Button_Loop(index)             \
  151.     mbt##index.loop();

  152. #define Button_Attach(index)         \
  153.     Bt##index.attach(button_callback##index);
  154.    
  155. Button_Callback_Def(0,"btn-0");
  156. Button_Callback_Def(1,"btn-1");
  157. Button_Callback_Def(2,"btn-2");
  158. Button_Callback_Def(3,"btn-3");
  159. Button_Callback_Def(4,"btn-4");
  160. Button_Callback_Def(5,"btn-5");
  161. Button_Callback_Def(6,"btn-6");
  162. Button_Callback_Def(7,"btn-7");
  163. Button_Callback_Def(8,"btn-8");
  164. Button_Callback_Def(9,"btn-9");

  165. BlinkerButton &GetBlButton(const uint32_t id)
  166. {
  167.   switch(id)
  168.   {
  169.     case 0: return Bt0;
  170.     case 1: return Bt1;
  171.     case 2: return Bt2;
  172.     case 3: return Bt3;
  173.     case 4: return Bt4;
  174.     case 5: return Bt5;
  175.     case 6: return Bt6;
  176.     case 7: return Bt7;
  177.     case 8: return Bt8;
  178.     case 9: return Bt9;
  179.     default: return Bt0;
  180.   }
  181. }

  182. void dataRead(const String & data)
  183. {
  184.     BLINKER_LOG("Blinker readString: ", data);

  185.     Blinker.vibrate();
  186.    
  187.     uint32_t BlinkerTime = millis();
  188.    
  189.     Blinker.print("millis", BlinkerTime);
  190. }

  191. float tmp;
  192. float hum;
  193. void heartbeat()
  194. {  
  195.   Temperature.print(tmp);
  196.   Humidity.print(hum);
  197.   BLINKER_LOG("heart beat temperature: ", tmp);
  198.   BLINKER_LOG("heart beat humidity: ", hum);
  199. }
  200. void dataStorage()
  201. {
  202.     Blinker.dataStorage("temp", tmp);
  203.     Blinker.dataStorage("humi", hum);
  204.     BLINKER_LOG("data Storage temperature: ", tmp);
  205.     BLINKER_LOG("data Storage humidity: ", hum);
  206. }
  207. void setup()
  208. {
  209.     Serial.begin(115200);
  210.     BLINKER_DEBUG.stream(Serial);
  211.    
  212.     Blwifi_InitWiFi();
  213.    
  214.     irrecv.enableIRIn();  // Start up the IR receiver.
  215.     irsend.begin();       // Start up the IR sender.
  216.    
  217.     Blinker.begin(wifiSettings.auth_key, wifiSettings.ssid, wifiSettings.pswd);
  218.     Blinker.attachData(dataRead);
  219.     Blinker.attachHeartbeat(heartbeat);

  220.     dht.setup(5, DHTesp::DHT11); // Connect DHT sensor to GPIO 5

  221.     Button_Attach(0);
  222.     Button_Attach(1);
  223.     Button_Attach(2);
  224.     Button_Attach(3);
  225.     Button_Attach(4);
  226.     Button_Attach(5);
  227.     Button_Attach(6);
  228.     Button_Attach(7);
  229.     Button_Attach(8);
  230.     Button_Attach(9);
  231.     Blinker.attachDataStorage(dataStorage);

  232.     loadConfig(&LittleFS);
  233. }

  234. void loop()
  235. {
  236.     float t1,h1;
  237.     Blinker.run();
  238.     Blwifi_Loop();
  239.     t1=dht.getTemperature();
  240.     h1=dht.getHumidity();
  241.     if(t1 != -1024)
  242.       tmp = t1;
  243.     if(h1 != -1024)
  244.       hum = h1;
  245.     Button_Loop(0);
  246.     Button_Loop(1);
  247.     Button_Loop(2);
  248.     Button_Loop(3);
  249.     Button_Loop(4);
  250.     Button_Loop(5);
  251.     Button_Loop(6);
  252.     Button_Loop(7);
  253.     Button_Loop(8);
  254.     Button_Loop(9);
  255.     ir_loop();
  256. }
复制代码
文件名:GpioButton.h(这是本论坛下载的),主要用于长按按键,恢复配网用的
代码:
  1. #ifndef _GPIO_BUTTON_H_
  2. #define _GPIO_BUTTON_H_
  3. #include <Arduino.h>

  4. #define DEF_ELIMINATING_JITTER_MS        20                // default eliminating jitter ms
  5. #define DEF_LONG_PRESS_WAIT_MS  1000                // default long press wait ms
  6. #define DEF_DB_PRESS_MS 300

  7. class GpioButton {
  8.     public:
  9.         GpioButton(uint8_t gpio_pin, void(*btn_press_event)()=nullptr) :
  10.             GpioPin(gpio_pin),
  11.             ButtonPressEvent(btn_press_event),
  12.             LongPressWaitMS(DEF_LONG_PRESS_WAIT_MS),
  13.             ButtonLongPressEvent(nullptr),
  14.             first_key_down_millis(0),
  15.             first_key_up_millis(0),
  16.             action_done(false),
  17.             last_gpio_state(HIGH) {
  18.                 pinMode(GpioPin, INPUT_PULLUP);
  19.                 digitalWrite(GpioPin, HIGH);
  20.         };
  21.         // bind click event CB function
  22.         void BindBtnPress(void(*btn_press_event)()) {
  23.                 ButtonPressEvent = btn_press_event;
  24.         };
  25.         // bind long key press CB function
  26.         bool BindBtnLongPress(void(*btn_long_press_event)(), uint16_t wait_ms=DEF_LONG_PRESS_WAIT_MS) {
  27.             if(wait_ms < DEF_LONG_PRESS_WAIT_MS) return false;
  28.             ButtonLongPressEvent = btn_long_press_event;
  29.             LongPressWaitMS = wait_ms;
  30.             return true;
  31.         };
  32.         // bind double click CB function
  33.         void BindBtnDblPress(void(*btn_dbl_press_event)()) {
  34.             ButtonDblPressEvent = btn_dbl_press_event;
  35.         };
  36.         // loop function
  37.         void loop(){
  38.             
  39.             uint8_t current_gpio_state = digitalRead(GpioPin);
  40.             uint32_t current_millis = millis();
  41.             
  42.             // gpio status no change
  43.             if(current_gpio_state == last_gpio_state) {
  44.                 if(current_gpio_state == LOW) {
  45.                     if(first_key_down_millis && !first_key_up_millis && (current_millis - first_key_down_millis > LongPressWaitMS)) {
  46.                         if(!action_done && ButtonLongPressEvent != nullptr) {
  47.                             ButtonLongPressEvent();
  48.                             action_done = true;
  49.                         }
  50.                     }
  51.                 }
  52.                 else {
  53.                     if(first_key_up_millis && (current_millis - first_key_up_millis > DEF_DB_PRESS_MS)) {
  54.                         if(!action_done && ButtonPressEvent != nullptr) {
  55.                             // Serial.println("Debug:Press Event.");
  56.                             ButtonPressEvent();
  57.                             action_done = true;
  58.                         }
  59.                     }
  60.                 }
  61.             }
  62.             // gpio status changed
  63.             else {
  64.                 if(current_millis - last_jitter_millis > DEF_ELIMINATING_JITTER_MS) {
  65.                     // key down
  66.                     if(current_gpio_state == LOW) {
  67.                         // is first keydown in cycle
  68.                         if(0 == first_key_down_millis) {
  69.                             first_key_down_millis = current_millis;
  70.                             first_key_up_millis = 0;
  71.                             action_done = false;
  72.                         }
  73.                         // is not first key down in cycle
  74.                         else {
  75.                             // has define double click CB function
  76.                             if(nullptr != ButtonDblPressEvent){
  77.                                 // key down mill - last key up mill > elimination jitter interval
  78.                                 if(        0 != first_key_up_millis // is release key in event cycle
  79.                                     && (current_millis - first_key_up_millis) > DEF_ELIMINATING_JITTER_MS) {        // skip eliminating jitter
  80.                                     // is double click?
  81.                                     if(        false == action_done // did in event cycle?
  82.                                         && current_millis - first_key_up_millis < DEF_DB_PRESS_MS) {        // and 2nd click is in interval
  83.                                         // call double click event function
  84.                                         // Serial.println("Debug:Double Press Event.");
  85.                                         ButtonDblPressEvent();
  86.                                         action_done = true;
  87.                                     }
  88.                                     
  89.                                 }
  90.                             }
  91.                         }
  92.                     }
  93.                     // key up
  94.                     else {
  95.                         if(!action_done && first_key_down_millis && first_key_up_millis == 0) {
  96.                             first_key_up_millis = current_millis;
  97.                         }
  98.                     }
  99.                     // Keep gpio status
  100.                     last_gpio_state = current_gpio_state;
  101.                     last_jitter_millis = current_millis;
  102.                 }
  103.             }
  104.             
  105.             if(action_done && current_gpio_state == HIGH) {
  106.                 // Serial.println("Event Reset.");
  107.                 first_key_down_millis = 0;
  108.                 first_key_up_millis = 0;
  109.                 action_done = false;
  110.             }
  111.         };
  112.     protected:
  113.         uint8_t GpioPin;                                                // gpio pin of key
  114.         void (*ButtonPressEvent)();       // Click Event CB function
  115.         uint16_t LongPressWaitMS;                            // Long press ms
  116.         void (*ButtonLongPressEvent)();                // Long press Event CB function
  117.         void (*ButtonDblPressEvent)();                // Double click Event CB function
  118.         uint32_t first_key_down_millis;
  119.         uint32_t first_key_up_millis;
  120.         bool action_done;
  121.         uint8_t last_gpio_state;
  122.         uint32_t last_jitter_millis;
  123. };

  124. #endif
复制代码
文件名:Button.h,用于支持Blinker按键长按
代码:
  1. #ifndef _BUTTON_H__
  2. #define _BUTTON_H__

  3. class Button
  4. {
  5.   protected:
  6.   void (*ButtonLongPressEvent)(uint32_t btID);
  7.   private:
  8.   uint32_t keyDownTime;
  9.   uint32_t keyLongPressTime = 3000;
  10.   String keyState = "";
  11.   bool keyDoneFlag = false;
  12.   uint32_t btID;
  13.   public:  
  14.   Button(void(*btn_long_press_event)(uint32_t btID),uint32_t id,uint32_t longPressTime)
  15.   {
  16.     BindBtnLongPress(btn_long_press_event,id,longPressTime);
  17.   }
  18.   void KeyEvent(const String & state)
  19.   {
  20.     keyState = state;
  21.     if(keyState == "press")
  22.       keyDownTime = millis();
  23.     else
  24.       keyDoneFlag = false;
  25.   }
  26.   void BindBtnLongPress(void(*btn_long_press_event)(uint32_t btID),uint32_t id,uint32_t longPressTime)
  27.   {
  28.     ButtonLongPressEvent = btn_long_press_event;
  29.     keyLongPressTime = longPressTime;
  30.     btID = id;
  31.   };
  32.   void loop()
  33.   {
  34.     if(keyDoneFlag == false && keyState == "press" && (millis()-keyDownTime)>=keyLongPressTime)
  35.     {
  36.       keyDoneFlag = true;
  37.       if(ButtonLongPressEvent!=nullptr)
  38.         ButtonLongPressEvent(btID);
  39.     }
  40.   }
  41. };

  42. #endif
复制代码
文件名:Blwifi.h(用于配网的)
代码:
  1. #ifndef __BLWIFI_H__
  2. #define __BLWIFI_H__

  3. #define RESET_WIFI_PIN   0

  4. struct Settings
  5. {
  6.   char auth_key[13];
  7.   char ssid[128];
  8.   char pswd[32];
  9. };
  10. extern Settings wifiSettings;

  11. void Blwifi_InitWiFi();
  12. void ClearWiFiInfo();
  13. void Blwifi_Loop();

  14. #endif
复制代码
文件名:Blwifi.cpp
代码:
  1. #include <WiFiManager.h>
  2. #include <EEPROM.h>
  3. #include "GpioButton.h"
  4. #include "Blwifi.h"

  5. WiFiManager wifiManager;


  6. // 定义按钮对象,指定按钮的GPIO口
  7. GpioButton myButton(RESET_WIFI_PIN);

  8. void ResetWifi()
  9. {
  10.   for(int i=0;i<3;i++)
  11.   {
  12.     digitalWrite(LED_BUILTIN, LOW);
  13.     delay(100);
  14.     digitalWrite(LED_BUILTIN, HIGH);
  15.     delay(400);
  16.   }
  17.   ClearWiFiInfo();
  18.   wifiManager.resetSettings();
  19.   ESP.restart();
  20. }
  21. void MyButton_Init()
  22. {
  23.   // 初始化板载LED信号灯
  24.   pinMode(LED_BUILTIN, OUTPUT);
  25.   digitalWrite(LED_BUILTIN, HIGH);
  26.   // 绑定按钮事件处理
  27.   myButton.BindBtnPress([](){
  28.     Serial.println("Button Press Event\r\n\tSetup Bind Event.");
  29.   });

  30.   // 绑定长按事件处理(长按判定为3000ms)
  31.   myButton.BindBtnLongPress([]()
  32.   {
  33.     Serial.println("Button Long Press Event\r\n\tSetup Bind Event.");
  34.     Serial.println(F("WiFi resetSettings."));
  35.     ResetWifi();
  36.   }, 3000);
  37. }


  38. bool shouldSaveConfig=false;
  39. Settings wifiSettings;

  40. void saveConfigCallback()
  41. {
  42.   Serial.println("Should save config");
  43.   shouldSaveConfig = true;
  44. }

  45. bool chkAuthkey(char* key, int len)
  46. {
  47.   if (len != 12) return false;
  48.   for (int i=0;key[i]!=0;i++){
  49.     if (!isxdigit(key[i])) return false;
  50.   }
  51.   return true;
  52. }
  53. void ClearWiFiInfo()
  54. {
  55.   EEPROM.begin(4096);
  56.   EEPROM.get<Settings>(2448, wifiSettings);
  57.   wifiSettings.auth_key[0]='\0';
  58.   EEPROM.put<Settings>(2448, wifiSettings);
  59.   if (EEPROM.commit())
  60.   {
  61.     Serial.println(F("EEPROM successfully committed"));
  62.   }
  63.   else
  64.   {
  65.     Serial.println(F("ERROR! EEPROM commit failed"));
  66.   }
  67.   EEPROM.end();
  68. }
  69. void Blwifi_InitWiFi()
  70. {
  71.   MyButton_Init();
  72.         
  73.   EEPROM.begin(4096);
  74.   EEPROM.get<Settings>(2448, wifiSettings);

  75.   if( wifiSettings.auth_key[0]=='\0'||wifiSettings.auth_key[0]==0xFF)
  76.   {
  77.     WiFi.mode(WIFI_STA);
  78.     //wifiManager.setDebugOutput(true);
  79.    
  80.     wifiManager.resetSettings();

  81.     wifiManager.setAPStaticIPConfig(IPAddress(192,168,10,1), IPAddress(192,168,10,1), IPAddress(255, 255, 255, 0));
  82.      // 3分钟配网时间,如没有完成则退出配网.
  83.      // 例如原正常连接的WIFI路由掉线死机或不通电等情况, 通过配网超时后, 会重新进行连接原WIFI信号。 避免停在配网模式下等待
  84.     wifiManager.setConfigPortalTimeout(180);
  85.     //wifiManager.setConnectTimeout(240);

  86.     // 设置点击保存的回调
  87.     wifiManager.setSaveConfigCallback(saveConfigCallback);

  88.     WiFiManagerParameter custom_authkey("auth_key", "Authkey", wifiSettings.auth_key, 12);
  89.     wifiManager.addParameter(&custom_authkey);

  90.     //AP名称:ESP_AP 密码:12345678
  91.     if(!wifiManager.autoConnect("ESP_AP","12345678"))
  92.     {
  93.       Serial.println(F("Failed to connect. Reset and try again. . ."));
  94.       ResetWifi();
  95.       delay(5000);
  96.     }

  97.     Serial.println(F("Connected to Wifi."));
  98.     Serial.print(F("My IP:"));
  99.     Serial.println(WiFi.localIP());

  100.     // 保存自定义信息
  101.     if (shouldSaveConfig)
  102.     {
  103.       Serial.println(F("saving config..."));
  104.       //Serial.println(custom_authkey.getValue());
  105.       strncpy(wifiSettings.auth_key, custom_authkey.getValue(), 12);
  106.       wifiSettings.auth_key[12] = '\0';
  107.       strcpy(wifiSettings.ssid, wifiManager.getWiFiSSID().c_str());
  108.       wifiSettings.ssid[wifiManager.getWiFiSSID().length()]='\0';
  109.       
  110.       strcpy(wifiSettings.pswd, wifiManager.getWiFiPass().c_str());
  111.       wifiSettings.pswd[wifiManager.getWiFiPass().length()]='\0';
  112.       
  113.       if (!chkAuthkey(wifiSettings.auth_key, strlen(wifiSettings.auth_key)))
  114.       {
  115.         Serial.println(F("Authkey is wrong."));
  116.         ResetWifi();
  117.         delay(5000);
  118.       }

  119.       EEPROM.put<Settings>(2448, wifiSettings);
  120.       if (EEPROM.commit())
  121.       {
  122.         Serial.println(F("EEPROM successfully committed"));
  123.       }
  124.       else
  125.       {
  126.         Serial.println(F("ERROR! EEPROM commit failed"));
  127.       }
  128.     }
  129.   }
  130.   EEPROM.end();
  131.   wifiSettings.auth_key[12] = '\0';
  132. }

  133. void Blwifi_Loop()
  134. {
  135.   myButton.loop();
  136. }
复制代码
注意依赖库
DHT_sensor_library_for_ESPx
IRremoteESP8266
WiFiManager
未命名1630744686.png 未命名1630744699.png 未命名1630744712.png
4.Blinker配置
配置界面:
lADPD4BhuhTg-ajNBP7NAmY_614_1278.jpg
界面配置代码如下
  1. {¨config¨{¨headerColor¨¨transparent¨¨headerStyle¨¨dark¨¨background¨{¨img¨¨assets/img/headerbg.jpg¨¨isFull¨«}}¨dashboard¨|{¨type¨¨btn¨¨ico¨¨fad fa-power-off¨¨mode¨É¨t0¨¨开启¨¨t1¨¨文本2¨¨bg¨É¨cols¨Í¨rows¨Í¨key¨¨btn-0¨´x´Ë´y´Ë¨speech¨|÷¨lstyle¨Ë¨clr¨¨#EA0909¨}{ßA¨num¨ßF¨室内温度¨ßC¨fad fa-thermometer-three-quarters¨ßQ¨#389BEE¨¨min¨É¨max¨¢1c¨uni¨¨℃ ¨ßJÉßKËßLËßM¨num-tmp¨´x´Ï´y´ËßO|÷ßPÉ}{ßAßSßF¨室内湿度¨ßC¨fad fa-humidity¨ßQßVßWÉßXº0ßY´%´ßJÉßKËßLËßM¨num-hum¨´x´É´y´ËßO|÷ßPÉ}{ßAßBßC¨fas fa-snowflakes¨ßEÉßF¨制冷¨ßHßIßJÉßKËßLËßM¨btn-1¨´x´É´y´ÍßO|÷ßQ¨#076EEF¨}{ßAßBßC¨fad fa-fire-alt¨ßEÉßF¨制热¨ßHßIßJÉßKËßLËßM¨btn-2¨´x´Ï´y´ÍßO|÷ßQ¨#FBA613¨}{ßA¨cha¨ßJɨsty¨¨line¨ßQßl¨sty1¨ßo¨clr1¨ßh¨sty2¨ßo¨clr2¨ßVßKÑßLÍßM¨cha-oh6¨´x´É´y´¤BßO|÷¨key0¨¨temp¨ßF¨温度¨¨key1¨¨humi¨ßH¨湿度¨ßPÊ}{ßAßBßC¨fad fa-cogs¨ßEÉßF¨定时2H¨ßHßIßJÉßKËßLËßM¨btn-3¨´x´Í´y´ÏßO|÷ßQ¨#00A90C¨}{ßAßBßCß10ßEÉßF¨定时3H¨ßHßIßJÉßKËßLËßM¨btn-4¨´x´Ï´y´ÏßO|÷ßQß13}{ßAßBßC¨fad fa-siren¨ßEÉßF´关闭´ßHßIßJÉßKËßLËßM¨btn-5¨´x´É´y´ÏßO|÷ßQßR}{ßAßBßCß10ßEÉßF¨定时1H¨ßHßIßJÉßKËßLËßM¨btn-6¨´x´Ë´y´ÏßO|÷ßQß13}{ßA¨tim¨ßJÉßKËßLËßM¨timing¨´x´Ì´y´ÑßO|÷ßPÉ}÷¨actions¨|{¨cmd¨{ßN¨tap¨}¨text¨¨开空调¨}{ß1D{ß17ß1E}ß1F¨关空调¨}÷¨triggers¨|÷}
复制代码
由于空调设置的值信息,如温度,风量,定时时间不好学习,所以这里就没做,因此不支持设定
5.使用方法
5.1烧录方法
(1)按住按键,给模块上电
(2)连上RX,TX到串口上
(3)Arduino上传
(4)下电重启
5.2配网方法
(1)手机搜索ESP_AP的WiFi信号,密码12345678
(2)弹出的界面上输入你家的WiFi名称和密码,再输入Blinker申请到的密钥
lADPD4d8t165il3NBP7NAmY_614_1278.jpg lADPD4PvOLnyoxvNBP7NAmY_614_1278.jpg
(3)点击Save即可完成配网
5.3学习方法
(1)设备上线后,长按需要配对的按键持续3s,按键颜色变灰
(2)遥控器对准红外接收头,按下需要学的按键
(3)长按变灰的按键,持续3s,颜色恢复正常即学习完成
(4)Blinker界面操作,看能否控制空调
(5)其他按键类似
5.4定时开启或关闭空调
(1)点击闹钟图标
(2)选择动作(开空调还是关空调)
(3)设置动作时间
5.5其他智能化场景,例如温度高自动开空调等,请自行摸索
6.原理图和代码
遥控器-原理图和代码.rar (475.92 KB, 下载次数: 23)
7.注意事项
7.1 DHT11经常出现NA的情况,原因不明,AM2320没这个问题
可以将DHT库里的NA换成-1024,这样就不影响使用了
7.2 按键支持学习10个,学习好的信息放在FS中,EEPROM放不下
7.3 空调按键有的是组合的(如开机+设定),目前只识别首个(开机指令)


打赏

参与人数 5家元 +103 收起 理由
a65071628 + 5 優秀文章
易记 + 18 優秀文章
hongo + 20 原創內容
10655188 + 10
writer15 + 50 優秀文章

查看全部打赏

发表于 2021-9-4 18:29:20 | 显示全部楼层
不错,能用上就好了。
回复 支持 反对

使用道具 举报

发表于 2021-9-4 20:04:17 | 显示全部楼层
做的不错,有时间改成涂鸦的试试:lol:
涂鸦现在免费送10个激活码。
回复 支持 反对

使用道具 举报

发表于 2021-9-4 21:19:14 来自手机浏览器 | 显示全部楼层
红米Note8都支持红外遥控了你居然小米8不支持?
回复 支持 反对

使用道具 举报

 楼主| 发表于 2021-9-4 22:06:50 | 显示全部楼层
触景情伤 发表于 2021-9-4 21:19
红米Note8都支持红外遥控了你居然小米8不支持?

小米8的确不支持
回复 支持 反对

使用道具 举报

发表于 2021-9-5 12:13:59 | 显示全部楼层
本帖最后由 易记 于 2021-9-5 12:17 编辑

可以直接刷在智能插座上面,让插座成为一个多功能插座,可以不用三极管,接一个100欧电阻后接单个红外发射管。

楼主再出个天猫精灵2812彩灯的呗
回复 支持 反对

使用道具 举报

 楼主| 发表于 2021-9-5 19:37:20 | 显示全部楼层
易记 发表于 2021-9-5 12:13
可以直接刷在智能插座上面,让插座成为一个多功能插座,可以不用三极管,接一个100欧电阻后接单个红外发射 ...

插座也有,控客mini pro就改了点灯的软件,带插座和红外遥控
不过玩的人比较少,就没发
回复 支持 反对

使用道具 举报

发表于 2021-9-7 15:41:54 | 显示全部楼层
会写代码的就是利害....:praise::praise::praise::praise:
回复 支持 1 反对 0

使用道具 举报

发表于 2022-3-16 17:09:06 | 显示全部楼层
想问下支持什么空调
回复 支持 反对

使用道具 举报

发表于 2022-3-16 17:11:03 | 显示全部楼层
想问下支持什么空调
回复 支持 反对

使用道具 举报

发表于 2022-4-6 17:22:15 | 显示全部楼层
只要是红外遥控的都可以支持吗?这个接头
回复 支持 反对

使用道具 举报

发表于 2024-4-29 22:12:24 | 显示全部楼层
易记 发表于 2021-9-5 12:13
可以直接刷在智能插座上面,让插座成为一个多功能插座,可以不用三极管,接一个100欧电阻后接单个红外发射 ...

你好
我从其他地方看评论说:不接S8050,发射距离非常近
不清楚你为何要去掉S8050?
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

APP|手机版|小黑屋|关于我们|联系我们|法律条款|技术知识分享平台

闽公网安备35020502000485号

闽ICP备2021002735号-2

GMT+8, 2024-5-16 06:59 , Processed in 0.124800 second(s), 11 queries , Redis On.

Powered by Discuz!

© 2006-2023 smzj.net

快速回复 返回顶部 返回列表