Dies ist die dritte Variante des IP KVM-Themas. Dieses Mal wurde das Konzept vollständig überarbeitet. Beginnen wir mit dem Aufbau von etwas Neuem. Es wird viele interessante Dinge geben, den Bildschirm nicht verlassen. Ein weiteres ungewöhnliches Gerät wird erscheinen, wir werden fast alle alten Komponenten verwerfen, zu unserem nativen Arduino zurückkehren und einen kleinen Hacker spielen.
Für diejenigen, die gerade beigetreten sind, eine Zusammenfassung der vorherigen Folgen:
- Erster Artikel
IP-KVM auf Arduino und Raspberry Pi gesammelt, stellte sich als teuer und mit schlechter Videoqualität heraus. - Zweiter Artikel
OrangePI und Atmega16u2, billig gelernt, aber die Bildqualität ist immer noch widerlich.
Und schließlich werden in diesem Artikel alle Nachteile der vorherigen behoben. Besonderes Augenmerk wird auf die maximale Reduzierung der Komponentenkosten gelegt.
Traditionell betrachten wir die Komponenten des zusammengebauten Geräts:1. Unser alter Freund Atmega16u2:
Dies ist die einzige Komponente, die von früheren Artikeln verschoben wird.
2. Das berüchtigte ESP8266, in diesem Fall ESP8266-12e:
Sie können eine andere Version des ESP8266 verwenden, nur müssen Sie die Anzahl und Position der Ports berücksichtigen.
3. Und tatsächlich der Held des Anlasses LKV373A

Dank dieses Geräts wurde es möglich, Videos über ein lokales Netzwerk mit hoher Lautstärke zu übertragen
Auflösung bis zu Full-HD.
Der Aktionsplan lautet wie folgt:
- Verstecken: Wir suchen nach LKV373A, wo er sich im Netzwerk unter welcher IP-Adresse versteckt hat
- Hacker-Spiel: Geben Sie die Firmware ein, setzen Sie die Passwörter zurück und konfigurieren Sie LKV373A
- Neue Freunde finden: ESP8266, Arduino IDE und lustige Bilder
- Das Finale der Feier. Wir verbinden alle Komponenten und übertragen Tastenanschläge über Telnet
LKV373A Hintergrund
Also fangen wir an! LKV373A oder HDMI Extender-Gerät zum Aufnehmen von Bildern direkt vom HDMI-Port und zum Senden an das lokale Netzwerk. Diese Geräte werden auch als HDMI-Extender bezeichnet. Wie von den Herstellern geplant, sollte ein Satz solcher Geräte aus einem Sender (Sender) und einem Empfänger (Empfänger) mit der Bezeichnung TX bzw. RX bestehen. Sie sollten wahrscheinlich verwendet werden, um dem Hersteller mehr Gewinn zu bringen, nur paarweise. Aber es gab einen Mann unter dem Spitznamen Danman, hier ist ein
Link zu seinem Blog, der daran interessiert war, wie es funktioniert. Er öffnete Wireshark, schnüffelte den vom TX-Gerät übertragenen Verkehr. Was stellte sich heraus?
Der Videostream wird ohne Verschlüsselung übertragen. Mit dem VLC Player können Sie ihn ohne großen Aufwand ansehen. Aber er hörte hier nicht auf, "fühlte": Er zog das Webinterface, TTL, Telnet und sogar die Firmware mit dem Programmierer. Er sprach darüber ausführlich in seinem Blog. Dort wurde auch die Firmware hochgeladen, die uns an erster Stelle interessiert: IPTV_TX_PKG_v4_0_0_0_20160427.PKG. In dieser Firmware verfügt die Weboberfläche mit erweiterten Einstellungen und nicht wie die Standardeinstellung nur über die Schaltfläche "Aktualisieren". Darüber hinaus verfügt diese Firmware über ein Telnet mit vielen zu konfigurierenden Befehlen. Mit dieser Firmware konfigurieren wir den HDMI Extender für unsere Aufgaben neu. Ich habe die Firmware und alles, was ich brauchte, auf Github gepostet. Hier ist der
Link , wir werden ihn später brauchen, aber jetzt sind wir mit der Theorie fertig. Lass uns weiter üben.
Sender
Wir suchen nach LKV373A im Netzwerk
Ich fiel in die Hände desselben Extenders wie Danman (y). Alles, was unten beschrieben wird, ist speziell für den HDMI Extender LKV373A Version V3.0 geeignet!
Wir verbinden den LKV373A mit dem lokalen Netzwerk und schalten den Strom ein. Stellen wir nun sicher, dass das Gerät im
ping 192.168.1.238
Netzwerk sichtbar ist.
192.168.1.238 ist die Standard-IP-Adresse. Wenn der Extender die alte Firmware-Adresse nicht ändert, unabhängig davon, ob sich ein DHCP-Server im Netzwerk befindet oder nicht. Neuere Firmware-Versionen verwenden IP standardmäßig nur, wenn das Gerät keine Adresse von DHCP erhalten konnte. Wenn Sie eine Antwort auf Ping erhalten haben, fahren Sie fort. Wenn nicht, verzweifeln Sie nicht, versuchen Sie, den Extender direkt an den LAN-Port des Computers anzuschließen, und verwenden Sie den Sniffer.
Blinkt
HDMI Extender gefunden, fahren Sie mit der Firmware fort.
Gehen wir zum
Github und laden alles herunter, was dort ausgelegt ist. Öffnen Sie nun die Weboberfläche des Extenders über einen Browser und sehen Sie das folgende Bild:

Klicken Sie auf "Durchsuchen ...", wählen Sie die Firmware aus, eine Datei mit dem Namen IPTV_TX_PKG_v4_0_0_0_20160427.PKG, und klicken Sie auf "Upgrade". Tadam! Die Firmware ist fertig. Stellen Sie nun per Telnet eine Verbindung zum LKV373A her, um das Kennwort zurückzusetzen.
Der Befehl zum Verbinden sieht ungefähr so aus wie Telnet 192.168.1.238 9999, wobei 9999 der Port ist, zu dem eine Verbindung hergestellt werden soll. CEP warnt: Die von DHCP erhaltene Adresse kann mit einem Netzwerkscanner gefunden werden.
Verbindung über Telnet herstellen
Beim Herstellen der Verbindung sollte die folgende Meldung angezeigt werden:
============================== ========IPTV TX Server======== ============================== input>
Wir schreiben eine
list
. Als Antwort erhalten wir eine Liste von Befehlen:
============================== ========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
Verwenden Sie den Befehl
factory_reset
um alle Einstellungen und das Kennwort
factory_reset
. Wir schreiben einen Befehl, drücken die Eingabetaste und erhalten dieses Bild:
input>factory_reset Processing factory reset! System will reboot after few seconds! Connection closed by foreign host.
Webschnittstelle
Jetzt können wir das Gerät nach Bedarf konfigurieren. Gehen wir zum Webinterface. Wir verwenden das Standard-Login: Admin-Passwort: 123456 und hier ist das "begehrte" Webinterface mit zusätzlichen Einstellungen:

Die Möglichkeiten in der Weboberfläche haben zwar zugenommen, aber sie reichen für unsere Zwecke immer noch nicht aus. Besonders fehlen mehr kostenlose Einstellungen für das Streaming, es ist eine fest codierte Liste von IP-Adressen, an die Sie streamen können, bei weitem nicht die bequemste. Es gibt natürlich einen Multicast, aber es ist besser, ihn dem Fernsehen zu überlassen. Einschränkungen können umgangen werden, dazu später mehr.
Also fanden sie das Gerät im Netzwerk, rollten es zusammen und setzten die Passwörter zurück. Der Sender ist fast bereit, zum Empfänger überzugehen.
Empfänger
Entscheiden wir uns für das Gerät, unter dessen Steuerung wir den Stream übertragen. Ich glaube nicht, dass Sie die Qual der Wahl erleben werden, es gibt nur zwei Möglichkeiten:
Windows
Für Windows habe ich mehrere Player ausprobiert, aber die Ergebnisse waren mittelmäßig. Beim Aufnehmen und anschließenden Abspielen eines Videostreams wird eine Verzögerung angezeigt, die hauptsächlich vom Player abhängt, der den Stream abspielt. Bei verschiedenen Spielern lag die Verzögerung zwischen einer Sekunde und fünf oder mehr. Das Beste ist, dass sich VLC Player unter Windows bewährt hat.
Kommen wir zur Sache. Starten Sie VLC Player, wählen Sie oben im Dropdown-Menü "Medien" im Feld "Netzwerkadresse" die Option "URL öffnen ..." aus, schreiben Sie
udp://@:5004
, setzen Sie eine Dämmerung in das Kontrollkästchen "Erweiterte Einstellungen anzeigen" und geben Sie den Wert in das Feld "Caching" ein. Dieser Parameter wird individuell festgelegt. Je kleiner der Wert in diesem Feld ist, desto geringer ist die Verzögerung. Ein zu kleiner Wert kann jedoch zu „Artefakten“ und Bildausfällen führen. Alles hängt von der lokalen Netzwerkinfrastruktur ab. Die besten Ergebnisse, die ich erzielen konnte, waren eine Verzögerung von etwa einer Sekunde. Unter Linux waren die Ergebnisse um 200-300 Millisekunden viel besser.
Linux
Wie die Praxis zeigt, werden die besten Ergebnisse mit einer Kombination aus Socat- und Mplayer-Programmen erzielt. Ubuntu ist auf meinem Computer installiert, daher sieht der Befehl zum Installieren von socat folgendermaßen aus:
sudo apt-get install socat
Mplayer ist ähnlich installiert:
sudo apt-get install mplayer
Nun, und folge Danmans Rat:
sudo iptables -t raw -A PREROUTING -p udp -m length --length 28 -j DROP
Dieser Befehl wird benötigt, um die sogenannten "Zero Length UDP Packets" aus dem Stream zu entfernen - Pakete mit der Größe Null, die den Stream "verstopfen".
Geh live!
Der Empfänger ist bereit, Sie können die Sendung starten! Wir geben die Konsole des empfangenden Computers
ifconfig
oder
ipconfig
, je nach Betriebssystem,
ipconfig
uns die IP-Adresse des Empfängers und kehren zur Weboberfläche des Senders zurück. Wir öffnen die Weboberfläche. Wenn wir sie bereits geschlossen haben, geben Sie den Benutzernamen und das Kennwort ein und schreiben Sie direkt in die Adressleiste des Browsers:
http:
Ersetzen Sie Ihre IP-Adressen und drücken Sie die Eingabetaste. In dieser Zeile wird der HDMI-Extender so konfiguriert, dass das aufgenommene Video an die von Ihnen gewählte IP-Adresse gesendet und der Multicast ausgeschaltet wird.
Wir starten VLC in Windows. Oder im Linux-Terminal schreiben wir:
socat UDP-RECV:5004 - | mplayer –
Abra Cadabra! Und hier ist unser oder nicht unser Live-Desktop.

Mit ein paar Hacker-Methoden haben wir das Gerät gezwungen, das zu tun, was wir brauchten.
Gehen Sie nach der sortierten Videoübertragung zur Fernbedienung.
Kontrolle übertragen
Komponentenauswahl
Weil Die Kosten für HDMI Extender sind niedrig, etwa 1800 Rubel, und auch wegen der Kommentare, die, wie sie sagen, etwas teuer sind, habe ich den Slogan vorgebracht: "Geben Sie IP KVM für 2000 Rubel!". Der Rubel-Wechselkurs wird die Treue dieser Aussage stark beeinflussen, aber lassen Sie uns nicht über traurige Dinge sprechen, ich möchte an eine glänzende Zukunft glauben. Um das Ziel zu erreichen, brauchen wir sehr billige Elemente, meine Wahl fiel auf den ESP8266 als Controller und trotzdem Atmega (16.08.32) u2 als Aktuator.
Sie können natürlich auch andere Kandidaten für die Rolle eines Executive-Geräts (Tastatur) in Betracht ziehen. Die Firmware, die die Tastatur emuliert, wird in die LUFA-Bibliothek geschrieben. Diese Bibliothek kann für die gesamte AVR-Familie mit USB-Konnektivität verwendet werden. Daraus folgt, dass Sie als Tastaturemulator möglicherweise billigere Mikrocontroller erwerben können. Dies sind Informationen, die berücksichtigt werden müssen, aber jetzt fahren wir fort.
Sie können den ESP8266 für ungefähr 90 Rubel, Atmega (16.08.32) u2 für ungefähr 100 Rubel kaufen und sogar billiger, wenn Sie kleine Mengen von 5 oder mehr Stück aufnehmen. Natürlich werden Verbrauchsmaterialien zum Umreifen von Mikrocontrollern benötigt, aber ihre Kosten sind extrem gering, daher werde ich sie nicht berücksichtigen.
ESP8266
Dieses Wunder der chinesischen Industrie bedarf keiner Einführung, daher möchte ich nur sagen, dass ich in diesem Projekt die Version von ESP8266-12e verwendet habe. Natürlich können Sie auch andere Versionen verwenden, nur müssen Sie die Position der Ports berücksichtigen, weil In dieser Version wird einer der ESP8266-Ports zum Einschalten des Atmega (16.08.32) u2 verwendet. Dies wird in der folgenden Abbildung angezeigt.
Firmware
Die Firmware für ESP8266 ist in der ArduinoIDE-Umgebung geschrieben. Laden Sie daher die neueste Version von
der Entwicklerseite herunter. Als nächstes müssen Sie Unterstützung für ESP8266 hinzufügen - der einfachste Weg finden Sie unter diesem
Link . Auf derselben Seite finden Sie viele nützliche Informationen, wie z. B. den Stromanschluss und TTL. Für diejenigen, die nicht auf dem neuesten Stand sind, verwendet der ESP8266
streng 3,3 Volt! Wenn Sie sich in Ihren eigenen Fähigkeiten nicht sicher sind, ist es besser, eine für USB angepasste Board-Option wie NodeMCU zu verwenden:

Wenn alles fertig ist, öffne ArduinoIDE und kopiere meine Skizze:
Skizze #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); } } } } }
Verbinden Sie die gewünschte Bibliothek:
Wählen Sie die Registerkarte "Skizze" → "Bibliothek verbinden" → ".ZIP-Bibliothek hinzufügen". Wählen Sie die Bibliothek "UNO-HIDKeyboard-Library-master (mod) .zip" aus, die vom Github heruntergeladen wurde. Wir kompilieren und füllen die Firmware aus. Um die Firmware herunterzuladen, schließen Sie den ESP8266 TTL an und stellen Sie den gewünschten Port in ArduinoIDE ein. Die Einstellungen sollten ungefähr so aussehen:

Um die Firmware herunterzuladen, müssen Sie den GPIO0-Port gegen Masse kurzschließen und den Mikrocontroller neu starten, indem Sie den Reset-Port ebenfalls gegen Masse kurzschließen. Ich werde nicht im Detail malen, um den Artikel nicht aufzublasen, wird Google Ihnen helfen.
Die Logik des ESP8266 lautet wie folgt: Wenn Strom angelegt wird, versucht der Mikrocontroller etwa 30 Sekunden lang, eine Verbindung zu einem Wi-Fi-Zugangspunkt herzustellen:
Wenn die Verbindung erfolgreich ist :
Öffnet Port 23, mit dem Sie über Telnet eine Verbindung herstellen und Tastenanschläge übertragen können. Zusätzlich zu den Tasten können Sie Kombinationen übertragen, die auf "Strg + Taste" basieren und bestimmte Kombinationen drücken. Wenn Sie beispielsweise "Strg + d" übergeben, wird die Kombination STRG + ALT + ENTF auf dem verwalteten Computer gedrückt.
Es gibt auch Kombinationen zur Steuerung der ESP8266-Ports. Sie können beispielsweise ein Relais anschließen und das Relais mit der Kombination „Strg + q“ ein- und ausschalten, um den verwalteten Computer aus der Ferne ein- und auszuschalten. Sie können diese und andere Kombinationen in der Quelle sehen.
Wenn dies fehlschlug : ESP8266 wechselt in den Access Point-Modus mit dem Namen „TD“ und dem Kennwort „testtest“ und öffnet eine kleine Weboberfläche unter 192.168.4.1, in der Sie die Einstellungen für die Verbindung über WI-FI konfigurieren können.

Somit kann das Gerät leicht mit einem anderen Zugangspunkt verbunden werden. Ja, hier ist eine Fliege in der Salbe versteckt. Für den Betrieb unserer IP-KVM benötigen wir sowohl ein LAN-Kabel als auch WLAN. Dies sind die Kosten für die Billigkeit des Geräts.
Wir haben uns mit ESP8266 befasst, mit Atmega16u2 ist alles wie in den vorherigen Artikeln, wir flashen das Flip-Programm, die Firmware ist im Archiv, das vom Github heruntergeladen wurde.
Komponentenverbindung
Für den korrekten Anschluss der Komponenten bringe ich die Schaltung an. Denken Sie daran, dies ist ein bedingtes Schema, es dient der Klarheit und erhebt keinen Anspruch auf Ideal. Jeder kann sie nach Belieben "einrichten".

Lassen Sie mich einige Punkte erklären: Der Transistor in der Schaltung wird benötigt, um den Atmega16u2 nach dem Laden des ESP8266 einzuschalten, da beim Einschalten des ESP8266 Debug-Informationen an alle TX-Ports übertragen werden und wenn der Atmega16u2 eingeschaltet und mit dem Computer verbunden ist, ein Datenstrom mit dessen Volumen übertragen wird Der Fahrer kann nicht damit umgehen. Es ist nicht sicher bekannt, was in diesem Moment passiert, der Treiberpuffer läuft vermutlich über, der Effekt ist äußerst unangenehm: Hunderte von Tasten werden gedrückt, wenn ein Texteditor geöffnet wird, wird ein Haufen Kauderwelsch ausgegossen, und alle Servicetasten bleiben hängen, und infolgedessen wird das Arbeiten mit der Tastatur unmöglich . Um dies zu vermeiden, muss der Atmega16u2 nach dem Laden des ESP8266 eingeschaltet werden. In der Firmware wird dieser Moment berücksichtigt.
Natürlich gibt es eine Alternative zum Schema, aber dies ist eine Option für die Reichen oder die Faulen. Übrigens hebt diese Option das oben Gesagte nicht auf:

Auf dem Bild ist das Arduino UNO ohne Atmega328p-Chip mit dem chinesischen Gegenstück zu NodeMCU verbunden. Die 3,3-Volt-Leitung ist mit der Leitung mit dem gleichen Spannungspegel am Arduino sowie mit der Masse und dem GPIO2-Pin (ESP8266) mit dem TX-Pin am Arduino verbunden.
Endkontrolle
Wir verbinden uns per Telnet mit Port 23 und überprüfen die Leistung. Sie können dies tun: Unter Windows mit dem
telnet [ip- ESP8266]
Befehl
telnet [ip- ESP8266]
.
Unter Linux wird es etwas komplizierter:
Der
telnet [ip- ESP8266]
Befehl
telnet [ip- ESP8266]
dann müssen Sie das Steuerzeichen drücken, die Standardeinstellung ist "Strg +]", das Telnet sollte in den Befehlsmodus wechseln, dann "l" und "Enter" drücken. Mit diesen Aktionen schalten wir das Telnet in den Symbolmodus.
$ telnet 192.168.***.*** Trying 192.168.***.***... Connected to 192.168.***.***. Escape character is '^]'. ^] telnet> l
Alles ist fertig, wir können den Betrieb des von uns erstellten Geräts überprüfen. Ich möchte Sie an die möglichen Kombinationen für das Drücken von "Alt + Tab", "Strg + Alt + Entf" usw. erinnern. kann in der Skizze sehen. Das ist alles, die dritte KVM DIY IP-Inkarnation ist fertig.
Zusammenfassend
Vorteile:
- Das wahrscheinlich wichtigste Plus ist der Preis, der in 2000 Rubel passt
- Es sollte keine Beschwerden über die Qualität des Videos geben, Sie können problemlos auf Full HD streamen
- Die Möglichkeit, die Funktionalität durch Hinzufügen von bis zu vier Relais oder anderen Aktuatoren zu erweitern.
Nachteile:
- Sie müssen eine Verbindung über WLAN und LAN-Kabel herstellen
- Bei Verwendung mit VGA ist ein Adapter erforderlich, was sich natürlich auf die Kosten auswirkt
Im Allgemeinen erwies sich das Gerät als bemerkenswert, natürlich ist es kein Konkurrent zu seriellen IP-KVMs mit all ihren „Extras“, aber es gewinnt viel im Preis. Und für den Heimgebrauch, und vielleicht nicht nur, ist es durchaus geeignet.Ich möchte diese Gelegenheit nutzen, um dem Benutzer DaylightIsBurning zu danken ! Dieser freundliche Mann schlug die richtige Richtung für die Ausgrabung vor.Vielen Dank für Ihre Aufmerksamkeit. Bis bald!