Arduino als USB-Joystick

IMAG1861
Arduino als USB-Joystickinterface

Die große Welt der kleinen Microcontroller und vor allem der sehr günstigen Microcontroller und deren Vielfältigkeit, hat mich beim folgenden 'Projektchen' wieder motiviert sie zu verwenden. Für die eher weniger outdoorlastigen kalten Wintertage habe ich mir ein Projekt vorgenommen, dass das Thema Retrocomputer betrifft. Zum einen habe geplant, die Website um die Rubrik der alten Computer zu erweitern (zumindest sollen die paar wenigen aus meiner Sammlung vorgestellt und in Betrieb genommen werden...) und zum anderen will ich mir eine Arcade-Station bauen, deren Kern das neue RaspBerry2 Modell ist . Auf dem soll die Emulatorplattform Retropie aus dem gleichnamigen Projekt zu Einsatz kommen. Die ersten Versuche mit den Images aus dem Projekt sehen sehr gut aus. Die alten 8-Bit und 16-Bit Computer laufen in der Emulation ausgezeichnet (C64, Atari, Amiga usw...). Was die Anbindung von Eingabegeräten betrifft, kann man natürlich Maus und Keyboard vom PC an den Raspberry anschliessen und alles steuern. Die Jungs aus dem Projekt haben auch selbst einige Boards entwickelt, die die Anbindung von Joysticks und co an des Raspberry ermöglichen. (zB. den GPIO Adapter). Aber da ich ein paar Arduino Unos herumliegen habe, dachte ich mir, warum nicht diese verwenden. Da es beim Arduino möglich ist, den Mega 16U2 zu flashen (der Chip wird als Programmer für den Atmega 328 auf dem Uno - Board verwendet) und aus dem Uno-Board so zum Beispiel ein USB-HID (Human Interface Device) zu machen -sprich Keyboard, Mouse, was auch immer, bot sich der als ideale Plattform an.

Tutorials, den Arduino zu einem HID-Interface zu flashen, gibt es mittlerweile schon sehr viele. Zum Beispiel findet man hier eine schöne Anleitung. Je nach dem welche Arduino-Uno Boardversion man hat, kann man sich den zusätzlichen Widerstand fürs DFU-Flashen sparen. (z.Bsp. bei meinen Boardversionen R3 ist der Widerstand nicht nötig.) Auf den neuen Boards ist auch nicht mehr der Atmega 8U2 verbaut, sondern der 16U2. Man muß einfach im Atmega Flash-Tool "ATMEL-FLIP" den entsprechenden Chip auswählen. Die entsprechenden Firmwarefiles findet man im Netz...

Arduino-keyboard-0.3.hex
Arduino-mouse-0.1.hex

Ist der Arduino dann geflasht, so wird er beim Anschluss an den PC eben als Keyboard oder Maus erkannt. Jetzt braucht man nur mehr den gewünschten Code in den Atmega328 zu schreiben und die Arduino UNO Eingänge führen z.Bsp. Tastaturbefehle aus. Um die Firmware jetzt nicht jedes Mal zwischen Programmer und USB-HID zu ändern, verwende ich einfach einen zweiten UNO der als Programmer dient und stecke einfach den geflashten Chip immer um (ist viel einfacher beim Testen).

Da das Interface jetzt soweit passt, habe ich mich mit dem HID-Codetable beschäftigt und die entsprechenden Tasten, die die Joystickbewegungen an den PC senden sollen herausgesucht.

Hier der sehr einfache Code der momentan die alten Commodore Joystickbewegungen umsetzt:)
/* HID Joystickinterface für Arduino UNO im HID Modus
 Jun2015 by I.Bihlo
 Die Tasten brauch i  Taste/Hexcode/Dec-Code  
  KEY_LEFT_CTRL    0x01  //01 
  KEY_LEFT_SHIFT    0x02  //02 
  KEY_LEFT_ALT    0x04  //04 
  KEY_LEFT_GUI    0x08  //08 
  KEY_RIGHT_CTRL    0x10  //16 
  KEY_RIGHT_SHIFT 0x20  //32 
  KEY_RIGHT_ALT   0x40  //64 
  KEY_RIGHT_GUI   0x80  //128 

  KEY_RIGHT_ARROW 0x4F  //79 
  KEY_LEFT_ARROW  0x50  //80 
  KEY_DOWN_ARROW  0x51  //81 
  KEY_UP_ARROW    0x52  //82 
  KEY_TAB         0x2B  //43 
  KEY_ENTER       0x28  //40 
  KEY_SPC         0x2C  //44 
 */ 
     uint8_t keyNone[8] = { 0, 0, 0, 0, 0, 0, 0 }; 
     uint8_t keyA[8] = { 0, 0, 4, 0, 0, 0, 0 };  //left 
     uint8_t keyD[8] = { 0, 0, 7, 0, 0, 0, 0 }; //right 
     uint8_t keyW[8] = { 0, 0, 26, 0, 0, 0, 0 }; //up 
     uint8_t keyS[8] = { 0, 0, 22, 0, 0, 0, 0 }; //down 
     uint8_t keySPACE[8] = { 0, 0, 44, 0, 0, 0, 0 }; //space 
      
     uint8_t keyLEFT[8] = { 0, 0, 80, 0, 0, 0, 0 };  //left 
     uint8_t keyRIGHT[8] = { 0, 0, 79, 0, 0, 0, 0 }; //right 
     uint8_t keyUP[8] = { 0, 0, 82, 0, 0, 0, 0 }; //up 
     uint8_t keyDOWN[8] = { 0, 0, 81, 0, 0, 0, 0 }; //down 
     uint8_t keyENTER[8] = { 0, 0, 40, 0, 0, 0, 0 }; //enter 
      
 // DEFINE inputs 
 const int UPA = 12; 
 const int DOWNA = 13; 
 const int LEFTA = 2; 
 const int RIGHTA = 3; 

 const int UPB = 4; 
 const int DOWNB = 5; 
 const int LEFTB = 6; 
 const int RIGHTB = 7; 

 int out=0; //fürs Testen am Serial Monitor im Programmermodus 

 void setup() { 
    
   // Die Pins als Eingang definieren (Intern PullUP setzen - ist bei mir nötig da actice Low geschaltet wird 
   pinMode(UPA, INPUT_PULLUP); pinMode(DOWNA, INPUT_PULLUP); pinMode(LEFTA, INPUT_PULLUP); pinMode(RIGHTA, INPUT_PULLUP);  
   pinMode(A0, INPUT); 
   pinMode(UPB, INPUT_PULLUP); pinMode(DOWNB, INPUT_PULLUP); pinMode(LEFTB, INPUT_PULLUP); pinMode(RIGHTB, INPUT_PULLUP);  
   pinMode(A1, INPUT);    
    
   Serial.begin(9600); 
    
 } 

  void loop() { 
     
    // Joystickbewegungen abfragen und senden 
    // Da das Interface einen Invert-Schmitt Trigger verpasst bekommen hat, werden die Ausgänge auf active LOW abgefragt - wenn nix passiert sind alles Eingänge HIGH 
     
    if (digitalRead(UPA)==LOW) {out=120; Serial.write(keyW, 8);}   
      
    if (digitalRead(DOWNA)==LOW) {out=121; Serial.write(keyS, 8);}   
      
    if (digitalRead(LEFTA)==LOW) {out=122; Serial.write(keyA, 8);}  
      
    if (digitalRead(RIGHTA)==LOW) {out=123; Serial.write(keyD, 8);}  
     
    if (digitalRead(A0)==LOW) {out=124; Serial.write(keySPACE, 8);}  
      
     
    if (digitalRead(UPB)==LOW) {out=130; Serial.write(keyUP, 8);}  
      
    if (digitalRead(DOWNB)==LOW) {out=131; Serial.write(keyDOWN, 8);}  
       
    if (digitalRead(LEFTB)==LOW) {out=132; Serial.write(keyLEFT, 8);}  
       
    if (digitalRead(RIGHTB)==LOW) {out=133; Serial.write(keyRIGHT, 8);}  
       
    if (digitalRead(A1)==LOW) {out=134; Serial.write(keyENTER, 8);}  
      
  delay(20);   
  //Serial.println(out); //des is nur fürs debuggen im serial monitor 
  Serial.write(keyNone, 8); // den Tastendruck beenden 

 delay(20); 
}
IMAG1858
Lochrasterplatine am Arduino

Als nächstes habe ich ein Interfaceboard (eine einfache Lochrasterplatine) mit zwei 9-poligen SUB-D-Buchsen für den Anschluss der Joysticks gebastelt. Da der Arduino genügend Ports besitzt, habe ich auf ein Multiplexen oder Matrixverschalten der insgesamt zehn Steuerleitungen verzichtet und jeden Joystickkontakt direkt auf einen Port gelegt. Das funktioniert schon einmal ganz gut. Aber das Prellen der Federkontakte und Microtaster in den Joysticks muss natürlich softwaremäßig entfernt werden. Um jetzt nicht in jeder Softwareversion einen debounce-code mitzuführen entschloss ich mich das Entprellen in der Hardware zu machen. Einfach ein RC-Glied (10k - 1uF) an einen Schmitt-Trigger und gut ist´s. Also schnell ein Board gelayoutet (das geht schneller als am Lochrasterprint zu löten), geätzt und bestückt... und heraus kam das Board hier:

IMAG1870
Board geätzt und gebohrt
IMAG1871
fertig bestückt am Arduino

Der Funktionstest verlief positiv. Die Bewegungen des Sticks werden sauber umgesetzt. Ein schneller Test mit WinVice ließ sofort das Zockergefühl von vor 30 Jahren aufkommen 😉

IPhone 5s unter dem Wirebonder

 

IMAG1839
IPhone 5S unter der Lupe 😀

Wenn der Bildschirm eines IPhone 5S einmal seinen Geist aufgibt (sprich zerbricht o.ä.), dann hilft nur mehr der Tausch desselben. Aber Vorsicht ! Die Schräubchen, die das Schirmblech über den drei Flexiprint-Steckern vom Display halten sind NICHT gleich lang.

Es gibt hier Schrauben unterschiedlicher Länge – auch wenn man das optisch nicht unbedingt gleich erkennt. Achtet man beim Zusammenbau nicht peinlich genau darauf, wieder alle Schrauben in die ursprüngliche Gewindebuchse zu drehen, dann ist es auch schon passiert. Die ca. 0.1mm längern Schräubchen stehen über die Buchse und berühren und beschädigen die Oberfläche der Platine. Wenn jemand es dann ganz genau nimmt und die Schrauben auch fest genug anzieht, dann drückt sich diese ins in den zweiten Layer der Platine. Und genau dort verlaufen sieben parallele Leiterbahnen, die zusammen eine Breite von knapp 1000um (1mm) benötigen. Jetzt kann man sich vorstellen, was die Spitze einer Schraube hier anrichten kann.

Genau – Chaos und Zerstörung. Die knapp 50um breiten Leiterbahnen haben keine Chance gegen den Koloss von Schraube mit 1000um.

Das Resultat: Mehrere dieser Leiterbahnen werden durchtrennt und das Handy findet nach dem Einschalten nicht mehr alle seine elektronischen Komponenten und beginnt den Bootvorgang zyklisch neu.(mit kurzem Aufleuchten eines Bluescreen)

Normalerweise ist das Gerät jetzt reif für die Tonne, oder zumindest wäre ein neues Mainboard fällig. Genau so ein Handy ist letztens bei mir auf dem Tisch gelandet.

IMAG1829_1
Bild 1

Im Bild 1 sind die Anschlüsse zum Display zu erkennen. Rechts unten, am schwarzen Fleck, war die Gewindebuchse montiert, in die die zu lange Schraube gedreht wurde. Wenn man die Buchse nun entfernt, kann man den Schaden begutachten.

 

Die Vergrößerung in Bild 2 zeigt deutliche Abdrücke der Schraube und ein leichtes kupfernes Schimmern ist auch zu erkennen.

 

 

Das Ausmaß der Beschädigung lässt sich aber nur feststellen, wenn der Layer in dem Bereich freigelegt wird. Mit einem geeigneten Mikroskalpell habe ich nun versucht, die Ebene freizulegen.

IMAG1827_1
Bild 2
IMAG1831
Bild 3

In Bild 3 sind die Leiterbahnen und deren Unterbrechungen zu sehen. Eine Reparatur mit Lötkolben und Reparaturlitze ist hier allerdings nicht mehr möglich.

IMAG1835
Bild 4

Da ich aber die Möglichkeit habe, an einem Wirebonder arbeiten zu können, kam mir die Idee, diesen für einen Reparaturversuch heranzuziehen. Der Bonder der Firma TPT-Wirebond bietet die Funktionen Wedge- und Ballbonden in verschiedenen Drahtdurchmessern. Das Wedgebonden konnte ich mir als geeignete und realisierbare Variante vorstellen. Der Bonddraht mit 25um Durchmesser sollte passen. Einzig für das Problem mit der Temperatur des Chuck hatte ich keine Lösung. Denn es ist sicher keine gute Idee, das IPhone aufzuheizen. Also versuchte ich kalt zu bonden. Kurzerhand den Chuck von seiner Stromversorgung getrennt und dafür die Ultraschallenergie des Bondwerkzeugs erhöht und einen Versuch gestartet. Und siehe da, der Bond hält. Also kurzerhand sechs von den sieben Leitung mit Golddrahtbrücken wieder leitend gemacht (Bild 4) und danach das Display für einen Startversuch angeschlossen. Und siehe da, das IPhone startete wieder normal.

IMAG1837_1
Bild 5

Jetzt ging es nur mehr darum, die empfindlichen Bonddrähte vor Beschädigung zu schützen.

Hier bot sich ein Kunstharz-Zweikomponenten-Kleber an, von dem ich eine stecknadelspitzengroße Menge abmischte und mit diesem Tröpfchen die Reparaturstelle überzog. Nach dem Aushärten konnte ich das Phone dann wieder zusammensetzen (an der Reparaturstelle natürlich ohne Schraube. Ein kurzer Funktionstest verlief positiv. 😉

 

 

Basteln am Motorrad

Die heißen Sommertage locken nicht unbedingt jeden vor Bildschirm und Tastatur um zu bloggen. Da verbringt man seine freie Zeit doch lieber im Freien und widmet sich seinen Outdoorhobbies. In meinem Fall, wenn ich nicht gerade damit beschäftigt bin, Unwetterschäden aufzuräumen, fahre ich mit der Perle mit dem Motorrad herum. Da das Motorrad auch aus reichlich Technik besteht, an der ich gerne und viel herumbastle, will ich diesmal einen kurzen Beitrag darüber verfassen.

Versys im Originalzustand
Versys im Originalzustand

Mein derzeitiges Moped, eine Versys von Kawasaki, ein Tourenmoped, soll aus Gründen der Verkehrssicherheit zusätzlich zur Serienbeleuchtung noch zwei Nebelscheinwerfer bekommen. Diese darf man nach der aktuellen Gesetzeslage nachrüsten und auch zu jeder Zeit einschalten und damit fahren.

Versys mit Nebelscheinwerfern
Versys mit Nebelscheinwerfern

Also nichts wie her mit einem Satz Scheinwerfer und los gehts mit dem Einbau.

 

Im folgenden Video ist der Einbau dokumentiert: