Computersteuerung ĂŒber Fernbedienung von einem VerstĂ€rker mit Arduino und Node.js.

Vorwort


Die Geschichte beginnt mit der Tatsache, dass ich vor einem halben Jahr einen Yamaha A-S501 VerstÀrker gekauft habe.


Yamaha A-S501


Im Lieferumfang war eine Fernbedienung enthalten, mit der sowohl der VerstĂ€rker als auch der Yamaha-CD-Player gesteuert werden konnten, die ich natĂŒrlich nicht hatte. Daher wurden die meisten Tasten auf der Fernbedienung einfach nicht verwendet. Und im Allgemeinen war die Konsole selbst nicht notwendig und lag immer auf einem Regal.


Als ich ihn jedoch ansah, wurde ich von der Idee verfolgt, die Fernbedienung in vollen ZĂŒgen zu nutzen. Zum Beispiel wĂ€re es bequem, sich auf das Sofa zu legen und einen Film anzusehen, mit einer schnellen Handbewegung zurĂŒckzuspulen, ihn anzuhalten usw. Zu diesen Zwecken habe ich natĂŒrlich Anwendungen auf meinem Smartphone verwendet, um die Programme MPC-HC, Foobar2000 zu steuern, aber die Fernbedienung wĂ€re schneller und bequemer.


Wie sie sagen, haben die Augen Angst und die HĂ€nde tun es. Mit der Wahl der Technologie war sofort alles klar. Arduino - Ich wollte schon lange mit ihr spielen, und das ist einfach eine große Chance. FĂŒr den Button-Handler Node.js, weil Ich habe mich auf Javascript spezialisiert und wollte den Kontext nicht wechseln.


Und so, lass uns gehen ...


Fertige Lösungen


Eines der vorhandenen Analoga, die ich finden konnte, ist Flirc . Mit ihm können Sie TastenanschlÀge auf der physischen Tastatur eines Computers emulieren.



Ein solcher InfrarotempfĂ€nger kostet 100 Zloty (28 US-Dollar). Mit Blick auf die Zukunft ist es doppelt so teuer wie das, was ich bekommen habe. DarĂŒber hinaus fiel es in Bezug auf die FunktionalitĂ€t (subjektiv) noch besser aus.


Teile kaufen



Ich brauchte:


  • Eigentlich das Arduino Uno Board selbst. Es ist erwĂ€hnenswert, dass dies nicht das ursprĂŒngliche Board ist, sondern eine Art polnischer Klon. Laut Beschreibung ist es dem Original völlig Ă€hnlich. (27,90 zƂ)
  • InfrarotempfĂ€nger VS1838B HX1838 (Spannung: 3,3–5 V, Frequenz: 38 kHz, Winkel: 90 °) (1,30 zƂ)
  • Prototyping Board + DrĂ€hte (13,90 zƂ)
  • Eine leere Platine zum Löten (2.10 zƂ)
  • AnschlĂŒsse zum Anschließen von Platinen (2,51 zƂ)

Gesamt: 47,71 zƂ (≈ 14 USD)


Software


WĂ€hrend ich auf die Lieferung wartete, begann ich, einen „Treiber“ zu schreiben, der Daten von der seriellen Schnittstelle von Arduino lesen und bestimmte Aktionen fĂŒr die gedrĂŒckte Taste auf der Fernbedienung ausfĂŒhren sollte.


Die Idee war, alles und jeden anpassen zu können. Jeder Taste auf der Fernbedienung können bestimmte Aktionen verschiedener Typen zugewiesen werden:


  • Emulation eines Tastenanschlags auf einer Tastatur (ĂŒber Node-Key-Sender ):

{ "key": "space" } 

  • AusfĂŒhren eines beliebigen Programms mit Parametern:

 { "exec": ["c:\\Program Files (x86)\\foobar2000\\foobar2000.exe", "/play"] } 


 { "if": { "running": "mpc-hc.exe" }, "then": [ ... ], "else": [ ... ] } 

Jeder Typ hat einen eigenen Handler, der dieselbe API hat. Daher war es möglich, alles zu einer einfachen Schleife zusammenzufassen, die alle Handler nacheinander startet.


 const runHandlers = require('./handlers') module.exports = async function run(actions) { if (!Array.isArray(actions)) { actions = [actions] } for (const act of actions) { await runHandlers(act) } } 

Anstelle von tausend Dokumentationswörtern sagen Tests alles:


 run when "exec" action √ executes the specified file without args (as array) (4ms) √ executes the specified file without args (as string) (1ms) √ executes the specified file with args √ rejects if "exec" has wrong type (5ms) when "key" action √ sends the specified key press if passed string (1ms) √ sends the specified key combination if passed array √ rejects if "key" has wrong type (1ms) when "if" action √ rejects if no "then" (1ms) √ rejects if operator is not supported when operator if "running" √ runs "then" actions if the condition is true (1ms) √ runs "else" actions if the condition is false √ does not run anything if the condition is false and no "else" statement (1ms) when multiple actions √ executes all actions (1ms) when multiple actions are mixed into one √ runs only first one alphabetically 

Es bleibt auf die geschÀtzten Details zu warten.


Eisen


Ich gebe zu, ich habe nichts Neues erfunden, alles wurde bereits vor mir getan. Ich habe gerade das vorgefertigte Diagramm aus dem Artikel Einrichten einer IR-Fernbedienung und eines IR-EmpfÀngers auf einem Arduino verwendet .


Das Schema ist ganz einfach:



In der Praxis:




Firmware


Ich habe die Firmware auch ehrlich aus dem Artikel ausgeliehen , fĂŒr ihre Arbeit benötige ich die IRremote Arduino Library .


Ich habe die Tastencodes durch die tatsÀchlichen auf meiner Fernbedienung ersetzt:


 void loop() { if (irrecv.decode(&results)) { if (results.value == 0xFFFFFFFF) { results.value = key_value; } switch (results.value) { case 0x9E6140BF: Serial.println("play"); break; case 0x9E61AA55: Serial.println("pause"); break; /* ...*/ case 0x5EA1A857: Serial.println("cd"); break; default: Serial.println(results.value, HEX); break; } key_value = results.value; irrecv.resume(); } } 


Sobald die Namen der gedrĂŒckten Tasten im Port Monitor-Fenster der Arduino IDE angezeigt wurden, musste dem Treiber eine Komponente fĂŒr die Arbeit mit der seriellen Schnittstelle hinzugefĂŒgt werden.


Das Ergebnis war ein Wrapper ĂŒber die Serialport- Bibliothek und tatsĂ€chlich den Datenstrom vom Port:


 const SerialPort = require('serialport') module.exports = class SerialPortReader { constructor(port) { const serialPort = new SerialPort(port) this.lineStream = serialPort.pipe(new SerialPort.parsers.Readline()) } start(handler) { this.lineStream.on('readable', () => { const data = this.lineStream.read().trim() handler(data) }) } } 

SpĂ€ter mussten die Handler in eine "Entprellungs" -Funktion umgewandelt werden, da die Fernbedienung ein sich schnell wiederholendes Signal empfĂ€ngt, das selbst bei kurzem DrĂŒcken der Taste mehrmals ausgelöst werden kann. Das Entfernen einer solchen Option fĂŒr alle SchaltflĂ€chen ist jedoch auch fĂŒr die LautstĂ€rke nicht ganz angemessen.


Der endgĂŒltige Code sieht folgendermaßen aus:


 const debounce = require('debounce') const settings = require('./lib/settings') const run = require('./lib/run') const SerialPortReader = require('./lib/SerialPortReader') const simpleHandle = async button => { const actions = settings.mappings[button] if (!actions) { console.warn(`Action not found for remote control button "${button}"`) return } try { await run(actions) } catch (e) { console.error(e.message) process.exit(1) } } const debouncedHandle = debounce(simpleHandle, settings.debounceDelay, true) const callHandleFn = button => { return (settings.noDebounce.includes(button) ? simpleHandle : debouncedHandle)(button) } const reader = new SerialPortReader(settings.serialPort) reader.start(callHandleFn) 

Schaffung eines unabhÀngigen Vorstands


Nachdem ich sichergestellt hatte, dass der Prototyp funktioniert, erstellte ich ein Board. Es ist erwĂ€hnenswert, dass dies fĂŒr mich die erste Erfahrung in solchen Angelegenheiten ist. Ich hatte keinen geeigneten Lötkolben mit einer kleinen Nadel - nur den alten großen sowjetischen mit einem dichten Draht.


Mit halbem Kummer gelang es mir, die "Beine" zu löten (von den beiden großen Verbindern mit 8 Stiften ĂŒberlebten nur 2 Stifte). Alles andere war einfacher.



(Krumm. Höchstwahrscheinlich aufgrund des Arduino-Klons. Die Nester sind relativ zueinander ungleichmĂ€ĂŸig.)



Ich habe den InfrarotempfĂ€nger absichtlich zwischen die Platinen gelegt. So passt das GerĂ€t problemlos unter den VerstĂ€rker. Ich beschloss, die Spuren zu machen, indem ich die Löcher auf dem Brett mit Zinn verband, anstatt sie mit DrĂ€hten zu verbinden. Und schließlich habe ich das Band aufgeklebt, damit sich die Platine nicht am MetallgehĂ€use des VerstĂ€rkers schließt.




Als Ergebnis: ein voll funktionsfĂ€higes GerĂ€t und eine Software fĂŒr 14 US-Dollar. Die gesammelten Erfahrungen und die Freude an der geleisteten Arbeit und das Ergebnis sind von unschĂ€tzbarem Wert! :-)


Vielen Dank fĂŒr Ihre Aufmerksamkeit!




Demo:



Quellen bei Github .




PS Danke ramanchik 'u fĂŒr die Beratung :)

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


All Articles