Forum: PC-Programmierung Problem mit libUSB - wie Gerät ansprechen?


von Doran S. (utzer)


Angehängte Dateien:

Lesenswert?

Hallo,

ich habe dieses Projekt nachgebaut: 
http://yveslebrac.blogspot.de/2008/10/cheapest-dual-trace-scope-in-galaxy.html
Das ganze bassiert auf dem EasyLogger: 
http://www.obdev.at/products/vusb/easylogger.html
Das Projekt verwendet VUSB, um mit dem PC zu kommunizieren.
Das Programm, das bei ersterem Link dabei ist, funktioniert auch für 
meinen Nachbau, alles super so weit, die Hardware ist also ok.

Jetzt möchte ich für eben dieses Projekt ein eigenes Programm schreiben, 
um die Messwert vom Tiny45 auszulesen.
Dazu habe ich mir libusb angeschaut, und bin auch soweit, dass ich das 
Gerät finde.

Das war die Vorgeschichte, jetzt kommt mein Problem:

Ich weiß nicht, wie ich die Daten vom Tiny45 anfordern soll...
-Was genau muss ich an den Tiny45 senden?
-Was für eine Übertragungsart ist das eig. (Bulk-Transfer, 
Interrupt-Transfer....?)
-Oder muss ich eine usb_control_msg(); verwenden um den Tiny 
anzusprechen?

Kann ich vllt. einfach mit usb_interrupt_read(); die Messwerte aus dem 
Tiny auslesen?

An der Stelle komme ich einfach nicht weiter.
Ich habe leider auch nur einen Teil des Codes des Programm aus dem 
ersten Link, daraus ersieht man nur, wie man aus den Daten die man vom 
Tiny bekommen hat, den Spannungswert berechnen kann, aber leider fehlt 
der Teil mit der Kommunikation zum Tiny :-(

Im Anhang ist der kompletter Sourcecode, für die Firmware auf dem Tiny.
Wenn ihr noch irgendetwas braucht, lasst es mich wissen.

Ich hoffe mir kann hier weitergeholfen werden und bedanke mich im 
Vorraus.
Gruß
Doran

PS: Nein, ich erwarte keine "Wunder" von diesem Projekt - ich habe auch 
nicht vor, es als Oszilloskop zu verwenden :-)

von Krapao (Gast)


Lesenswert?

"EasyLogger is a simple example which does not require any host 
software. It presents itself as a USB keyboard to the host and 
automatically enters the values it measures. To get a series of 
measurement values, just open a text editor or even a spreadsheet like 
Excel and press the start/stop button on the logger. EasyLogger will 
start to type values directly into your host application." 
http://www.obdev.at/products/vusb/easylogger.html

Beim EasyLogger würde dein PC-Programm also einfach Datentelegramme als 
eine Folge von Zeichen vom Standardinput Stream lesen.

Eine Kommunikation vom PC zum EasyLogger ist nicht vorgesehen. Der 
EasyLogger sendet nach einer externen Aktion (press the start/stop 
button on the logger).

Die Struktur der Datentelegramme also Trennzeichen innerhalb eines 
Telegramms (z.B. Komma für CSV Dateiformat) und das Endezeichen (z.B. 
CRLF) kannst du bei einem DIY-Easylogger-ähnlichen Gerät selbst 
festlegen, wenn du entsprechend programmierst.

Bei dem Tiny45 Code oben sieht das Datentelegramm so aus
1
static void buildReport(void)
2
{
3
  reportBuffer[0] = adcval1>>8;
4
  reportBuffer[1] = adcval1;
5
  reportBuffer[2] = adcval2>>8;
6
  reportBuffer[3] = adcval2;
7
  reportBuffer[4] = 0x01;
8
}

d.h. 5 Zeichen gesamt, davon 4 Zeichen Binär die Messwerte der beiden 
ADC-Kanäle, keine Trennzeichen, Endezeichen 0x01.

USB-seitig ist zu beachten, dass ein Datentelegramm bei Interruptbetrieb 
max. 8 Byte Nutzdaten haben darf (s. Kommentare in usbdrv.c). Längere 
Datenserien musst du auf dem Tiny45 dann in kleinere Portionen stückeln 
und auf dem PC wieder zusammensetzen.

von was? (Gast)


Lesenswert?

Doran S. schrieb:
> Jetzt möchte ich für eben dieses Projekt ein eigenes Programm schreiben,
> um die Messwert vom Tiny45 auszulesen.

Ich kann dir leider nicht direkt helfen. Als Alternative könntest du dir 
aber mal http://littlewire.cc/ ansehen. Ähnlicher Aufbau mit vorhanden 
Bibliotheken in C, C++, Processing, Basic etc.

von Doran S. (utzer)


Lesenswert?

Hallo,

Danke für die Antworten.

Ja, der EasyLogger präsentiert sich als Tastatur und "tippt" die Werte 
einfach ein.
Das funktioniert bei mir auch.
Das andere Projekt macht das aber anders: die Werte werden nur in dem 
mitgelieferten Programm angezeigt und man kann nebenbei noch einen 
Text-Editor offen haben und hat nicht das Problem, dass der EasyLogger 
"dazwischen tippt"..

Irgendwie wurde bei dem EasyLogger-Ähnlichen Projekt also die 
Geräteklasse geändert/das Gerät wird aber als HID erkannt.

Jetzt ist eben die Frage, wie ich mit dem Gerät kommunizieren kann.
Leider sehe ich da noch nicht ganz durch...

Was muss ich denn zu dem Gerät senden, damit ich die Messwerte erhalte?
Über welche Funktion von LibUSB kann ich die Daten empfangen?

Gruß
Doran

von Krapao (Gast)


Lesenswert?

"UPDATE: for all who requested the C# code for this app, here is the 
link usb-scope.zip done with Visual Studio 2005"
http://yveslebrac.blogspot.de/2008/10/cheapest-dual-trace-scope-in-galaxy.html

Wenn du in C# programmierst, wäre das bereits ein Ansatzpunkt. Die 
Einleseschleife sitzt dort in dem Messagehandler private void 
usb_OnDataRecieved(object sender, DataRecievedEventArgs args) in der 
Datei usbscope.cs

Für C, C++ ist dein Ansatz mit usb_interrupt_read(); IMHO sinnvoll. 
Dabei aufpassen, was passiert, wenn ein Timeout zuschlägt z.B. so
http://libusb.6.n5.nabble.com/usb-interrupt-read-error-codes-td4562028.html

libUSB ist aber fremdes Terrain für mich. Da kann ich nicht 
weiterhelfen.

von Doran S. (utzer)


Lesenswert?

Hallo,

ok, danke für die Antwort.
Ja, den Sourcecode von der Seite habe ich auch schon angeschaut.
Aber leider finde ich da nichts darüber, wie ich konkret mit dem Gerät 
kommunizieren soll...

Wenn ich also mit dem usb_interrupt_read() arbeite, stellt sich die 
Frage, was ich genau übergeben muss. (z.B: auf welchen Endpoint muss ich 
zugreifen?)
Muss ich davor dem Gerät mitteilen, dass ich jetzt die Messwerte holen 
möchte?
Muss evnt. ein usb_control_msg() vorausgehen?

Gruß
Doran

von Doran S. (utzer)


Lesenswert?

Hallo,

ich glaube ich habe es jetzt (zumindest ein bisschen) hinbekommen:
1
int len = usb_interrupt_read(handle, 0x81, data, sizeof(data), 5000);

ich empfange wohl 5 bytes (zumindest ist len nach dem Empfangen dann 5)
und je nach angelegter Spannung variieren die Daten auch :-)
Werde mich jetzt um die Auswertung kümmern.

Trotzdem würde mich noch interessieren, ob es vllt. auch noch 
Steuerbefehle gibt, die ich an das Gerät senden kann, z.B. um 
festzulegen, wie oft der ADC im Tiny45 eine "Aufnahme" macht, etc...

Gruß
Doran

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Doran S. schrieb:
> Trotzdem würde mich noch interessieren, ob es vllt. auch noch
> Steuerbefehle gibt, die ich an das Gerät senden kann, z.B. um
> festzulegen, wie oft der ADC im Tiny45 eine "Aufnahme" macht, etc...

You've got the source, Luke!

Warum schaust du nicht einfach rein?

Wenn ich das richtig sehe, wirft die main loop jeweils eine neue
Messung an, nachdem die vorigen Daten durch den Host abgeholt worden
sind.  Damit bestimmt also rein deine Auslesegeschwindigkeit auf dem
Host, wie oft dort Daten ermittelt werden.

von Doran S. (utzer)


Lesenswert?

Hallo,

ja, ich habe den Quelltext, aber leider habe ich da noch nicht so ganz 
den Durchblick...

Naja, mit
1
int len = usb_interrupt_read(handle, 0x81, data, sizeof(data), 5000);
 funktioniert es bestens, ich habe jetzt meine eigene Anwendung fertig 
geschrieben und alles läuft so wie gedacht.

ist so ok, wie ich auf das Gerät zugreife?

Gruß
Doran

von Krapao (Gast)


Lesenswert?

Sieht OK aus. timeout 5000 (ms?) ist lang, aber das spielt praktisch 
in deiner Anwendung ja keine Rolle. data kann die 5 Bytes vom Tiny45 
aufnehmen? Das letzte der 5 Bytes sollte 0x01 sein, siehe oben, das 
kannst du auch noch testen.

von Doran S. (utzer)


Lesenswert?

Hallo,

jawohl, data ist so deklariert:
1
char data[5];
Ich habe zum testen auch mal den Inhalt von data[4] ausgegeben: ist 0x1.
(wenn man es so macht:
1
cout<<(int)char[4];
)

Welche Werte für timeout sind den Standard? Und was genau hat es mit 
diesem Wert auf sich, bzw. wann wird er relevant?

Gruß und danke für die Tipps,
Doran

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.