Manufaturação industrial
Internet das coisas industrial | Materiais industriais | Manutenção e reparo de equipamentos | Programação industrial |
home  MfgRobots >> Manufaturação industrial >  >> Manufacturing Technology >> Processo de manufatura

WiFi IR Blaster

Componentes e suprimentos

Espressif ESP8266 ESP-01
Você poderia fazer isso com um ESP8266 padrão ou com o kit de desenvolvimento NodeMCU
× 1
Arduino Nano R3
× 1
Transistor de uso geral NPN
× 1
LEDs IR Adafruit
× 1

Ferramentas e máquinas necessárias

Ferro de soldar (genérico)

Aplicativos e serviços online

Arduino IDE
Firmware NodeMCU

Sobre este projeto





Dois passos em frente ...


Parece que os principais fabricantes de telefones estão abandonando os blasters de infravermelho integrados, então estou procurando uma maneira de preparar meus dispositivos "burros" para o futuro que atualmente não se integram à minha infraestrutura de IoT. Tenho uma casa inteligente com rede mesh, mas preciso encontrar um controle remoto físico para ligar a TV? Tem que haver uma maneira melhor.

Recentemente, construí um IR blaster que controla condicionadores de ar autônomos em minha casa e outro projeto anterior foi uma ventilação HVAC conectada com um webapp conectado ao Android. Basicamente, tudo o que preciso fazer é combinar essas duas coisas em um blaster de infravermelho conectado à web com um front-end de webapp para que eu possa pressionar os botões do meu telefone e enviar os sinais de infravermelho aos meus centros de mídia. Eles podem ser implantados em todas as salas e controlados em qualquer lugar a partir de uma única interface, portanto, as aplicações para isso são extremamente amplas.





Prototipagem Rápida


Peguei alguns hardwares não usados ​​e conectei tudo de que precisava para me conectar ao meu WiFi, aceitar conexões HTTP e enviar sinais de infravermelho.

Isso funcionou muito bem, pois eu poderia solicitar uma URL específica no IP atribuído ao ESP8266 e fazer com que o Arduino emitisse um sinal de "Energia" para o LED IR. Eu só precisava descobrir onde hospedar o webapp, fazer com que enviassem os URLs para o blaster de IR e, em seguida, ter essas solicitações analisadas em códigos de IR específicos. Isso era muito tedioso de se fazer usando comandos AT com o ESP8266, e algo estava causando um atraso de 1 a 2 segundos entre o envio da solicitação e o piscar do LED.





NodeMCU


Eu fui em frente com a placa de desenvolvimento NodeMCU ESP8266 porque ela tem regulação de energia onboard, interface USB para serial e muitos pinos de E / S neste pequeno pacote (também é amigável para protoboard). Acontece que já existe uma biblioteca ESP8266 WebServer que aceita solicitações GET que fui capaz de adaptar para o envio de códigos IR e a biblioteca IRremote regular funciona fora da caixa.

O ESP8266 no NodeMCU não é poderoso o suficiente para hospedar o webapp em si, então irei executá-lo em um C.H.I.P. Computador de $ 9 que já está funcionando na minha rede doméstica. Outra limitação é que o ESP8266 é que ele é uma placa de 3,3 V, então os LEDs IR acionados diretamente de um pino de I / O eram muito escuros e tinham que estar próximos ao aparelho para o qual estava enviando o sinal. Em vez disso, usei o pino de E / S para acionar um transistor npn para ligar / desligar a tensão de alimentação de 5v.





REST ... ish


Depois de fazer algumas pesquisas, encontrei um ótimo tutorial para implementar uma API REST para Arduino para controlar LEDs em adafruit. Usei seus arquivos JavaScript e PHP para enviar as solicitações cURL e carreguei isso no CHIP que já está executando o apache, mas poderia facilmente ser hospedado na nuvem. Depois de criar uma página HTML básica para o controle remoto, adicionei os arquivos manifest.json e de ícone para que ele possa ser executado como um webapp nativo em um telefone Android.

No lado do Arduino, reduzi o servidor da Web para apenas aceitar uma solicitação GET, analisar a URL, enviar 200 OK e, em seguida, desconectar. Com base na URL, o Arduino enviaria o código IR que foi mapeado para o botão pressionado.





Remonster universal


Tudo está funcionando perfeitamente com atraso zero. Descobri que os LEDs de infravermelho que estou usando têm um ângulo muito estreito, então tenho que ter cuidado para que eles estejam apontados corretamente. Algum velcro industrial me permite montá-lo sob uma prateleira, fora da vista, e garante que ele fique apontado para os receptores de infravermelho na outra extremidade. Eu adicionei um fio de bitola grossa aos condutores de LED para que possam ser ajustados.

Ter resistores para os LEDs de infravermelho os tornava quase inutilizáveis, então o transistor os alimenta com 5v não regulados. Isso me permite lançar o infravermelho nas paredes e montar o blaster pela sala, mas com certeza terá um efeito na longevidade. Espero que, como eles são usados ​​com pouca frequência e os sinais de infravermelho são pulsos super curtos (ciclo de trabalho mais baixo do que a maioria dos sinais PWM escuros), não precisarei substituir os LEDs por algum tempo. Fiz questão de encomendar alguns LEDs IV de grande angular e saída mais alta para a versão 2, então, quando eles finalmente morrerem, vou substituí-los junto com um resistor em linha.





Atualização de 3 meses e recursos futuros


Eu uso isso todos os dias e tem funcionado perfeitamente. Eu até adicionei um segundo dispositivo em nossa sala de família para controlar nossa unidade de AC de janela e outra TV.

Planos para o futuro:
  • Migrar a IU da web para um serviço em nuvem
  • Integre com Amazon Echo para comandos de voz (Concluído)
  • A próxima iteração de hardware também terá um sensor de temperatura DHT22 e estou pesquisando maneiras de transmitir RF para meus ventiladores de teto
  • Adicione um receptor IR para um recurso de aprendizagem para que você possa "ensinar" os comandos do IR blaster a partir de controles remotos existentes
  • Integrar com minha automação residencial / segurança para desligar os aparelhos quando não estiverem em uso

Este pequeno IR blaster conectado está lentamente preenchendo a lacuna entre minha casa inteligente e os aparelhos antigos.

Código

  • WiFi IR Blaster para ESP8266 Arduino Sketch
  • script.js
  • index.html
  • curl.php
  • manifest.json
WiFi IR Blaster para ESP8266 Arduino Sketch C / C ++
Você precisará da biblioteca wi-fi ESP8266 e do IRremote.h. Você também deve optar por não usar os códigos RAW IR se o seu controle remoto for compatível com a biblioteca. Adaptei este esboço de um controlador de ar condicionado que construí que usava códigos IR não padrão.
 / * * WiFi IR Blaster de Buddy Crotty * Use um módulo ESP8266 ou placa de desenvolvimento para receber solicitação HTTP GET * e, em seguida, enviar códigos IR a um LED de infravermelho conectado com base nessas solicitações. * Isso funciona melhor com outro servidor da Web agindo como um front end que * envia solicitações cURL com base nos botões pressionados. * formato cURL:http:// ESP8266 / IRcode * / # include  #include  #include  const char * ssid ="AP_SSID"; const char * password ="AP_Pass "; MDNSResponder mdns; int khz =38; // Freqüência portadora de 38kHz para NEC e SamsungIRsend irsend (4); // um LED IR está conectado ao GPIO4 (pino D2 no NodeMCU) // Insira o sinal RAW IR para "TV Power" sem sinal int irTVpwr [] ={4650,4250, 700,1550, 650,1550, 700,1550, 650,450 , 650.500, 600.500, 600.500, 600.550, 550.1700, 550.1650, 600.1650, 550.550, 600.500, 600.550, 550.550, 600.500, 600.550, 550.1650, 600.550, 550.550, 600.500, 600.550, 550.550, 600.500, 600 , 1650, 600.500, 600,1650, 550,1700, 550,1650, 600,1650, 550,1650, 600,1650, 600}; // SAMSUNG E0E040BF // Insira o sinal RAW IR para "Fonte de TV" unsigned int irTVsrc [] ={4600,4300, 700,1550, 650,1550, 650,1600, 650.450, 650.450, 600.550, 550.550, 600.500, 600, 1650, 550,1650, 600,1650, 550.550, 600.500, 600.550, 550.550, 550.550, 600.1650, 550.550, 550.550, 600.500, 600.500, 600.550, 550.550, 600.500, 600.550, 550.1650, 550.1700, 550, 1650, 600,1600, 600,1650, 600,1600, 600,1650, 550}; // SAMSUNG E0E0807F // Insira o sinal RAW IR para "TV Mute" unsigned int irTVmute [] ={4650,4250, 700,1550, 650,1550, 700,1550, 650.450, 650.500, 600.500, 600.500, 600.500, 600, 1650, 600.1600, 600.1650, 550.550, 600.500, 600.550, 550.550, 600.500, 600.1650, 550.1650, 600.1650, 550.1650, 600.550, 550.550, 550.550, 600.500, 600.550, 550.550, 550.550, 600.500, 600,1650, 550,1650, 600,1650, 550,1650, 600}; // SAMSUNG E0E0F00F // Insira o sinal RAW IR para "Diminuir o volume da TV" unsigned int irTVvdn [] ={4650,4250, 700,1550, 650,1550, 700,1550, 650,450, 650,450, 650,450, 600,550, 550,550, 600 , 1650, 550,1650, 550,1650, 600.550, 550.550, 550.550, 600.500, 600.500, 600.1650, 600.1600, 600.500, 600.1650, 550.550, 600.500, 600.500, 600.550, 550.550, 600.500, 600.1650 , 550,550, 550,1650, 600,1650, 550,1650, 600,1650, 550}; // SAMSUNG E0E0D02F // Insira o sinal RAW IR para "Aumentar o volume da TV" unsigned int irTVvup [] ={4600,4300, 650,1600, 650,1550, 650,1600, 600.500, 600.550, 600.500, 600.550, 550.550, 550 , 1700, 550,1650, 600,1650, 550.550, 600.500, 600.550, 550.550, 600.500, 600.1650, 600.1650, 550.1650, 600.550, 550.550, 600.500, 600.550, 550.550, 600.500, 600.550, 550.550, 600 , 1600, 600,1650, 600,1650, 550,1650, 600,1650, 600}; // SAMSUNG E0E0E01F // Insira o sinal RAW IR para "TV Channel Up" unsigned int irTVchup [] ={4650,4250, 700,1550, 650,1600, 650,1550, 650.500, 600.500, 600.500, 650.500, 600.500, 600 , 1650, 550,1650, 600,1650, 600.500, 600.500, 600.550, 550.550, 600.550, 550.550, 550.1650, 600.550, 600.500, 600.1650, 550.550, 600.500, 600.550, 550.1650, 600.550, 550.1650 , 600,1650, 600,500, 600,1650, 600,1600, 600,1650, 600}; // SAMSUNG E0E048B7 // Insira o sinal RAW IR para "TV Channel Down" unsigned int irTVchdn [] ={4600,4350, 650,1550, 650,1600, 650,1600, 600,500, 600,500, 600,550, 550,550, 600,550, 550 , 1650, 600,1650, 550,1700, 550.550, 550.550, 600.500, 600.550, 550.550, 600.500, 600.550, 550.550, 550.550, 600.1650, 600.500, 600.500, 600.550, 550.1650, 600.1650, 600.1650 , 550,1650, 600,550, 550,1650, 600,1650, 600,1650, 550}; // SAMSUNG E0E008F7 // Insira o sinal RAW IR para "Receiver Power" unsigned int irRECpwr [] ={9050,4350, 650.500, 600.1600, 600.500, 650.500, 600.1600, 600.550, 600.1600, 600.1650, 550.550, 600.500, 600.1600, 650.1600, 600.500, 600.1650, 600.1600, 600.500, 600.1650, 600.1600, 600.550, 600.1600, 600.500, 600.550, 600.1600, 600.1600, 650.500, 600.500, 600.1600, 650.500, 600.1600, 600.1650, 600.500, 600.500, 600}; // NEC 4B36D32C // Insira o sinal RAW IR para "Receiver Power On" unsigned int irRECpwrON [] ={9000.4400, 600.550, 600.1600, 600.500, 600.550, 600.1600, 600.500, 600.1600, 650.1600 , 600.1600, 600.500, 650.1600, 600.1600, 600.500, 650.1600, 600.1600, 600.500, 600.550, 600.500, 600.1600, 600.550, 600.500, 600.500, 650.500, 600.500, 600.1600, 650 , 1600, 600.500, 600.1600, 650.1600, 600.1600, 600.1600, 600.1600, 650}; // NEC 4BB620DF // Insira o sinal RAW IR para "Receiver Power Off" unsigned int irRECpwrOFF [] ={9000,4400, 600,550, 550,1650, 600,550, 550,550, 600,1650, 550,550, 600,1650, 550,1650 , 600.550, 550.550, 550.1650, 600.1650, 600.550, 550.1650, 600.1650, 550.550, 600.1650, 550.1650, 600.1650, 600.500, 600.550, 550.550, 600.1650, 550.550, 600.500 , 600.550, 550.550, 550.1700, 550.1650, 600.1650, 550.550, 600.1650, 550}; // NEC 4B36E21D // Insira o sinal RAW IR para "Receptor Mudo" unsigned int irRECmute [] ={9000.4400, 650.450, 650.1600, 600.500, 600.500, 650.1600, 600.500, 600.1650, 600.1600, 600.1600, 650.500, 600.1600, 650.1600, 600.500, 600.1600, 650.1600, 600.500, 600.1650, 600.500, 600.1600, 650.500, 600.500, 600.500, 600.500, 650.500, 600.500, 600, 1600, 650,500, 600,1600, 600,1600, 650,1600, 600,1650, 600,1600, 600}; // NEC 4BB6A05F // Insira o sinal RAW IR para "Diminuição do volume do receptor" unsigned int irRECvdn [] ={9150,4250, 750,350, 700,1550, 700,400, 700,450, 650,1550, 700,450, 600,1600, 650,1600 , 600.1650, 600.500, 600.1650, 600.1600, 600.550, 600.1600, 600.1650, 600.500, 600.1650, 600.1600, 650.500, 600.500, 600.500, 650.500, 600.500, 600.500, 600.550, 600.500 , 600,1650, 600,1600, 600,1650, 600,1650, 600,1600, 600,1650, 600}; // NEC 4BB6C03F // Insira o sinal RAW IR para "Aumentar o volume do receptor" unsigned int irRECvup [] ={9050.4400, 650.500, 600.1600, 600.550, 600.500, 600.1650, 600.500, 600.1600, 650.1600 , 600.1600, 600.550, 600.1600, 600.1600, 650.500, 600.1600, 650.1600, 600.500, 600.550, 600.1600, 600.550, 600.500, 600.550, 600.500, 600.550, 600.500, 600.1600, 650.500 , 600.1600, 600.1650, 600.1600, 600.1650, 600.1600, 600.1600, 600}; // NEC 4BB640BF // Insira o sinal RAW IR para "Receiver Source CBL / SAT" unsigned int irRECsrc [] ={8950,4450, 600,500, 600,1650, 600,500, 600,500, 600,1650, 600,500, 600,1600, 600 , 1650, 600.1600, 600.550, 600.1600, 600.1650, 600.500, 600.1600, 600.1650, 600.500, 600.500, 600.1650, 600.1600, 600.1650, 600.500, 600.500, 600.500, 650.500 , 600.1600, 600.500, 600.550, 600.500, 600.1600, 600,1650, 600.1600, 600,1650, 600}; // NEC 4BB6708F // Cria uma instância do servidor // especifica a porta para escutar como um argumentWiFiServer server (80); void setup () {Serial.begin (115200); atraso (10); irsend.begin (); // Conectar à rede WiFi Serial.println (); Serial.println (); Serial.print ("Conectando a"); Serial.println (ssid); WiFi.begin (ssid, senha); enquanto (WiFi.status ()! =WL_CONNECTED) {atraso (500); Serial.print ("."); } Serial.println (""); Serial.println ("WiFi conectado"); // Inicie o servidor server.begin (); Serial.println ("Servidor HTTP iniciado"); // Imprime o endereço IP Serial.print ("Endereço IP:"); Serial.println (WiFi.localIP ()); if (mdns.begin ("IRBlasterLR", WiFi.localIP ())) {Serial.println ("MDNS Respondente iniciado"); } Serial.println (); Serial.println ();} void loop () {// Verifique se um cliente conectou WiFiClient client =server.available (); if (! cliente) {return; } // Espere até que o cliente envie alguns dados Serial.println ("novo cliente"); while (! client.available ()) {delay (1); } // Lê a primeira linha da solicitação String req =client.readStringUntil ('\ r'); Serial.println (req); client.flush (); // Corresponde à solicitação if (req.indexOf ("/ irTVpwr")! =-1) {irsend.sendRaw (irTVpwr, sizeof (irTVpwr) / sizeof (irTVpwr [0]), khz); Serial.println ("IRreq irTVpwr enviado"); } else if (req.indexOf ("/ irTVsrc")! =-1) {irsend.sendRaw (irTVsrc, sizeof (irTVsrc) / sizeof (irTVsrc [0]), khz); Serial.println ("IRreq irTVsrc enviado"); } else if (req.indexOf ("/ irTVmute")! =-1) {irsend.sendRaw (irTVmute, sizeof (irTVmute) / sizeof (irTVmute [0]), khz); Serial.println ("IRreq irTVmute enviado"); } else if (req.indexOf ("/ irTVvdn")! =-1) {irsend.sendRaw (irTVvdn, sizeof (irTVvdn) / sizeof (irTVvdn [0]), khz); Serial.println ("IRreq irTVvdn enviado"); } else if (req.indexOf ("/ irTVvup")! =-1) {irsend.sendRaw (irTVvup, sizeof (irTVvup) / sizeof (irTVvup [0]), khz); Serial.println ("IRreq irTVvup enviado"); } else if (req.indexOf ("/ irTVchup")! =-1) {irsend.sendRaw (irTVchup, sizeof (irTVchup) / sizeof (irTVchup [0]), khz); Serial.println ("IRreq irTVchup enviado"); } else if (req.indexOf ("/ irTVchdn")! =-1) {irsend.sendRaw (irTVchdn, sizeof (irTVchdn) / sizeof (irTVchdn [0]), khz); Serial.println ("IRreq irTVchdn enviado"); } else if (req.indexOf ("/ irALLpwr")! =-1) {irsend.sendRaw (irRECpwrON, sizeof (irRECpwrON) / sizeof (irRECpwrON [0]), khz); irsend.sendRaw (irTVpwr, sizeof (irTVpwr) / sizeof (irTVpwr [0]), khz); atraso (2000); irsend.sendRaw (irRECsrc, sizeof (irRECsrc) / sizeof (irRECsrc [0]), khz); Serial.println ("IRreq irALLpwr enviado"); } else if (req.indexOf ("/ irRECpwr")! =-1) {irsend.sendRaw (irRECpwr, sizeof (irRECpwr) / sizeof (irRECpwr [0]), khz); Serial.println ("IRreq irRECpwr enviado"); } else if (req.indexOf ("/ irRECpwrON")! =-1) {irsend.sendRaw (irRECpwrON, sizeof (irRECpwrON) / sizeof (irRECpwrON [0]), khz); Serial.println ("IRreq irRECpwrON enviado"); } else if (req.indexOf ("/ irRECpwrOFF")! =-1) {irsend.sendRaw (irRECpwrOFF, sizeof (irRECpwrOFF) / sizeof (irRECpwrOFF [0]), khz); Serial.println ("IRreq irRECpwrOFF enviado"); } else if (req.indexOf ("/ irRECmute")! =-1) {irsend.sendRaw (irRECmute, sizeof (irRECmute) / sizeof (irRECmute [0]), khz); Serial.println ("IRreq irRECmute enviado"); } else if (req.indexOf ("/ irRECvdn")! =-1) {irsend.sendRaw (irRECvdn, sizeof (irRECvdn) / sizeof (irRECvdn [0]), khz); Serial.println ("IRreq irRECvdn enviado"); } else if (req.indexOf ("/ irRECvup")! =-1) {irsend.sendRaw (irRECvup, sizeof (irRECvup) / sizeof (irRECvup [0]), khz); Serial.println ("IRreq irRECvup enviado"); } else {Serial.println ("solicitação inválida"); client.stop (); Retorna; } client.flush (); // Envia a resposta ao cliente //client.print(s); client.print ("HTTP / 1.1 200 OK \ r \ n"); atraso (1); Serial.println ("Cliente desconectado"); Serial.println (); // O cliente será realmente desconectado // quando a função retornar e o objeto 'cliente' for detroyed} 
script.js JavaScript
javascript para webapp (requer jquery)
 // Função para enviar comandos IR function buttonClick (clicked_id) {if (clicked_id =="irTVpwr") {$ .get ("curl.php", {room:"192.168.1.62" , botão:"irTVpwr"}); } if (clicked_id =="irTVsrc") {$ .get ("curl.php", {room:"192.168.1.62", botão:"irTVsrc"}); } if (clicked_id =="irTVmute") {$ .get ("curl.php", {room:"192.168.1.62", botão:"irTVmute"}); } if (clicked_id =="irTVvdn") {$ .get ("curl.php", {room:"192.168.1.62", botão:"irTVvdn"}); } if (clicked_id =="irTVvup") {$ .get ("curl.php", {room:"192.168.1.62", botão:"irTVvup"}); } if (clicked_id =="irTVchup") {$ .get ("curl.php", {room:"192.168.1.62", botão:"irTVchup"}); } if (clicked_id =="irTVchdn") {$ .get ("curl.php", {room:"192.168.1.62", botão:"irTVchdn"}); } if (clicked_id =="irRECpwr") {$ .get ("curl.php", {room:"192.168.1.62", botão:"irRECpwr"}); } if (clicked_id =="irALLpwr") {$ .get ("curl.php", {room:"192.168.1.62", botão:"irALLpwr"}); } if (clicked_id =="irRECpwrON") {$ .get ("curl.php", {room:"192.168.1.62", botão:"irRECpwrON"}); } if (clicked_id =="irRECpwrOFF") {$ .get ("curl.php", {room:"192.168.1.62", botão:"irRECpwrOFF"}); } if (clicked_id =="irRECmute") {$ .get ("curl.php", {room:"192.168.1.62", botão:"irRECmute"}); } if (clicked_id =="irRECvdn") {$ .get ("curl.php", {room:"192.168.1.62", botão:"irRECvdn"}); } if (clicked_id =="irRECvup") {$ .get ("curl.php", {room:"192.168.1.62", botão:"irRECvup"}); }} 
index.html HTML
HTML básico para exibir botões.
           



TV





Vol -        


Receptor





curl.php PHP
script php para enviar solicitações GET para ESP8266
  
manifest.json JSON
Isso permitirá que a página da web seja executada como um aplicativo da web nativo no Android.
 {"name":"WiFi Remote", "icons":[{"src":"remote_icon_36.png", "tamanhos":"36x36" , "tipo":"imagem / png", "densidade":0,75}, {"src":"remote_icon_48.png", "tamanhos":"48x48", "tipo":"imagem / png", "densidade" :1.0}, {"src":"remote_icon_128.png", "tamanhos":"128x128", "tipo":"imagem / png", "densidade":1.0}, {"src":"remote_icon_192.png" , "tamanhos":"192x192", "tipo":"imagem / png", "densidade":1,0}], "escopo":"/ remoto /", "url_inicial":"/remote/index.html", "display":"tela cheia", "orientação":"retrato"} 

Esquemas

Nada realmente incomodado, apenas energia e um único pino conectado a um transistor NPN para acionar dois LEDs IR em série (sem resistores) fora da tensão de alimentação de 5v. Se desejar executar LEDs adicionais ou precisar de menos queda de tensão de uma fonte de 3,3 V, você pode usar um NPN transistor para alternar vários transistores PNP (um por LED). Esta configuração permite que você use tantos LEDs quanto a tensão da fonte pode fornecer corrente.

Processo de manufatura

  1. As deficiências do WiFi RTLS
  2. Nova tecnologia sem fio 2015
  3. Como instalar um servidor da Web incorporado seguro em um dispositivo WiFi $ 3
  4. Comunicação MQTT entre NodeMCU e Raspberry Pi 3 B +
  5. ROBÔ WIFI RASPBERRY PI CONTROLADO PELO TELEFONE INTELIGENTE ANDROID
  6. Robô controlado por Wi-Fi usando Raspberry Pi
  7. O que é chamada WiFi? Como funciona?
  8. IOT - Jar inteligente usando ESP8266, Arduino e sensor ultrassônico
  9. Trava de porta inteligente usando página de login WiFi por Arduino e ESP8266
  10. O que é uma explosão de contas? Um guia para jateamento de esferas