mikrocontroller.net

Forum: PC-Programmierung Mehrere USB Geräte (VID,PID gleich) im PC ansprechen


Autor: SF (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

ich entwickle USB Gerät für Temperaturlogging.
Am PC läuft eine Software, welche die ADC Werte vom Gerät bekommt, 
Datenauswertung macht und die Temperatur darstellt.

Dabei setze ich generischen Treiber Win32-LibUsb ein.
In der Software spreche das Gerät über VID und PID an. D.h. der Bus wird 
nach meinen VID und PID gescannt und gibt mir einen Handle auf das Gerät 
zurück.

Mein Problem ist:
Wenn zwei Geräte gleichzeitig am PC angeschlossen sind, wie kann ich die 
dann unterscheiden? Denn beide haben gleiche VID und PID.

Vieleicht kann mir jemand paar Tipps geben, diese SChwierigkeit schnell 
zu lösen :)

Autor: Ingenius (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Du brauchst noch eine eindeutige Gerätekennung.
Die VID gibt den Hersteller an und die PID das Produkt des Herstellers. 
Jetzt muss man noch das Produkt eindeutig kennzeichnen, so dass VID / 
PID / eine eindeutige Kombination ergeben.

UINT USB_VID = 0x1234;
UINT USB_PID = 0x1234;
BYTE USB_SerialStr[] = {0x0A,0x03,'1',0,'1',0,'1',0,'8',0}; /**< 
Eindeutige USB-Device Nummer <br>*/

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
SF wrote:

> Wenn zwei Geräte gleichzeitig am PC angeschlossen sind, wie kann ich die
> dann unterscheiden? Denn beide haben gleiche VID und PID.

Per Seriennummer.  (Weiß nicht, ob dir das aus Ingenius' Antwort
wirklich klar geworden war.)

Autor: SF (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

danke für die Antowort.
Hab jetzt nach SEriennummer mein Gerät und die Software duchgeschaut.

Stimmt. Ich muss die Seriennummer verwenden. Diese muss für jedes Gerät 
eindeutig sein. Man sieht sie, wenn man Eigenschaften des Gerätes unter 
GErätmanager anschaut.

Z.B.:
USB\VID_1A40&PID_0101\5&23D3BB0F&0&4

Seriennummer: 5&23D3BB0F&0&4

In der PC-software kann ich auch über  dev->descriptor.iSerialNumber auf 
die Seriennummer zugreifen.

Muss nur noch heruasfinden welchen Datentyp ich verwenden darf.
Aber das ist Compiler und Entwicklungsumgebung Sache...

Das Prinzip mit USB ist soweit klar! Danke vielmals

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
SF wrote:

> Muss nur noch heruasfinden welchen Datentyp ich verwenden darf.

An sich ist die Seriennummer bei USB ein x-beliebiger Text.
Allerdings schreiben wohl manche Geräteklassen ein bestimmtes
Format vor (habe sowas von mass storage devices gehört).  Sofern
ich mich recht entsinne, ist das typischerweise ein hexadezimaler
String dann.

Autor: Christian R. (supachris)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
SF wrote:

> Z.B.:
> USB\VID_1A40&PID_0101\5&23D3BB0F&0&4
>
> Seriennummer: 5&23D3BB0F&0&4

Das ist dann die von Windows "zufällig" gewählte, wenn kein SerialNumber 
String eingetragen ist.

> In der PC-software kann ich auch über  dev->descriptor.iSerialNumber auf
> die Seriennummer zugreifen.

Nicht direkt. iSerialNumber ist nur die Nummer des StringDescriptors, 
der die SerialNumber enthält.
Der StringDescriptor selbst muss genauso definiert werden wie der für 
Hersteller und Gerätekennung.

> Muss nur noch heruasfinden welchen Datentyp ich verwenden darf.
> Aber das ist Compiler und Entwicklungsumgebung Sache...

Ein String. Und da bLength im StringDescriptor ein 8-Bit Typ ist, darf 
die Länge maximal 255 Zeichen sein.

Autor: SF (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Nicht direkt. iSerialNumber ist nur die Nummer des StringDescriptors,
>der die SerialNumber enthält.

Das stimmt. Hab es grad eben ausprobiert. Ich bekomme nur die Nummer des 
String deskriptors. Wie kann ich aber auf den Inhalt dieses Deskriptors 
zugreifen?

Mein Ziel ist es gesamten String auslesen und den dann vergleichen.

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich schieb' das mal rüber in die PC-Programmierung, denn dein Problem
scheint mir ja nun mehr auf der oberen Ebene (nicht im Gerät selbst)
zu liegen.

Autor: Ralf (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Muss nur noch heruasfinden welchen Datentyp ich verwenden darf.
> Aber das ist Compiler und Entwicklungsumgebung Sache...
Soweit ich weiss, ist die Seriennummer ein String.
Du darfst für die Seriennummer die darstellbaren Zeichen (0x20 - 0x7F) 
verwenden, mit Ausnahme des Codes 0x2C -> Komma.

Du darfst die Seriennummer auch weglassen, Windows unterscheidet in 
diesem Fall die Geräte anhand des Ports, an dem die Geräte eingesteckt 
sind. Jeder USB-Anschluss hat eine sogenannte LocationID, die man dann 
verwenden kann.

Einige USB-Geräteklassen setzen eine Seriennummer voraus.

Ralf

Autor: Christian R. (supachris)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
SF wrote:
>>Nicht direkt. iSerialNumber ist nur die Nummer des StringDescriptors,
>>der die SerialNumber enthält.
>
> Das stimmt. Hab es grad eben ausprobiert. Ich bekomme nur die Nummer des
> String deskriptors. Wie kann ich aber auf den Inhalt dieses Deskriptors
> zugreifen?

aus der Header-Datei von der LibUSB:
  int usb_get_string(usb_dev_handle *dev, int index, int langid, char *buf,
                     size_t buflen);
  int usb_get_string_simple(usb_dev_handle *dev, int index, char *buf,
                            size_t buflen);

Autor: SF (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>>aus der Header-Datei von der LibUSB:
int usb_get_string(usb_dev_handle *dev, int index, int langid, char *buf,
                     size_t buflen);
int usb_get_string_simple(usb_dev_handle *dev, int index, char *buf,
                            size_t buflen);


Ja. Damit gehts. Hab das ganze dann so realisiert:
  /* Generic USB library bus structure traversal */
  usb_find_busses( );
  usb_find_devices( );
  
  usb_dev = NULL;
  
  /* Scan device tree for vendor ID/product ID match */
    for ( usb_bus = usb_get_busses( ); usb_bus; usb_bus = usb_bus -> next )
    {
        for ( dev = usb_bus -> devices; dev; dev = dev -> next )
        {
            if (( dev->descriptor.idVendor == VENDORID ) &&
                ( dev->descriptor.idProduct == PRODUCTID ))
            {      
                   
              usb_dev = dev;
        
              //get handle on device
              handle = usb_open(usb_dev);

             //get serialnumber
             char index = dev->descriptor.iSerialNumber;
             usb_get_string_simple(handle, index, device_serial, sizeof(device_serial));

             //compare serialID with derial from device
             if((strcmp(SERIALNUMBER,device_serial))==0)
             {
                //break scan, device found
                break;
             }
             else
             {
                //return NULL -> no matching device
                handle = NULL;
             }
           }      
        }
     }

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.