Forum: Mikrocontroller und Digitale Elektronik AVR(ATtiny85) PC<->USB Bidirektional-Lösung-VUSB


von Kahn P. (Gast)


Lesenswert?

Hallo zusammen,

ich habe mich kürzlich mit AVR's beschäftigt, das sind 8Bit ARM 
Prozessoren die mit bis zu >20Mhz laufen.

Es gibt sehr kleine Boards  z.B.  : OLIMEXINO-85S
http://www.olimex.com/Products/Duino/AVR/OLIMEXINO-85S/open-source-hardware

Die Arduino IDE auf die ich mich jetzt beziehe kann "normal" lediglich 
über eine RS232 Verbindung einen Baustein ansprechen.

Diese kleinen AVR-Boards haben keinen FIFO / Serial Baustein was eine 
Kommunikation lediglich direkt über die Pegelleitung Rx/Tx ermöglicht.
Entsprechend gering sind die Übertragungsraten.

Die Lösung zur Kommunikation ohne RS232 liefert Digispark: 
http://digistump.com/wiki/digispark/tutorials/connecting

Allerdings muss dann auch der Bootloader des Bausteins sowie die 
Arduino-IDE
auf Digsipark umgestellt werden. Den Bootloader kann man sich auf der 
Seite
samt dem hex file herunterladen und mit der micronucleus.exe auf den 
Baustein übertragen.

Vorher sollte man die Spezial Version der Arduino-IDE von Digistump 
installieren hier werden gleich die Treiber aus der usblib mit 
installiert.
Diese IDE kann problemlos parallel zur Original IDE installiert sein.

Im weiteren beziehe ich mich auf den Baustein ATtiny85.

Nach dem man die IDE installiert hat, kann man diese nun über das Menu 
Tools/Board/Digsipark(default 16.5 Mhz) umstellen.

Und das auschlaggebend Example über File/Example/DigsiparkUSB/Echo 
auswählen, und den Baustein damit laden.

Jetzt kommt's !

Wenn man das Example auf den Baustein geladen hat, sieht man erstmal 
nichts.

Es ist nun der C/C++ Programmierer der über Windows mit dem Baustein 
kommunizieren will.
Was nun gänzlich un-dokumentiert ist, ist wie das genau erfolgen soll.
Das Digsipark verwendet nämlich die sog. VUSB-Lib dies ist eine auf dem 
Mikrocontroller basierende Abwandlung der usblib und wird über die 
Arduino-IDE
beim Kompilieren des Samples in das AVR-Projekt verlinkt, so das dieses 
Baustein über drehen von internen Pins über die Tx/Rx Leitung als USB 
-Gerät
auf dem Windows PC erscheint. z.B. Als Joystick / Keyboard /Maus oder 
wie im Echo -sample als "DigiUSB"  mit dem man "reden" möchte.


Auf der PC Seite muss man ein Console basierendes Projekt erstellen, und 
die usblib herunterladen so das die libs/dll/include für die 
Kommunikation über
usblib hergestellt werden kann. Die libusb gibt es hier :
http://sourceforge.net/projects/libusb-win32/files/libusb-win32-releases/1.2.6.0/


Im C/C++ Projekt(VisualStudio) die Pfade für Include und Lib auf die, 
aus dem Archiv erstellten analogen Verzeichnisse erweitern.

Der Treiber wurde bereits bei der Installation der veränderten DigsiPark 
Arduino-IDE installiert, kann aber im Bin verz. des Archives
jederzeit erneut installiert werden, z.B. wenn man das ganze weiter 
geben möchte.

Primitives aber einfaches Beispiel, das zum Kommunikation -Erfolg führt:
1
  #include "stdio.h"//printf usw.
2
  #include "libusb_dyn.c"//this load the DLL at runtime dynamical
3
  
4
  usb_init(); // initialize the library 
5
  usb_find_busses(); // find all busses 
6
  usb_find_devices(); // find all connected devices 
7
  
8
  if (!(dev = open_dev()))
9
  {
10
   printf("error opening device: \n%s\n", usb_strerror());
11
   return 0;
12
  }
13
  
14
  BYTE n = 0;
15
  while (1)
16
  {  
17
    usb_control_msg(dev,USB_TYPE_CLASS | USB_ENDPOINT_OUT,USB_REQ_SET_CONFIGURATION,USB_RECIP_DEVICE,'H', 0, 0, 1000);
18
    usb_control_msg(dev,USB_TYPE_CLASS | USB_ENDPOINT_OUT,USB_REQ_SET_CONFIGURATION,USB_RECIP_DEVICE,'A', 0, 0, 1000);
19
    usb_control_msg(dev,USB_TYPE_CLASS | USB_ENDPOINT_OUT,USB_REQ_SET_CONFIGURATION,USB_RECIP_DEVICE,'L', 0, 0, 1000);
20
    usb_control_msg(dev,USB_TYPE_CLASS | USB_ENDPOINT_OUT,USB_REQ_SET_CONFIGURATION,USB_RECIP_DEVICE,'L', 0, 0, 1000);
21
    usb_control_msg(dev,USB_TYPE_CLASS | USB_ENDPOINT_OUT,USB_REQ_SET_CONFIGURATION,USB_RECIP_DEVICE,'O', 0, 0, 1000);
22
    usb_control_msg(dev,USB_TYPE_CLASS | USB_ENDPOINT_OUT,USB_REQ_SET_CONFIGURATION,USB_RECIP_DEVICE,'\n', 0, 0, 1000);
23
  
24
    tmp[0] = 0;
25
    
26
  
27
    while ((ret = usb_control_msg(dev, USB_TYPE_CLASS | USB_ENDPOINT_IN, USB_RECIP_INTERFACE, 0, 0, &tmp[0], sizeof(char), 1000)) > 0)
28
    {
29
      printf("%s", &tmp[0]);
30
    }
31
  
32
  }

Es ist also die Art der Parameterisierung der missbrauchten Funktion 
usb_control_msg, um einzelne bytes hin oder her zu transferieren.
Diese Ansprechung habe ich nach langer recherche und vielen Experimenten 
heraus gewonnen.

Der Baustein war in der Lage fehlerfrei bis zu 1[KB/s] an Daten zu 
senden und weit weniger zu empfangen, die ganze Sache führt zum crash 
des Bausteins wenn man
versucht zu viel Eingaben zu senden. Die Basis der Kommunikation sollte 
also ein Byte -Befehlscode sein, aufgrund dessen der Baustein größere 
Datenmengen absetzt.
Das Senden von Daten an den Baustein geht nur schleppend, das Empfangen 
ist erstaunlich flott.

Basierend auf ein turturial das so leider aber nicht funktinierte:
http://codeandlife.com/2012/01/22/avr-attiny-usb-tutorial-part-1/

Ich habe inzwischen eine Mutithread pipeline Klasse entwickelt, wo eine 
birdirektionale Kommunikation mit dem Baustein wunderbar
funktioniert. Und das mit einer nicht sichtbaren PC-CPU -Auslastung.

Der Baustein sollte Codetechnich nicht mit weiteren library's belastet 
werden, dieser hat gut zu tun mit der Abhandlung der VUSB -Lib,
liefert aber noch genug Zündstoff seine Port's und analogen Daten an den 
PC zu übertragen,oder Befehle zu empfangen, man sollte zusehen
keine Stringoperationen oder komplexe Programmstrukte auf den 
Kleincomputer anzuwenden.

Für Fragen oder Besserungs-Vorschläge einfach melden.

Viel Erfolg
  Karsten

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.