FTDI USB device notification

OP #2364014
Lesenswert?

Hallo miteinander

Ich habe eine kleine Software die einen Daten-Stream mit einem MCU 
ermöglicht. Dabei werden Messwerte vom MCU an den PC gesendet. Der PC 
sendet ein paar Einstellungen an den MCU.

Alles läuft soweit so gut. Nun bin ich am Überarbeiten der Software, 
damit diese etwas stabiler läuft: Wenn z.B die Verbindung getrennt 
wurde, erkennt dies die Software noch nicht und versucht einfach weiter 
Daten zu senden.

Jetzt möchte ich dieses Problem beheben. Im gleichen Zug, könnte man ja 
noch eine "Auto-Connect" Funktion hinzufügen.

Bis jetzt habe ich etwas über die Windows Device Notification Events 
gelesen, aber dies ist sehr sehr "kompliziert". Über einen Timer wäre 
dies lösbar, aber nicht so elegant...

FTDI hat dafür eine App-Note herausgegeben, aber leider ist diese in C++ 
geschrieben und ich bräuchte diese in C#. Das wäre zwar nicht sonderlich 
schwer es umzuschreiben, wenn man es versteht...

Hat jemand da einen Tipp?
MFG
Patrick
#2364198
Lesenswert?

OK, 2 Zeilen sind nicht nur, aber viel mehr auch nicht. Ich programmiere 
mit der MFC, daher diese Lösung. Hab ich von hier: 
http://www.codeproject.com/KB/system/HwDetect.aspx
1
BEGIN_MESSAGE_MAP(..., CDialog)
2
  ...
3
  ON_MESSAGE(WM_DEVICECHANGE, OnMyDeviceChange)
4
  ...
5
END_MESSAGE_MAP()
6

7

8
BOOL Dialog::OnInitDialog()
9
{
10
  DEV_BROADCAST_DEVICEINTERFACE NotificationFilter;
11
  ZeroMemory( &NotificationFilter, sizeof(NotificationFilter) );
12
  NotificationFilter.dbcc_size = sizeof(DEV_BROADCAST_DEVICEINTERFACE);
13
  NotificationFilter.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE;
14
  
15
  NotificationFilter.dbcc_classguid = GUID;
16
  HDEVNOTIFY hDevNotify = RegisterDeviceNotification(this->GetSafeHwnd(), &NotificationFilter, DEVICE_NOTIFY_WINDOW_HANDLE);
17

18
  return TRUE;  // return TRUE  unless you set the focus to a control
19
}
20

21
LRESULT Dialog::OnMyDeviceChange(WPARAM wParam, LPARAM lParam)
22
{
23
    // for more information, see MSDN help of WM_DEVICECHANGE
24

25
    // this part should not be very difficult to understand
26

27
  if(wParam == DBT_DEVICEARRIVAL)
28
  {
29

30
  }
31
  
32
  if(wParam == DBT_DEVICEREMOVECOMPLETE)
33
  {
34

35
  }
36
  
37
    return 0;
38
}

Musst du natürlich bissl modifizieren und die Methoden deklarieren.
OP #2364859
Lesenswert?

OK.

Das Abfangen der Meldung, ob ein USB Gerät angeschlossen oder entfernt 
wurde habe ich mitlerweile:
1
protected override void WndProc(ref Message m)
2
{
3
    if (m.Msg == WM_DEVICECHANGE)
4
    {
5
        switch (m.WParam.ToInt32())
6
        {
7
            case DBT_DEVICEARRIVAL:
8
                MessageBox.Show(m.LParam.ToString());
9
                break;
10
            
11
            case DBT_DEVICEREMOVECOMPLETE:
12
                MessageBox.Show(m.LParam.ToString());
13
                break;
14
        }
15
    }
16
    base.WndProc(ref m);
17
}

Jetzt ist einfach noch das Problem, dass der Event jedesmal kommt. Aber 
ich möchte ihn nur für ein Device. Die GUID habe ich...
Kann ich da irgendwas noch hinzufügen?
#2364926
Lesenswert?

In C++ kommst du über den LParam an die Device-Infos ran:
1
if(wParam == DBT_DEVICEARRIVAL)
2
  {
3
    PDEV_BROADCAST_HDR pHdr = (PDEV_BROADCAST_HDR)lParam;
4
    if(pHdr->dbch_devicetype == DBT_DEVTYP_DEVICEINTERFACE)
5
    {
6
      PDEV_BROADCAST_DEVICEINTERFACE pDevInf = (PDEV_BROADCAST_DEVICEINTERFACE)pHdr;
7
      ...
8
    }
9
  }

An pDevInf hängt dann der Name, Gerätepfad, Class-GUID usw. da kannst du 
dir das passende raussuchen und nur was machen, wenn die GUID 
passt....ich vermute, das geht bei dir genau so.
OP #2364957
Lesenswert?

Klapt leider nicht.

Ich müsste die Events für ein ganz spezielles Device bekommen, da wenn 
z.B 2 FTDI Chips angeschlossen wurden und einer Entfernt wird, bekomme 
ich dann den selben Event...

Werde noch etwas Suchen, aber irgendwie habe ich das Gefühl das hierfür 
C# nicht unbedingt geeignet ist.
#2365029
Lesenswert?

Hm, du musst doch auch in C# den Gerätepfad usw. mit dem Event 
mitbekommen. Da musst du dann halt nach deiner genauen Seriennummer oder 
was auch immer suchen. Mit der C++ Variante und 
RegisterForDeviceNotification() bekommst du auch für alle Geräte, die 
mit der gleichen Treiber GUID laufen das Event.
#2365183
Lesenswert?

Patrick B. schrieb:
> Klapt leider nicht.
>
> Ich müsste die Events für ein ganz spezielles Device bekommen, da wenn
> z.B 2 FTDI Chips angeschlossen wurden und einer Entfernt wird, bekomme
> ich dann den selben Event...
>
> Werde noch etwas Suchen, aber irgendwie habe ich das Gefühl das hierfür
> C# nicht unbedingt geeignet ist.

http://social.msdn.microsoft.com/Forums/eu/csharpgeneral/thread/c4b7445f-9e1d-4b3e-b4a1-320d1d8b1ef7

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren