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


von SF (Gast)


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 :)

: Gesperrt durch Moderator
von Ingenius (Gast)


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>*/

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


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.)

von SF (Gast)


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

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


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.

von Christian R. (supachris)


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.

von SF (Gast)


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.

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


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.

von Ralf (Gast)


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

von Christian R. (supachris)


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:
1
  int usb_get_string(usb_dev_handle *dev, int index, int langid, char *buf,
2
                     size_t buflen);
3
  int usb_get_string_simple(usb_dev_handle *dev, int index, char *buf,
4
                            size_t buflen);

von SF (Gast)


Lesenswert?

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

Ja. Damit gehts. Hab das ganze dann so realisiert:
1
  /* Generic USB library bus structure traversal */
2
  usb_find_busses( );
3
  usb_find_devices( );
4
  
5
  usb_dev = NULL;
6
  
7
  /* Scan device tree for vendor ID/product ID match */
8
    for ( usb_bus = usb_get_busses( ); usb_bus; usb_bus = usb_bus -> next )
9
    {
10
        for ( dev = usb_bus -> devices; dev; dev = dev -> next )
11
        {
12
            if (( dev->descriptor.idVendor == VENDORID ) &&
13
                ( dev->descriptor.idProduct == PRODUCTID ))
14
            {      
15
                   
16
              usb_dev = dev;
17
        
18
              //get handle on device
19
              handle = usb_open(usb_dev);
20
21
             //get serialnumber
22
             char index = dev->descriptor.iSerialNumber;
23
             usb_get_string_simple(handle, index, device_serial, sizeof(device_serial));
24
25
             //compare serialID with derial from device
26
             if((strcmp(SERIALNUMBER,device_serial))==0)
27
             {
28
                //break scan, device found
29
                break;
30
             }
31
             else
32
             {
33
                //return NULL -> no matching device
34
                handle = NULL;
35
             }
36
           }      
37
        }
38
     }

von Peter (Gast)


Lesenswert?

Hallo,

das Thema würde mich auch sehr interessieren, da ich auch einen USB 
Gerät entwickelt habe, mit der ich Relais schalten kann.

Frage ist, wie oder wo lässt sich es einstellen, wenn ich mit der PC 
Software zwei gleiche USB Geräte ansteuern möchte?

VID / PID und die BUS Serial Nummer sind alle identisch.

Wie verwaltet Windows das ganz?
Was muss ich an Windows-System ändern, damit ich beide Geräte 
gleichzeitig ansprechen kann?


danke im Voraus
Peter

von Clemens L. (c_l)


Lesenswert?

Peter schrieb:
> Serial Nummer sind alle identisch.

Dann ändere deine Firmware, so dass verschieden Geräte auch verschiedene 
Seriennummern haben.

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


Lesenswert?

Peter schrieb:
> das Thema würde mich auch sehr interessieren

Offenbar nicht so sehr, dass du dir den Thread auch durchgelesen 
hättest,
bevor du ihn nach acht(!) Jahren wieder ausbuddelst.

Dieser Beitrag ist gesperrt und kann nicht beantwortet werden.