Il s'agit de la troisième variation sur le thème IP KVM, cette fois le concept a été complètement révisé, commençons à construire quelque chose de nouveau. Il y aura beaucoup de choses intéressantes, ne quittez pas l'écran. Un autre appareil inhabituel apparaîtra, nous éliminerons presque tous les anciens composants, retournerons à notre arduino natif et jouerons un petit pirate.
Pour ceux qui viennent de rejoindre, un résumé des épisodes précédents:
- Premier article
Collecté IP KVM sur Arduino et Raspberry Pi, il s'est avéré coûteux et avec une mauvaise qualité vidéo. - Deuxième article
OrangePI et Atmega16u2, appris à moindre coût, mais la qualité d'image est toujours dégoûtante.
Et enfin, dans cet article, tous les inconvénients des précédents seront corrigés. Un accent particulier sera mis sur la réduction maximale du coût des composants.
Par tradition, nous considérons les composants du dispositif assemblé:1. Notre vieil ami Atmega16u2:
Il s'agit du seul composant qui passera des articles précédents.
2. Le fameux ESP8266, en l'occurrence ESP8266-12e:
Vous pouvez utiliser une autre version de l'ESP8266, il vous suffit de prendre en compte le nombre et l'emplacement des ports.
3. Et, en fait, le héros de l'occasion LKV373A

Grâce à cet appareil, il est devenu possible de transmettre de la vidéo sur un réseau local à haute
résolution jusqu'à full-HD.
Le plan d'action est le suivant:
- Cache-cache: Nous recherchons LKV373A où il s'est caché sur le réseau sous quelle adresse ip
- Jeu de piratage: remplissez le firmware, réinitialisez les mots de passe et configurez LKV373A
- Se faire de nouveaux amis: ESP8266, IDE Arduino et images amusantes
- La finale de la célébration. Nous connectons tous les composants et transmettons les touches via telnet
LKV373A Background
Commençons donc! LKV373A ou appareil HDMI Extender pour capturer des images directement à partir du port HDMI et les diffuser sur le réseau local, ces appareils sont également appelés extensions HDMI. Comme prévu par les fabricants, un ensemble de ces appareils devrait être composé d'un émetteur (émetteur) et d'un récepteur (récepteur), respectivement de la désignation TX et RX. Ils devraient être utilisés, probablement, afin d'apporter plus de bénéfices au fabricant, uniquement par paires. Mais il y avait un homme, sous le surnom de Danman, voici un
lien vers son blog, qui s'intéressait à son fonctionnement. Il a ouvert Wireshark, a reniflé le trafic transmis par l'appareil TX, qu'est-ce qui s'est avéré être?
Le flux vidéo est transmis sans aucun cryptage, et en utilisant VLC Player, vous pouvez le regarder sans trop d'effort. Mais il ne s'est pas arrêté là, "ressenti": il a tiré l'interface web, TTL, telnet, et même tiré le firmware avec le programmeur. Il en a parlé en détail sur son blog. Le firmware qui nous intéresse en premier lieu y a également été téléchargé: IPTV_TX_PKG_v4_0_0_0_20160427.PKG. Dans ce firmware, l'interface Web avec des paramètres avancés, et pas comme celle standard, n'a que le bouton de mise à jour. De plus, ce firmware a un telnet avec de nombreuses commandes à configurer. C'est avec ce firmware que nous reconfigurons le HDMI Extender pour nos tâches. J'ai posté le firmware et tout ce dont j'avais besoin sur github, voici le
lien , nous en aurons besoin plus tard, mais pour l'instant nous terminons avec la théorie. Passons à la pratique.
Émetteur
Nous recherchons LKV373A dans le réseau
Je suis tombé entre les mains du même répéteur que Danman (y). Tout ce qui sera décrit ci-dessous convient spécifiquement à la version HDMI Extender LKV373A V3.0!
Nous connectons le LKV373A au réseau local, allumez-le. Essayons maintenant de nous assurer que le périphérique est visible sur le réseau
ping 192.168.1.238
.
192.168.1.238 est l'adresse IP par défaut. Si le répéteur ne modifie pas l'ancienne adresse du micrologiciel, qu'il y ait ou non un serveur DHCP sur le réseau. Les versions plus récentes du micrologiciel utilisent IP par défaut uniquement si le périphérique n'a pas pu obtenir une adresse auprès de DHCP. Si vous avez reçu une réponse au ping, continuez. Sinon, ne désespérez pas, essayez de connecter le répéteur directement au port LAN de l'ordinateur et utilisez le renifleur.
Clignotant
Extender HDMI trouvé, passez au firmware.
Allons dans le
github et téléchargeons tout ce qui y est présenté. Ouvrez maintenant l'interface Web de l'extendeur via un navigateur et voyez l'image suivante:

Cliquez sur "Parcourir ...", sélectionnez le firmware, un fichier appelé IPTV_TX_PKG_v4_0_0_0_20160427.PKG, et cliquez sur "Mettre à niveau". Tadam! Le firmware est terminé, connectez-vous maintenant au LKV373A par telnet pour réinitialiser le mot de passe.
La commande de connexion ressemblera à Telnet 192.168.1.238 9999, où 9999 est le port auquel se connecter. CEP prévient: l'adresse obtenue de DHCP peut être trouvée à l'aide d'un scanner réseau.
Se connecter via telnet
Lors de la connexion, le message suivant doit apparaître:
============================== ========IPTV TX Server======== ============================== input>
Nous écrivons la
list
. En réponse, nous obtenons une liste de commandes:
============================== ========IPTV TX Server======== ============================== input>list set_group_id get_group_id set_dhcp get_dhcp set_uart_baudrate get_uart_baudrate set_static_ip get_static_ip set_mac_address get_mac_address get_lan_status get_hdcp get_video_lock get_ip_config set_session_key set_device_name get_device_name set_video_bitrate get_video_bitrate set_downscale_mode get_downscale_mode set_video_out_mode get_video_out_mode set_streaming_mode get_streaming_mode get_fw_version get_company_id factory_reset reboot list exit
Pour réinitialiser tous les paramètres et le mot de passe, utilisez la commande
factory_reset
. Nous écrivons une commande, appuyez sur Entrée et obtenez cette image:
input>factory_reset Processing factory reset! System will reboot after few seconds! Connection closed by foreign host.
Interface Web
Nous pouvons maintenant configurer l'appareil selon nos besoins. Passons à l'interface Web. Nous utilisons le login standard: mot de passe administrateur: 123456 et le voici, l'interface web "convoitée" avec des paramètres supplémentaires:

Bien que les opportunités dans l'interface Web aient augmenté, elles ne sont toujours pas suffisantes pour nos besoins. Il manque particulièrement des paramètres plus gratuits en termes de streaming, il est codé en dur, loin des plus pratiques, une liste d'adresses IP vers lesquelles vous pouvez diffuser. Il y a bien sûr une multidiffusion, mais il vaut mieux la laisser à la télévision. Les limitations peuvent être contournées, plus à ce sujet plus tard.
Ainsi, ils ont trouvé l'appareil sur le réseau, l'ont roulé, ont réinitialisé les mots de passe. L'émetteur est presque prêt à passer au récepteur.
Récepteur
Décidons de l'appareil sous le contrôle de quel système d'exploitation nous transmettrons le flux. Je ne pense pas que vous ferez l'expérience des affres du choix, il n'y a que deux options:
Windows
Pour Windows, j'ai essayé plusieurs lecteurs, mais les résultats étaient moyens. Lors de la capture puis de la lecture d'un flux vidéo, un délai apparaît, qui dépend principalement du lecteur lisant le flux. Sur divers joueurs, le retard variait d'une seconde à cinq ou plus. Surtout, sous Windows, VLC Player s'est avéré être.
Passons aux choses sérieuses. Lancez VLC Player, en haut du menu déroulant "Media", sélectionnez "Open URL ..." dans le champ d'adresse réseau, écrivez
udp://@:5004
, mettez un daw dans la case "Show advanced settings" et mettez sa valeur dans le champ "Caching", ce paramètre est déterminé individuellement. Plus la valeur dans ce champ est petite, plus le délai est faible, mais une valeur trop petite peut entraîner des «artefacts» et des pertes de trames, tout dépendra de l'infrastructure du réseau local. Les meilleurs résultats que j'ai pu obtenir ont été un retard d'environ une seconde. Sous Linux, les résultats étaient bien meilleurs autour de 200-300 millisecondes.
Linux
Comme le montre la pratique, les meilleurs résultats sont obtenus en utilisant une combinaison de programmes socat et mplayer. Ubuntu est installé sur mon ordinateur, donc la commande pour installer socat ressemblera à ceci:
sudo apt-get install socat
Mplayer est installé de la même manière:
sudo apt-get install mplayer
Eh bien, et suivez les conseils de Danman:
sudo iptables -t raw -A PREROUTING -p udp -m length --length 28 -j DROP
Cette commande est nécessaire pour supprimer les soi-disant «paquets UDP de longueur nulle» du flux - des paquets de taille nulle qui «obstruent» le flux.
Allez vivre!
Le récepteur est prêt, vous pouvez commencer la diffusion! Nous tapons dans la console de l'ordinateur récepteur
ifconfig
ou
ipconfig
, selon le système d'exploitation, nous nous souvenons de l'adresse IP du récepteur et revenons à l'interface web de l'émetteur. Nous ouvrirons l'interface Web, si nous l'avons déjà fermée, entrez le nom d'utilisateur, le mot de passe et écrivez directement dans la barre d'adresse du navigateur:
http:
Remplacez vos adresses IP et appuyez sur Entrée. Cette ligne configurera le HDMI Extender pour diffuser la vidéo capturée sur votre IP choisie et désactiver la multidiffusion.
Nous démarrons VLC dans Windows. Ou dans le terminal Linux, nous écrivons:
socat UDP-RECV:5004 - | mplayer –
Abra Cadabra! Et voici notre bureau en direct, ou pas le nôtre.

Donc, avec quelques méthodes de piratage, nous avons forcé l'appareil à faire ce dont nous avions besoin.
Une fois le transfert de la vidéo trié, accédez à la télécommande.
Transfert de contrôle
Sélection des composants
Parce que le coût de HDMI Extender est faible, environ 1800 roubles, et aussi à cause des commentaires qui, disent-ils, un peu chers, j'ai proposé le slogan: "Donnez IP KVM pour 2000 roubles!". Le taux de change du rouble affectera grandement la fidélité de cette déclaration, mais ne parlons pas de tristes choses, je veux croire en un avenir radieux. Pour atteindre l'objectif, nous aurons besoin d'éléments très bon marché, mon choix s'est porté sur l'ESP8266 en tant que contrôleur, et tout de même Atmega (8/16/32) u2 en tant qu'actionneur.
Vous pouvez bien sûr envisager d'autres candidats pour le rôle de dispositif exécutif (clavier). Le firmware qui émule le clavier est écrit dans la bibliothèque LUFA (en quelque sorte). Cette bibliothèque peut être utilisée pour toute la famille AVR avec une connectivité USB. Il s'ensuit qu'en tant qu'émulateur de clavier, vous pouvez vous procurer un microcontrôleur, peut-être moins cher. Ces informations sont à prendre en considération, mais nous continuons maintenant.
Vous pouvez acheter l'ESP8266 pour environ 90 roubles, Atmega (8/16/32) u2 pour environ 100 roubles, et encore moins cher si vous prenez en petits lots de 5 ou plus de pièces. Bien sûr, des consommables pour le cerclage des microcontrôleurs seront nécessaires, mais leur coût est extrêmement faible, donc je ne les considérerai pas.
ESP8266
Ce miracle de l'industrie chinoise n'a pas besoin d'être présenté, donc je dirai seulement que dans ce projet, j'ai utilisé la version d'ESP8266-12e. Bien sûr, vous pouvez utiliser d'autres versions, seulement vous devez considérer l'emplacement des ports, car dans cette version, un des ports ESP8266 est utilisé pour allumer l'Atmega (8/16/32) u2, il sera indiqué dans le schéma ci-dessous.
Firmware
Le firmware pour ESP8266 est écrit dans l'environnement ArduinoIDE, alors téléchargeons la dernière version sur
le site du développeur . Ensuite, vous devez ajouter le support pour ESP8266 - le moyen le plus simple peut être trouvé sur ce
lien . Sur la même page, vous pouvez trouver de nombreuses informations utiles, par exemple, le schéma de connexion d'alimentation et TTL. Pour ceux qui ne sont pas à jour, l'ESP8266 utilise
strictement 3,3 volts! Si vous n'avez pas confiance en vos propres capacités, il est préférable d'utiliser une option de carte adaptée pour USB, telle que NodeMCU:

Si tout est prêt, ouvrez ArduinoIDE et copiez mon croquis:
Esquisse #include <ESP8266WiFi.h> #include <WiFiClient.h> #include <ESP8266WebServer.h> #include <ESP8266mDNS.h> #include <SoftwareSerial.h> #include <HIDKeyboard.h> #define MAX_SRV_CLIENTS 3 HIDKeyboard keyboard; const char* host = "esp8266"; const char* ssid = ""; const char* pass = ""; int rebootdev = 0; int modeswitch = 0; // , ESP8266 #define Port1 15 #define Port2 14 #define Port3 12 #define Port4 4 #define Port5 5 // String ColorB1; String ColorB2; String ColorB3; String ColorB4; String ColorB5; ESP8266WebServer server(80); WiFiClient serverClients[MAX_SRV_CLIENTS]; const char* serverIndex = "<form method='POST' action='/update' enctype='multipart/form-data'><input type='file' name='update'><input type='submit' value='Update'></form><a href='/'>BACK</a>";//Update // void handleRedirect(){ String content = "<html><head><meta http-equiv='refresh' content='0;/'><head></html>"; server.send(200, "text/html", content); } // WI-FI void handleLogin(){ String msg = ""; if (server.hasArg("SSID") && server.hasArg("PASSAP")){ if ((server.arg("SSID") != NULL) && (server.arg("PASSAP") != NULL)){ String header = "HTTP/1.1 301 OK\r\r\nLocation: /\r\nCache-Control: no-cache\r\n\r\n"; server.sendContent(header); String web_ssid = server.arg("SSID"); String web_pass = server.arg("PASSAP"); ssid = web_ssid.c_str();// C pass = web_pass.c_str(); Serial.println(); Serial.print("SSID "); Serial.println(ssid); Serial.print("Pass "); Serial.println(pass); WiFi.begin(ssid, pass); digitalWrite(LED_BUILTIN, LOW); ESP.reset(); return; } msg = "Wrong ssid/password! try again."; Serial.println("Login Failed"); } String content = "<html><body><form action='/' method='POST'>Enter the access point name and password <br>";// SSID content += "Name AP:<input type='text' name='SSID' placeholder='SSID'><br>"; content += "Password:<input type='password' name='PASSAP' placeholder='password'><br><br>"; content += "<input type='submit' name='SUBMIT' value='Connect to WI-FI'></form><b><font color='red'>" + msg + "</font></b><br>"; content += "Firmware update <a href='/upload'>UPDATE</a></body></html>"; server.send(200, "text/html", content); } 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); } // int controlPin(int UsePin){ if (UsePin > 0){ int StPort; if (digitalRead(UsePin) == 1) {// digitalWrite(UsePin, LOW); StPort = 0; } else { digitalWrite(UsePin, HIGH); StPort = 1; } digitalWrite(LED_BUILTIN, HIGH);// Serial.print("Port "); Serial.print(UsePin); Serial.print("="); Serial.println(StPort); delay(500); digitalWrite(LED_BUILTIN, LOW); return(StPort); } return(-1); } // int clientConnect(int Seconds){ Serial.print("connection "); for (int i=0; i <= Seconds; i++){ WiFi.begin(ssid, pass); digitalWrite(LED_BUILTIN, LOW); delay(250); digitalWrite(LED_BUILTIN, HIGH); delay(250); Serial.print(" "); Serial.print("."); if (WiFi.status() == WL_CONNECTED) return(0); } return(1); Serial.println(); } void setup(void){ Serial.begin(115200); delay(1000); pinMode(LED_BUILTIN, OUTPUT); digitalWrite(LED_BUILTIN, HIGH); //uint8_t i = 0; if (modeswitch == 0) WiFi.mode(WIFI_STA);// modeswitch = 0 Serial.println(); Serial.println(); if (clientConnect(30) != 0) modeswitch = 1;// if (modeswitch == 1){ Serial.println(""); Serial.println("WiFi switch AP mode"); //WiFi.mode(WIFI_AP_STA); + . WiFi.mode(WIFI_AP); WiFi.softAP("TD", "testtest"); Serial.print("AP mode ip adress "); Serial.println(WiFi.softAPIP()); digitalWrite(LED_BUILTIN, LOW); } if (modeswitch != 1){ WiFiServer server(23); Serial.println(); Serial.print("Client mod ip address: "); Serial.println(WiFi.localIP()); digitalWrite(LED_BUILTIN, LOW); } MDNS.begin(host); pinMode(Port1, OUTPUT); pinMode(Port2, OUTPUT); pinMode(Port3, OUTPUT); pinMode(Port4, OUTPUT); pinMode(Port5, OUTPUT); if (modeswitch == 1){ // server.on("/", handleLogin);// (SSID) // server.on("/upload", HTTP_GET, [](){ server.sendHeader("Connection", "close"); server.send(200, "text/html", serverIndex); }); server.on("/update", HTTP_POST, [](){ server.sendHeader("Connection", "close"); int uperror = Update.hasError(); Serial.printf("UPERR %u\nRebooting...\n",Update.hasError()); if (uperror == 0) server.send(200, "text/html", "Firmware update successfully <a href='/'>BACK</a>"); else server.send(200, "text/html", "Update error <a href='/'>BACK</a>"); 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()); if (upload.filename == NULL) { Serial.printf("ERROR: zero file size"); server.send(200, "text/html", "<html> zero file size <a href='/upload'>BACK</a></html>"); return(-1); } 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.on("/PoRt1", [] { controlPin(Port1); handleRedirect();// }); server.on("/PoRt2", [] { controlPin(Port2); handleRedirect(); }); server.on("/PoRt3", [] { controlPin(Port3); handleRedirect(); }); server.on("/PoRt4", [] { controlPin(Port4); handleRedirect(); }); server.on("/PoRt5", [] { controlPin(Port5); handleRedirect(); }); server.on("/reboot", [] { rebootdev = 1;// handleRedirect(); }); server.onNotFound(handleNotFound);// //server.begin(); MDNS.addService("http", "tcp", 80); Serial.println(); Serial.println("HTTP server started"); } server.begin(); } void loop(void){ uint8_t i; if (modeswitch == 1) server.handleClient(); delay(100); if (modeswitch != 1){ if (WiFi.status() != WL_CONNECTED) clientConnect(30); else { digitalWrite(5, HIGH);// ATMEGA16U2 digitalWrite(LED_BUILTIN, LOW); } } WiFiServer server(23); server.setNoDelay(true); server.begin(); keyboard.begin(); while(WiFi.status() == WL_CONNECTED) { if (server.hasClient()){ for(i = 0; i < MAX_SRV_CLIENTS; i++){ //find free/disconnected spot if (!serverClients[i] || !serverClients[i].connected()){ if(serverClients[i]) serverClients[i].stop(); serverClients[i] = server.available(); Serial.println("New client: "); Serial.print(i); continue; } } //no free/disconnected spot so reject WiFiClient serverClient = server.available(); serverClient.stop(); } //check clients for data for(i = 0; i < MAX_SRV_CLIENTS; i++){ if (serverClients[i] && serverClients[i].connected()){ if(serverClients[i].available()){ //get data from the telnet client and push it to the UART String bufkey; while(serverClients[i].available()) bufkey += (serverClients[i].read());// if (bufkey != 0) { bufkey = bufkey.substring(0, 8);// int key = bufkey.toInt();// switch (key){ case 277980: keyboard.pressSpecialKey(F1); break; case 277981: keyboard.pressSpecialKey(F2); break; case 277982: keyboard.pressSpecialKey(F3); break; case 277983: keyboard.pressSpecialKey(F4); break; case 27914953: keyboard.pressSpecialKey(F5); break; case 27914955: keyboard.pressSpecialKey(F6); break; case 27914956: keyboard.pressSpecialKey(F7); break; case 27914957: keyboard.pressSpecialKey(F8); break; case 27915048: keyboard.pressSpecialKey(F9); break; case 27915049: keyboard.pressSpecialKey(F10); break; case 27915051: keyboard.pressSpecialKey(F11); break; case 27915052: keyboard.pressSpecialKey(F12); break; case 1310: keyboard.pressSpecialKey(ENTER); break; case 130: keyboard.pressSpecialKey(ENTER); break; case 27: keyboard.pressSpecialKey(ESCAPE); break; case 8: keyboard.pressSpecialKey(BACKSPACE); break; case 9: keyboard.pressSpecialKey(TAB); break; case 32: keyboard.pressSpecialKey(SPACEBAR); break; case 27915012: keyboard.pressSpecialKey(INSERT); break; case 27914912: keyboard.pressSpecialKey(HOME); break; case 27915312: keyboard.pressSpecialKey(PAGEUP); break; case 27915212: keyboard.pressSpecialKey(END); break; case 27915412: keyboard.pressSpecialKey(PAGEDOWN); break; case 279167: keyboard.pressSpecialKey(RIGHTARROW); break; case 279168: keyboard.pressSpecialKey(LEFTARROW); break; case 279166: keyboard.pressSpecialKey(DOWNARROW); break; case 279165: keyboard.pressSpecialKey(UPARROW); break; case 127: keyboard.pressSpecialKey(DELETE); break; case 27915112: keyboard.pressSpecialKey(DELETE); break; case 4: keyboard.pressSpecialKey((LCTRL | ALT), DELETE); break; //CTRL+ALT+DELETE Ctrl + d case 6: keyboard.pressSpecialKey(ALT, F4); break; //alt+f4 Ctrl + f case 19: keyboard.pressSpecialKey(ALT | SHIFT); break;// Ctrl+s case 2: keyboard.pressSpecialKey(LCTRL | SHIFT); break;// Ctrl+b // case 17: controlPin(Port1); break;//Ctrl+q case 23: controlPin(Port2); break;//Ctrl+w case 5: controlPin(Port3); break;//Ctrl+e case 18: controlPin(Port4); break;//Ctrl+r case 20: controlPin(Port5); break;//Ctrl+t default: keyboard.pressKey(key); break;// } keyboard.releaseKey();// Serial.print(" string: "); Serial.print(key);// Serial.print(" KEY: "); Serial.write(bufkey.toInt()); bufkey = '0';// } } } } //check UART for data if(Serial.available()){ size_t len = Serial.available(); uint8_t sbuf[len]; Serial.readBytes(sbuf, len); //push UART data to all connected telnet clients for(i = 0; i < MAX_SRV_CLIENTS; i++){ if (serverClients[i] && serverClients[i].connected()){ serverClients[i].write(sbuf, len); delay(1); } } } } }
Connectez la bibliothèque souhaitée:
Sélectionnez l'onglet "Esquisse" → "Connecter la bibliothèque" → "Ajouter une bibliothèque .ZIP". Sélectionnez la bibliothèque appelée "UNO-HIDKeyboard-Library-master (mod) .zip", qui a été téléchargée à partir du github. Nous compilons et remplissons le firmware. Pour télécharger le firmware, connectez l'ESP8266 TTL, définissez le port souhaité dans ArduinoIDE. Les paramètres doivent ressembler à ceci:

Pour télécharger le firmware, vous devez court-circuiter le port GPIO0 à la terre et redémarrer le microcontrôleur en court-circuitant également le port de réinitialisation à la terre. Je ne peindrai pas en détail, afin de ne pas gonfler l'article, Google vous aidera.
La logique de l'ESP8266 est la suivante: à la mise sous tension, le microcontrôleur tente de se connecter à un point d'accès Wi-Fi pendant une trentaine de secondes:
Si la connexion réussit : ouvre le port 23, qui peut être connecté à l'aide de telnet et transmettre les frappes. En plus des touches, vous pouvez transférer des combinaisons basées sur "Ctrl + touche" qui appuieront sur certaines combinaisons. Par exemple, si vous passez «Ctrl + d», la combinaison CTRL + ALT + SUPPR sera enfoncée sur l'ordinateur géré.
Il existe également des combinaisons pour contrôler les ports ESP8266, par exemple, vous pouvez connecter un relais et utiliser la combinaison «Ctrl + q» pour activer et désactiver le relais, allumant et éteignant ainsi l'ordinateur géré à distance. Vous pouvez voir ces combinaisons et d'autres dans la source.
En cas d'échec : ESP8266 passe en mode point d'accès avec le nom «TD», mot de passe «testtest» et ouvre une petite interface Web, accessible à 192.168.4.1, où vous pouvez configurer les paramètres de connexion via WI-FI.

Ainsi, l'appareil peut être facilement connecté à un autre point d'accès. Oui, une mouche dans la pommade est cachée ici, pour le fonctionnement de notre IP KVM, nous aurons besoin à la fois d'un câble LAN et d'une connexion Wi-Fi. Tel sera le coût du bon marché de l'appareil.
Nous avons traité ESP8266, avec Atmega16u2 tout est comme dans les articles précédents, nous flasherons le programme Flip, le firmware est dans l'archive téléchargée depuis le github.
Connexion des composants
Pour la bonne connexion des composants, j'attache le circuit. Gardez à l'esprit qu'il s'agit d'un schéma conditionnel, il sert à la clarté et ne prétend pas être idéal. Chacun est libre de la «meubler» à sa guise.

Permettez-moi d'expliquer certains points: le transistor dans le diagramme est nécessaire pour activer Atmega16u2 après le chargement de l'ESP8266, car lorsque vous allumez l'ESP8266, les informations de débogage sont transmises à tous les ports TX, et si l'Atmega16u2 est allumé et connecté à l'ordinateur, un flux de données dont le volume est transmis le conducteur ne peut pas faire face. On ne sait pas avec certitude ce qui se passe en ce moment, le tampon du pilote est probablement débordant, l'effet est extrêmement désagréable: des centaines de touches sont enfoncées, si un éditeur de texte est ouvert, il déverse un tas de charabia, et toutes les touches de service se bloquent et, par conséquent, travailler avec le clavier devient impossible . Pour éviter cela, l'Atmega16u2 doit être mis sous tension après le chargement de l'ESP8266. Dans le firmware, ce moment est pris en compte.
Il y a bien sûr une alternative au schéma, mais c'est une option pour les riches ou les paresseux. Et au fait, cette option n'annule pas ce qui précède:

Dans l'image, l'Arduino UNO sans la puce Atmega328p est connecté à l'homologue chinois de NodeMCU. La ligne 3,3 volts est connectée à la ligne du même niveau de tension sur l'Arduino, et la masse et la broche GPIO2 (ESP8266) sont également connectées à la broche TX sur l'Arduino.
Contrôle final
Nous nous connectons par telnet au port 23 et vérifions les performances. Vous pouvez le faire: sous Windows avec la commande
telnet [ip- ESP8266]
.
Sous Linux, ce sera un peu plus compliqué:
La commande
telnet [ip- ESP8266]
puis vous devez appuyer sur le caractère de contrôle, la valeur par défaut est "Ctrl +]", le telnet devrait passer en mode commande, puis appuyez sur "l" et "Entrée". Avec ces actions, nous basculerons le telnet en mode symbole.
$ telnet 192.168.***.*** Trying 192.168.***.***... Connected to 192.168.***.***. Escape character is '^]'. ^] telnet> l
Tout est prêt, nous pouvons vérifier le fonctionnement de l'appareil que nous avons créé. Permettez-moi de vous rappeler les combinaisons possibles pour appuyer sur "Alt + Tab", "Ctrl + Alt + Suppr" et etc. peut voir dans l'esquisse. C'est tout, la troisième incarnation IP KVM DIY est prête.
Pour résumer
Avantages:
- Le plus probablement le plus important est le prix, il s'est avéré qu'il pouvait tenir en 2000 roubles
- Il ne devrait y avoir aucune plainte concernant la qualité de la vidéo, vous pouvez diffuser en Full HD sans problème
- La possibilité d'étendre les fonctionnalités en ajoutant jusqu'à quatre relais ou autres actionneurs.
Inconvénients:
- Besoin de se connecter via Wi-Fi et câble LAN
- Lorsqu'il est utilisé avec VGA, un adaptateur est requis, ce qui affectera naturellement le coût
En général, l'appareil s'est avéré digne d'attention, bien sûr, il n'est pas un concurrent des KVM IP série avec tous leurs «goodies», mais il gagne beaucoup en prix. Et pour un usage domestique, et peut-être pas seulement, il convient parfaitement.Je profite de cette occasion pour remercier l'utilisateur DaylightIsBurning ! Cet homme gentil a suggéré la bonne direction dans laquelle creuser.Merci de votre attention. A très bientôt!