A gestão do clima é barata e alegre (biblioteca IRremoteESP8266 e respiro Tion 02)

Encontrei uma maneira de fazer amizade com um ar condicionado (ou outro dispositivo controlado por um controle remoto) e uma casa inteligente, ou controlar esse dispositivo, por exemplo, a partir de um celular.
Em teoria, basta conectar o esp8266 (cerca de US $ 2 do chinês) ao LED infravermelho, preencher o firmware e pronto.


Na prática, acabou sendo um pouco mais complicado, porque minha revisão esp-01 teve que soldar (algo assim ) a fiação na perna de um microcircuito medindo 5 * 5mm, produzindo um GPIO adicional. Eu recomendo usar uma revisão mais antiga, por exemplo, o ESP-12.
Para leitores não familiarizados com esp8266, sugiro que você leia este artigo .

Componentes e Módulos


* Revisão Esp8266 esp-01
* FT232RL: Adaptador USB para Serial 232 TTL + fios para conexão
* Fotodetector Tsop 4838
* Regulador 3.3v
* Transistor S9014
* LED infravermelho 5013IRAB (comprimento de onda 940 nm)
* 330 ohm resistor
* Diretoria do Projeto
* Ferro de solda, solda, fluxo.
* Para o trabalho com RI, a notável biblioteca IRremoteESP8266 é usada . Autores Mark Szabo, Sebastien Warin, Ken Shirriff.

Salvando códigos


* Conecte o fotodetector , VCC a +3,3, GND a zero, OUT a GPIO.
* Abra um exemplo para despejar códigos da nossa biblioteca \ IRremoteESP8266 \ examples \ IRrecvDump \ IRrecvDump.ino
* Se necessário, altere o número do pino ao qual conectamos a OUT do fotodetector (linha “int RECV_PIN = 2;”).
* Preencha o firmware. Estamos conectados à saída do módulo. Como alternativa, mantenha pressionados os botões do controle remoto para obter os códigos de despejo.
Para o respirador Tion O2, recebi os seguintes códigos:
Para baixo
16711935
NEC decodificado: FF00FF (32 bits)
- até
16724175
NEC decodificado: FF30CF (32 bits)
- Definir
16722135
NEC decodificado: FF28D7 (32 bits)
- Potência
16720095
NEC decodificado: FF20DF (32 bits)


O fotodetector não é mais necessário até que você precise "pegar" o código de outro controle remoto.

Gerenciamento de dispositivos


* Conecte o LED IR de acordo com o esquema.

(Imagem emprestada de Fritzing)
GPIO pode ser usado diferente. A partir de uma tensão de 3,3v, o LED também funciona normalmente.
UPD: Como corretamente observado nos comentários, é aconselhável usar um resistor limitador de corrente .
* O firmware de demonstração com o servidor está aqui
\ IRremoteESP8266 \ examples \ IRServer \ IRServer.ino
* Altere o nome e a senha do seu ponto de acesso, para que o esp possa se conectar a ele. E também o número de GPIO usado
const char* ssid = ".....";
const char* password = ".....";
IRsend irsend(0);

* Módulo de firmware.
* Quando conectado ao console, o endereço IP alocado por esp será exibido.

Agora você pode enviar o código digitando no navegador um endereço no formato 192.168.1.1/ir?code=16720095 (basta substituir o IP e o código desejados).

Código de firmware de atualização aérea
 /* * IRremoteESP8266: IRServer - demonstrates sending IR codes controlled from a webserver * An IR LED must be connected to ESP8266 pin 0. * Version 0.1 June, 2015 */ #include <ESP8266WiFi.h> #include <WiFiClient.h> #include <ESP8266WebServer.h> #include <ESP8266mDNS.h> #include <IRremoteESP8266.h> const char* ssid = "FFFF"; const char* password = "XXXX"; unsigned long last_cmd_send_time = 0; MDNSResponder mdns; ESP8266WebServer server(80); const char* serverIndex = "<form method='POST' action='/update' enctype='multipart/form-data'><input type='file' name='update'><input type='submit' value='Update'></form>"; // IRsend irsend(2); IRsend irsend(13); void handleRoot() { server.send(200, "text/html", "<html><head> <title>ESP8266 Demo (Web Update)</title></head><body><h1>Hello from ESP8266, you can send NEC encoded IR signals from here!</h1><p><a href=\"ir?code=16769055\">Send 0xFFE01F</a></p><p><a href=\"ir?code=16429347\">Send 0xFAB123</a></p><p><a href=\"ir?code=16771222\">Send 0xFFE896</a></p></body></html>"); } void handleIr(){ for (uint8_t i=0; i<server.args(); i++){ if(server.argName(i) == "code") { unsigned long code = server.arg(i).toInt(); irsend.sendNEC(code, 32); } } handleRoot(); } void handleSeq(){ unsigned long code = 0; unsigned long cnt = 0; unsigned long dl = 0; unsigned long nwt = 0; for (uint8_t i=0; i<server.args(); i++){ if(server.argName(i) == "code") { code = server.arg(i).toInt(); } if(server.argName(i) == "count") { cnt = server.arg(i).toInt(); } if(server.argName(i) == "delay") { dl = server.arg(i).toInt(); } if(server.argName(i) == "need_wait") { nwt = server.arg(i).toInt(); } } if (nwt > 0){ unsigned long wt = millis() - last_cmd_send_time; if (wt < nwt && wt > 0) { delay(nwt - wt); } } if (code != 0) { for (uint8_t i=0; i<cnt; i++){ irsend.sendNEC(code, 32); delay(dl); } } last_cmd_send_time = millis(); handleRoot(); } void handleNotFound(){ String message = "File Not Found\n\n"; message += "URI: "; message += server.uri(); message += "\nMethod: "; message += (server.method() == HTTP_GET)?"GET":"POST"; message += "\nArguments: "; message += server.args(); message += "\n"; for (uint8_t i=0; i<server.args(); i++){ message += " " + server.argName(i) + ": " + server.arg(i) + "\n"; } server.send(404, "text/plain", message); } void setup(void){ irsend.begin(); Serial.begin(115200); WiFi.mode(WIFI_AP_STA); WiFi.begin(ssid, password); Serial.println(""); // Wait for connection while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); } Serial.println(""); Serial.print("Connected to "); Serial.println(ssid); Serial.print("IP address: "); Serial.println(WiFi.localIP()); if (mdns.begin("esp8266", WiFi.localIP())) { Serial.println("MDNS responder started"); } server.on("/", handleRoot); server.on("/ir", handleIr); server.on("/seq", handleSeq); server.on("/inline", [](){ server.send(200, "text/plain", "this works as well"); }); server.on("/update", HTTP_GET, [](){ server.sendHeader("Connection", "close"); server.sendHeader("Access-Control-Allow-Origin", "*"); server.send(200, "text/html", serverIndex); }); server.on("/update", HTTP_POST, [](){ server.sendHeader("Connection", "close"); server.sendHeader("Access-Control-Allow-Origin", "*"); server.send(200, "text/plain", (Update.hasError())?"FAIL":"OK"); ESP.restart(); },[](){ HTTPUpload& upload = server.upload(); if(upload.status == UPLOAD_FILE_START){ Serial.setDebugOutput(true); WiFiUDP::stopAll(); Serial.printf("Update: %s\n", upload.filename.c_str()); uint32_t maxSketchSpace = (ESP.getFreeSketchSpace() - 0x1000) & 0xFFFFF000; if(!Update.begin(maxSketchSpace)){//start with max available size Update.printError(Serial); } } else if(upload.status == UPLOAD_FILE_WRITE){ if(Update.write(upload.buf, upload.currentSize) != upload.currentSize){ Update.printError(Serial); } } else if(upload.status == UPLOAD_FILE_END){ if(Update.end(true)){ //true to set the size to the current progress Serial.printf("Update Success: %u\nRebooting...\n", upload.totalSize); } else { Update.printError(Serial); } Serial.setDebugOutput(false); } yield(); }); server.onNotFound(handleNotFound); server.begin(); Serial.println("HTTP server started"); } void loop(void){ server.handleClient(); } 



Eu criei esta página com a conveniência de gerenciar meu fôlego.
brizer.html
 <html> <head> <script> function sendIR(str) { if (str.length == 0) { // document.getElementById("txtHint").innerHTML = ""; return; } else { var xmlhttp = new XMLHttpRequest(); xmlhttp.onreadystatechange = function() { if (this.readyState == 4 && this.status == 200) { // document.getElementById("txtHint").innerHTML = this.responseText; } }; xmlhttp.open("GET", "http://192.168.0.193/" + str, true); xmlhttp.send(); } } </script> </head> <body> <div id="demo"> <button type="button" onclick="sendIR('ir?code=16724175')">Up</button> <button type="button" onclick="sendIR('ir?code=16711935')">Down</button> <button type="button" onclick="sendIR('ir?code=16722135')">Set</button> <button type="button" onclick="sendIR('ir?code=16720095')">Power</button> <button type="button" onclick="sendIR('seq?need_wait=11000&code=16722135&count=2&delay=20');sendIR('seq?code=16711935&count=50&delay=20');sendIR('seq?code=16724175&count=21&delay=20')">day</button> <button type="button" onclick="sendIR('seq?need_wait=11000&code=16722135&count=2&delay=20');sendIR('seq?code=16711935&count=50&delay=20');sendIR('seq?code=16724175&count=35&delay=20')">night</button> <a href="http://192.168.0.193/update">update</a> </div> </body> </html> 



Especificamente, no meu caso, o respirador trabalha com o controle remoto de maneira incomum, na primeira vez em que "acorda", liga a luz de fundo e somente depois disso começa a receber comandos. Quando a automação vale a pena considerar isso.

Espero que esta instrução seja útil para alguém. Por favor, compartilhe o firmware atualizado.

Source: https://habr.com/ru/post/pt401637/


All Articles