IResp — пульт IoT на ESP-01s + большая библиотека кодов пультов ДУ

Внешний вид передатчика IR сигналов на ESP-01SУстройство собрано из минимального количества деталей — ESP-01S, ключа на транзисторе, инфракрасного светодиода и стабилизатора напряжения +3,3v и нескольких резисторов. Позволяет управлять вашим телевизором или приставкой (STB) через интернет по принципу интернета вещей. Идея создать такое устройство появилось после получения достаточно огромной базы данных кодов для пультов к TV / STB (более 500 моделей).

схема подключения ESP-01s к инфракрасному светодиоду

Приведённый ниже скетч позволяет работать схеме в обоих направлениях — как передавать инфракрасные посылки, так и принимать их по пину GPIO0 (можно не устанавливать). В этом случае принятые коды будут выводить в UART на скорости 9600 бод. Для успешной компиляции скетча необходимо подключить стандартные библиотеки ESP8266WiFi и IRremoteESP8266.

#include <Arduino.h>
#include <assert.h>
#include <ESP8266WiFi.h>
#include <WiFiClient.h>
#include <ESP8266WebServer.h>
#include <ESP8266mDNS.h>
#include <IRremoteESP8266.h>
#include <IRrecv.h>
#include <IRsend.h>
#include <IRac.h>
#include <IRtext.h>
#include <IRutils.h>
#include <EEPROM.h>

#define ESSID eeprom_reads(0x10);
#define EPASS eeprom_reads(0x30);
// если нужен статический ip, то ставим 1 и ниже прописываем адреса
#define STATIC 0
IPAddress ip(192,168,1,177);
IPAddress gateway(192,168,1,1);
IPAddress subnet(255,255,255,0);

IRsend irsend(3);  // GPIO IR pin=3
IRrecv irrecv(0, 1024, 50, true); // IR sensor pin=0
decode_results results;

ESP8266WebServer server(80);
const int led = LED_BUILTIN;
const int btn = 0;

void handleRoot() {
  String ans="undefined";
  unsigned long cmd = 0x00000000;
  String proto = "";
  if(server.args() and server.argName(0)=="cmd"){
    cmd = str_to_long(server.arg(0));
    proto = server.argName(1);
    if(proto=="RC5"){
      irsend.sendRC5(cmd);
    }else if(proto=="SAMSUNG"){
      irsend.sendSAMSUNG(cmd);
    }else{ // NEC - default
      irsend.sendNEC(cmd);
    }
    server.send(200, "text/html", "OK");
  }else{
    proto = String(random(10000,99999));
    server.send(200, "text/html", "<html><head>"
    "<script src='https://conture.by/iresp/jquery.min.js'></script>"
    "<script src='https://conture.by/iresp/script.js?"+proto+"'></script>"
    "<link rel='stylesheet' href='https://conture.by/iresp/mdi/css/materialdesignicons.min.css' />"
    "<link type='text/css' rel='stylesheet' href='https://conture.by/iresp/styles.css?"+proto+"' />"
    "</head><body>"
    "...something went wrong"
    "</body>"
    "</html>\r\n");
  }
}

void handleNotFound() {
  String message = "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) {
  EEPROM.begin(512);
  Serial.begin(9600);
  char t=0;
  String essid = ESSID;
  String epass = EPASS;
  irsend.begin();
  pinMode(btn, INPUT);
  pinMode(led, OUTPUT);
  WiFi.mode(WIFI_STA);
  digitalWrite(led, HIGH); // led off
label1:
  if(EEPROM.read(0x0F)==1){
    WiFi.begin(essid, epass);
    if(STATIC)WiFi.config(ip, gateway, subnet);
    Serial.println("\nESSID: "+essid);
    Serial.println("EPASS: "+epass);
    goto label3;
  }
label2:
  WiFi.beginWPSConfig();
label3:
  while (WiFi.status() != WL_CONNECTED) {
    delay(200);
    Serial.print(".");
    digitalWrite(led, !digitalRead(led));
    if(t==60){
      t=0;
      goto label2;
    }
    t++;
  }
  digitalWrite(led, HIGH); // led off
  Serial.println("OK");
  if(EEPROM.read(0x0F)!=1 or WiFi.SSID()!=essid or WiFi.psk()!=epass){
    EEPROM.write(0x0F, 1); // признак того, что пароли сохранены
    eeprom_writes(0x10, WiFi.SSID());
    eeprom_writes(0x30, WiFi.psk());
    EEPROM.commit();
  }
  
  MDNS.begin("iresp");
  server.on("/", handleRoot);
  server.onNotFound(handleNotFound);
  server.begin();
  digitalWrite(led, LOW); // lef on

  assert(irutils::lowLevelSanityCheck() == 0);
  irrecv.setUnknownThreshold(12);
  irrecv.setTolerance(kTolerance);
  irrecv.enableIRIn();
  
}

void loop(void){
  server.handleClient();
  MDNS.update();
  if (irrecv.decode(&results)) {
    digitalWrite(led, HIGH);
    delay(10);
    Serial.println(resultToSourceCode(&results));
    digitalWrite(led, LOW);
  }  
}



unsigned long str_to_long(String str){
  unsigned long ansver = 0;
  for(byte n = 0; n < str.length(); n++){
    if((byte(str.charAt(n) ) >= 0x30) && (byte(str.charAt(n) ) <= 0x39)){//цифры ASCII 0 - 9
      ansver |= ((byte(str.charAt(n) )- 0x30));
    }
    if((byte(str.charAt(n) ) >= 0x41) && (byte(str.charAt(n) ) <= 0x46)){//символы ASCII A - F
      ansver |= ((byte(str.charAt(n) )- 0x41 + 10)); 
    }
    if((byte(str.charAt(n) ) >= 0x61) && (byte(str.charAt(n) ) <= 0x66)){//символы ASCII a - f
      ansver |= ((byte(str.charAt(n) )- 0x61 + 10)); 
    }
    if(n < (str.length() - 1) ){
      ansver = ansver << 4;
    }
  }
  return ansver;
}


void eeprom_writes(int addr, String s){
  int len = s.length();
  EEPROM.write(addr, len);
  for(int i=1; i<=len; i++){
    EEPROM.write(addr+i, s[i-1]);
  }
}

String eeprom_reads(int addr){
  String s = "";
  int len = EEPROM.read(addr);
  for (int i=1; i<=len; i++){
    s += char(EEPROM.read(addr+i));
  }
  return s;
}

Идея логики работы устройства следующая. После программирования ESP-01S и сборки по схеме выше, необходимо подключиться по WiFi к вашему роутеру. Для этого нажимаем кнопку WPS на роутере и включаем собранное устройство. Попытка подключения — светодиод на ESP будет мигать. При успешном подключении — будет гореть постоянно (процесс можно наблюдать и по UART). Данные для входа сохраняются в EEPROM, поэтому следующее подключение произойдёт автоматически.

После того, как успешно подключились к сети, определим адрес назначенный роутером нашей ESP. Для этого пинганём адрес службы mDNS с доменом «iresp».

ping

Теперь переходим по этому IP-адресу на телефоне или компьютере и вводим в строке название нашего пульта (например нам нужен пульт от MAG255)..

Screenshot_20220902-083159_Chrome   Screenshot_20220902-083222_Chrome   Screenshot_20220902-083232_Chrome   browser_ir

Так как памяти в ESP не так уж и много, а хотелось бы вместить всю базу данных пультов и сделать пульт по возможности красивым, то скрипты и БД залил на https://conture.by/iresp — откуда они и подкачиваются.

Корпус устройства для распечатки на 3д принтере в формате STL.

Запись опубликована в рубрике «Начинающим», C++, Автоматика, Программирование, Телевидение с метками , . Добавьте в закладки постоянную ссылку.

Добавить комментарий