Category: arduino

Arduino als Tastaturcontroller verwenden

30.01.2014 yahe arduino hardware legacy

Manchmal dauert es eine ganze Weile, bis man die richtige Idee für die Lösung eines Problems hat, in diesem Fall habe ich für die richtige Idee fast ein halbes Jahr gebraucht. Und zwar ging es darum, wie ich es hinbekommen könne, das Tastaturfeld einer gekauften Tastatur mit einem Arduino zu verbinden. Hierzu hatte ich im letzten Jahr mehrere Tastaturen auseinander genommen, nur um herauszufinden, dass diese immer eine Tastaturmatrix aus Plastik enthielten, ein Material, mit dem man als Privatperson kaum praktisch arbeiten kann.

Doch manchmal sieht man den Wald vor lauter Bäumen nicht. Es gibt Tastaturen, mit denen man nicht solche großen Probleme hat. Gemeint sind mechanische Tastaturen, wie die Cherry G80-3000. Diese ist mit normalen, mechanischen Tasten versehen, die auf eine Platine gelötet sind. Damit kann man wunderbar arbeiten!

Cherry G80-3000 Cherry G80-3000 Cherry G80-3000 Cherry G80-3000 Cherry G80-3000 Cherry G80-3000

Man muss jedoch aufpassen, dass man beim Ablöten des standardmäßigen Controllers nichts kaputt macht. Falls das doch geschehen sollte, kann man es aber zum Glück auch relativ einfach wieder reparieren, indem man eine direkte Verbindung zieht. Schon kann man bereits die ersten Tests beim Auslesen der Tastatur machen.

Tastatur reparieren und auslesen Tastatur reparieren und auslesen Tastatur reparieren und auslesen

Im ersten Schritt reicht es, die Anschlüsse mit einem Multimeter zu verbinden und zu prüfen, ob eine durchgehende Leitung vorhanden ist. Dies sollte dann der Fall sein, wenn die passende Taste gedrückt wird. Hat man diesen Test erfolgreich erfolgreich hinter sich gebracht, kann man damit anfangen, durchzuprobieren, welche Anschlüsse für welche Taste stehen. Es dauert ein kleines bisschen, bis man weiß, welche Tasten mit welchen Anschlüssen verbunden sind, doch die Arbeit lohnt sich. Bereits die ersten praktischen Tests sehen schon sehr cool aus. Zum Beispiel kann man die gedrückten Tasten auslesen und mit Hilfe eines Arduino Leonardo eine USB-Tastatur emulieren. Nunja, von Emulieren kann aber diesem Zeitpunkt ja eigentlich keine Rede mehr sein.

Ein Problem, das man lösen muss, ist, dass man nicht alle Pins des Arduino Leonardo mit der Tastaturansteuerung blockieren will. Man muss also irgendwie die ganzen Pins des Tastaturlayouts zusammenschrumpfen. Genauer gesagt verwendet die Cherry G80-3000 genau 18 Leitungen als Eingang und 8 Leitungen als Ausgang. Damit lassen sich theoretisch 144 verschiedene Tasten ansteuern. Leider habe ich keine Ahnung, weshalb man solch ein merkwürdiges Design gewählt hat. Wahrscheinlich will man dadurch gewisse, häufiger vorkommende, Tastenkombinationen ermöglichen, ohne gleich Dioden für alle Tasten verbauen zu müssen. Jedenfalls kann man hierfür mein LED-Beispiel von früher etwas abwandeln, um die 26 Steuerleitungen ansprechen zu können. Ich habe das Konstrukt "Tastaturtreiber" getauft. Es besteht im Grunde aus 4-Bit-Zählern, Demultiplexern und ein wenig NAND-Logik. Als Resultat reichen nun 4 Leitungen aus, um die Tastatur vollständig auslesen zu können:

G80-3000 Tastaturtreiber-Layout

Das ganze lässt sich sogar, wenn auch etwas unübersichtlich, auf einer 5x10cm Streifenrasterplatine unterbringen. Der initiale Aufwand lohnt sich, sobald man etwas mehr mit dem ganzen Setup herumexperimentieren will. Denn ein Aufbau auf einem Steckboard ist einfach wesentlich instabiler.

G80-3000 Tastaturtreiber G80-3000 Tastaturtreiber G80-3000 Tastaturtreiber G80-3000 Tastaturtreiber G80-3000 Tastaturtreiber G80-3000 Tastaturtreiber G80-3000 Tastaturtreiber


calc.pw beim 30C3

06.01.2014 yahe arduino calcpw hardware legacy publicity security

Das Ende des letzten Jahres hatte es in sich: Ich durfte auf dem 30C3 einen Vortrag zu calc.pw halten.

Screenshot vom 30C3

Im Vortrag selbst habe ich die Idee hinter calc.pw vorgestellt, was ich mir für eine Lösung ausgedacht habe, welchen Problemen ich bei der Implementierung begegnet bin, wie ich diese gelöst habe und welche Pläne ich für die kommende Zeit habe.

Vortragssaal Vortragssaal

Wer sich das ganze ansehen mag, kann sich die MP4-Datei direkt beim CCC herunterladen.


Software-Reset aus dem Arduino Leonardo herauspatchen

19.12.2013 yahe arduino code hardware legacy security

Der Arduino Leonardo, der nun seit etwa einem Jahr auf dem Markt ist, besitzt dank seines ATmega 32u4 direkt die Möglichkeit, eine USB-Verbindung mit dem PC aufzubauen. Auf dem Arduino Uno war dafür ein separater Mikrocontroller zuständig. Durch diese Änderung hat sich jedoch auch die Art, wie Resets über den USB-Anschluss angestoßen werden, geändert. Dieser Reset ist inzwischen eine reine Software-Routine und kann falls nötig herausgepatcht werden.

Der Software-Reset wird ausgeführt, indem vom PC aus eine serielle Verbindung mit 1200 Baud aufgebaut und wieder geschlossen wird. Die auf dem Arduino Leonardo laufende Software interpretiert dies als Wunsch, einen Reset durchzuführen. Dieser Reset kann im Anschluss zum Beispiel genutzt werden, um einen neuen Sketch auf das Gerät zu laden. In Fällen, in denen mit Hilfe der Arduinos jedoch z.B. eine Kleinserie gefertigt wird, kann der Wunsch bestehen, das einfache Aufspielen von neuen Sketches zu unterbinden. Hierfür sollte man bei seinem Arduino-IDE Installationsverzeichnis einmal in die Datei "/hardware/arduino/avr/cores/arduino/CDC.cpp" blicken. In dieser findet sich die Funktion "CDC_Setup()", die folgenden Passus enthält:

if (CDC_SET_LINE_CODING == r || CDC_SET_CONTROL_LINE_STATE == r)
{
  // auto-reset into the bootloader is triggered when the port, already
  // open at 1200 bps, is closed.  this is the signal to start the watchdog
  // with a relatively long period so it can finish housekeeping tasks
  // like servicing endpoints before the sketch ends

  // We check DTR state to determine if host port is open (bit 0 of lineState).
  if (1200 == _usbLineInfo.dwDTERate && (_usbLineInfo.lineState & 0x01) == 0)
  {
    *(uint16_t *)0x0800 = 0x7777;
    wdt_enable(WDTO_120MS);
  }
  else
  {
    // Most OSs do some intermediate steps when configuring ports and DTR can
    // twiggle more than once before stabilizing.
    // To avoid spurious resets we set the watchdog to 250ms and eventually
    // cancel if DTR goes back high.

    wdt_disable();
    wdt_reset();
    *(uint16_t *)0x0800 = 0x0;
  }
}

Um den Software-Reset zu deaktivieren, muss dieser Code einfach vollständig auskommentiert werden. Anschließend ist ein Reset nur noch durch Betätigung des Reset-Buttons oder durch manuelles Verbinden des RESET-Pins mit einem GND-Pin möglich. Natürlich ist es auch möglich, den Software-Reset später wieder zu aktivieren. Dazu muss der vormals auskommentierte Quelltextblock wieder einkommentiert und einmal ein Sketch durch einen rechtzeitigen manuellen Reset geflasht werden.


Zwei Arduinos miteinander verbinden

18.12.2013 yahe arduino hardware legacy

Derzeit arbeite ich mal wieder ein wenig an calc.pw, da der vorhandene Code für ein Arduino allein inzwischen zu umfangreich wird. Deshalb sehe ich mir derzeit an, wie ich den Programmcode auf zwei Arduinos verteilen kann. Es bestünde natürlich die Möglichkeit, auf ein anderes Mikrocontroller-Board zu wechseln, das ist jedoch mit höheren Aufwänden verbunden. Zudem verwendet selbst der Arduino Uno R3 mehrere Mikrocontroller (einen ATmega 328 für die Sketchausführung und einen ATmega 16u2 für die USB-Kommunikation).

Das erste Problem, das einem begegnet, ist das richtige Anschließen des zweiten Arduinos und die Kommunikation zwischen den beiden Arduinos. Beides lässt sich mit vier Verbindungen lösen:

  • der +5V-Pin von Arduino A wird mit dem +5V-Pin von Arduino B verbunden
  • ein GND-Pin von Arduino A wird mit einem GND-Pin von Arduino B verbunden
  • der RX-Pin (Pin 0) von Arduino A wird mit dem TX-Pin (Pin 1) von Arduino B verbunden
  • der TX-Pin (Pin 1) von Arduino A wird mit dem RX-Pin (Pin 0) von Arduino B verbunden

Anschließend kann man unter Verwendung der Serial-Schnittstelle Daten zwischen den beiden Arduinos hin und herschicken. Das funktioniert soweit auch ganz gut, hat aber ein kleines Problem: Es mangelt an einer ordentlichen Synchronisation zwischen den beiden Arduinos. Normalerweise übernimmt Arduino A die Führung, während Arduino B die Befehle von Arduino A ausführt. Hier muss jedoch dafür gesorgt werden, dass beide Arduinos wissen, dass der jeweils andere für die Kommunikation bereit ist. Erhalten jedoch beide gleichzeitig Strom, beginnt bei ihnen die Ausführung der Setup-Routine. Je nach Umfang kann sie jedoch bei dem einen früher fertig werden als bei der anderen. Vielleicht benötigt die eine auch Nutzereingaben, sodass nicht einfach nach einer kurzen Verzögerung die Arbeitsbereitschaft vorausgesetzt werden kann.

Zwei Arduinos miteinander verbinden

Die Lösung, die mir hierfür in den Sinn kam, ist, dass Arduino A, das die Führung übernimmt, einfach selbst bestimmt, wann Arduino B mit der Setup-Routine beginnen darf. Hierfür lasse ich Arduino A einfach den RESET-Pin von Arduino B steuern. Das sieht nun insgesamt wie folgt aus:

  • Arduino A setzt den Pin, der mit dem RESET-Pin von Arduino B verbunden ist, auf LOW
  • Arduino A führt sein Setup durch und startet dabei auch die serielle Kommunikation
  • Arduino A setzt den Pin, der mit dem RESET-Pin von Arduino B verbunden ist, auf HIGH
  • Arduino A wartet auf die Fertig-Meldung von Arduino B
  • Arduino B führt sein Setup durch und startet dabei auch die serielle Kommunikation
  • Arduino B sendet die Fertig-Meldung an Arduino A
  • Arduino A kann Befehle an Arduino B senden

*Arduino A weiß, dass Arduino B bereit ist, indem es eine entsprechende Fertig-Meldung zugesandt bekommt. Arduino B wiederum weiß indirekt, dass Arduino A bereit ist, da es nur dann läuft, wenn Arduino A das möchte.

Man sollte übrigens die Verbindungen zwischen den Datenpins (RX, TX) und RESET am besten mit einem Widerstand (1kΩ bis 10kΩ sollten problemlos funktionieren) absichern, um Überspannungen zu verhindern. In ersten, einfachen Tests hat es jedoch auch komplett ohne funktioniert.


Vom Arduino zur Standalone-Hardware

21.06.2013 yahe arduino hardware legacy

Wenn man das erste Mal mit Arduinos in Kontakt kommt, wundert man sich, wie klein und günstig die Plattform doch ist. Nach und nach merkt man dann allerdings, dass das Arduino doch sehr überladen und teuer ist. Für die Entwicklung ist es großartig, für den späteren produktiven Einsatz jedoch nicht. Früher oder später guckt man, wie man das ganze ein wenig verschlanken kann.

Für kleinere Projekte bieten sich hierfür die ATtiny-Microcontroller von ATMEL an. Ein kleiner ATtiny 85 ist bereits ab 0,99€ zu haben und hat mit 8MHz und 8KiB EEPROM doch schon einiges zu bieten. Für 1,65€ kriegt man auch einen ATtiny 84, der einem noch mehr Eingabe- und Ausgabe-Pins bietet.

Jedoch ist es mit dem Chip allein noch nicht getan, denn irgendwie muss man dort ja sein Programm drauf bekommen. Hier hat das MIT einiges an Vorarbeit geleistet und leicht verständliche Anleitungen online gestellt. Zudem verweisen sie auf die Hardwaredefinitionen, die die Arduino-Software benötigt, um ordentlich mit solch einem Chip kommunizieren zu können. Auch auf der Arduino-Webseite und bei Youtube erfährt man viel darüber, was man tun muss, um Microcontroller mit Software zu füttern.

Auch ich habe das ganze nach und nach ausprobiert. Angefangen hatte ich mit einem wirklich simplen Projekt: einer kleinen Ampelanlage. Diese schaltet einfach zwischen den Ampelphasen rot, rot-gelb, grün und gelb hin und her. Der kleine Chip auf dem Breadboard ist der Microcontroller.

ATMEL ATtiny 85 Ampel

Das ganze kann natürlich auch ein bisschen komplizierter sein, als eine einfache Ampel. Mit Hilfe eines 12-Bit-Counters, eines NAND-Gatters, eines NOR-Gatters und drei Multiplexern habe ich zum Beispiel das LED-Beispiel vom letzten Mal von 16 auf 24 LEDs erweitern können.

ATMEL ATtiny 85 Lichtershow ATMEL ATtiny 85 Lichtershow

Die Logik ist auch bei 24 LEDs recht einfach. Der 12-Bit-Counter zählt hoch. Solange nur die niedrigsten 3 Bits gesetzt sind, ist der erste Multiplexer aktiv. Ist das vierte Bit gesetzt, so ist der zweite Multiplexer aktiv und ist das fünfte Bit aktiv, dann wird der dritte Multiplexer aktiv geschaltet. Sobald das vierte UND fünfte Bit gesetzt sind, wird das als Reset für den Zähler genutzt und alles fängt von vorne an.

Mit gar nicht allzu viel Aufwand ist es übrigens möglich, ein kleines Arduino-Shield zu basteln, das in Kombination mit dem ArduinoISP-Quelltext aus dem Arduino einen kleinen ATtiny-Programmierer macht. Hierbei sollte man übrigens die Pin-Belegungen entsprechend der jeweiligen Datasheets im Auge behalten (ATtiny 85 Datasheet, ATtiny 84 Datasheet).

ArduinoISP-Lochraster-Prototyp

Dank meines selbstgebauten ISP-Shields kann ich einfach einen ATtiny Microcontroller in den Testsockel einspannen und über die Arduino-Software mühelos neue Programme auf ihn aufspielen. Danach muss ich den Microcontroller nur noch in das Projekt einsetzen, in dem ich ihn verwenden möchte. Einfacher geht es wirklich nicht mehr.

ArduinoISP-Proto-Shield

Und auf Basis eines Arduino Proto-Shield sieht der ArduinoISP sogar richtig gut aus.


Search

Links

RSS feed

Categories

administration (40)
arduino (12)
calcpw (2)
code (33)
hardware (16)
java (2)
legacy (113)
linux (27)
publicity (6)
review (2)
security (58)
thoughts (21)
windows (17)
wordpress (19)