Einzelnen Beitrag anzeigen

KRM

Registriert seit: 6. Feb 2007
Ort: Kölle am Rhing
24 Beiträge
 
Turbo Delphi für Win32
 
#1

Wie kann ich mit Delphi Daten vom USB-Controller abfragen?

  Alt 14. Apr 2007, 09:29
Ok, ich hoffe, dass ich hier die richtige Rubrik getroffen habe...

Ich brauche eure Hilfe, weil ich wahrscheinlich den Wald vor lauter Bäumen nicht mehr sehe o_O...

Ih bastel an einem System mit einem Microcontroller, der IR-Daten empfängt und diese via USB an einen PC überträgt.
Auf dem PC läuft ein Delphiprogramm...

Die Treiber und alles sind vorhanden und es funktioniert in soweit, dass ich vom dem Delphi-Programm aus eine Abfrage über bestimmte Daten, wie z.B. die Firmwareversion machen kann, der Microcontroller diese beantwortet und das Delphi-Programm es anzeigt.

Nun ist es aber so, dass die IR-Daten, die ich übermitteln muss, nicht direkt auf Anhieb verfügbar sind...

D.h. ich habe also vor einen Button zu drücken, der im Microcontroller das Empfangen von IR-Daten scharf schaltet (funktioniert auch)...
Aber wenn er Daten empfangen hat, muss das Delphi-Programm das irgendwie mitbekommen...

Eine Systembeschreibung als Bild (erklärt es vllt noch verständlicher) hänge ich an

Nach der USB-Spezifikation ist es so, dass der Hostcontroller im PC ständig seine Schäfchen abfragt, ob neue Daten vorhanden sind... D.h. ein USB-Gerät kann keinen direkten Interrupt auslösen...

Beispiel: Eine USB-Maus wird mehrere hundert Male in der Sekunde abgefragt, ob sie neue Daten hat, da sie nicht schreien kann "EY, der User berührt mich!"...
Im Hintergrund muss dann irgendwo dieser Treiber laufen, der dann auf neue Daten reagiert und sie graphisch umsetzt...
Aber er weiß ja nie, WANN der Benutzer die Maus bewegen wird...


Wie kann ich denn nun mit Delphi auf den Host-Controller zugreifen um meine Daten abzufragen?
Mit der Treiber DLL?
Mit irgendeiner Windows Datei?
Muss ich in einer Schleife immer wieder via USB den Controller selbst abfragen?

Zum Anfang würde es mir reichen, dass das Delphi-Programm solange in einer Schleife wartet, bis der Controller Daten liefert und dann sagt "Neue Daten empfangen. Daten: ..."
Vllt müsste ich im Hintergrund dann nur einen Timer laufen lassen, falls eine Minute nichts empfangen wurde, dass er den ganzen Kram abbricht...

Btw: Gibt es in Delphi eine fertige Timer-Funktion, die man im Hintergrund laufen lassen kann und die einen Interrupt im Programm auslöst? Oder muss ich sowas mit einer while-Schleife umsetzen?


INFOS:

Die USB-DLL basiert auf http://www.sixca.com/delphi/article/microchip_usb.html
Genauer auf die von Sprut: http://www.sprut.de/electronic/pic/8...sb/usb_dll.htm

Auf http://sprut.de/electronic/pic/8bit/...50/usb2550.htm ist das bisher verwendete Delphi-Programm beschrieben!
Ich habe einfach noch ein Button dazu gebaut, dass momentan eben nur einen Code sendet, der das Starten des Microcontroller aktiviert.
Bei Sprut ist auch die Funktion SendReceivePacket erklärt, die zur USB-Kommunikation verwendet wird.


Code Beispiel: Auslesen der Firmware im Microcontroller
Delphi-Quellcode:
procedure TForm1.Button3Click(Sender: TObject);
var
   selection : DWORD;
   send_buf : PBYTE;
   receive_buf : PBYTE;
   RecvLength : DWORD;
   CurrentCMD : BYTE;
begin
  // Read Firmware version
  //instance ist warscheinlich 0, kann aber auch einen anderen Wert haben
  selection:=0;

  // sind USB-Devices vorhanden?
  if (_MPUSBGetDeviceCount(vid_pid)=0) then
  begin
    Memo1.lines.add('- Device not connected');
    exit;
  end;

  //pipes anfordern
  //für die instance=0
  //es kann aber passieren, da´ss instance<>0 !!
  //da ist noch nacharbeit nötig
  myOutPipe:= _MPUSBOpen(selection,vid_pid,out_pipe,MP_WRITE,0);
  myInPipe:= _MPUSBOpen(selection,vid_pid,out_pipe,MP_READ,0);
  //habe ich pipes bekommen?
  if ((myOutPipe = INVALID_HANDLE_VALUE) or (myInPipe = INVALID_HANDLE_VALUE)) then
  begin
    Memo1.lines.add('USB Error');
    exit;
  end;

  //Firmwareversion auslesen
  send_buf[0]:=READ_VERSION; [b]// READ_VERSION: Eine hexadezimale Konstante, die vom PIC interpretiert werden kann,
                                // worauf er in recieve_buf[3] und [2] seine Antwort hinein schreibt. (Ausgabe = 2.0)[/b]
  RecvLength:=4; [b]// Anzahl zu empfangener Bytes[/b]

  // HIER DAS IST DIE SCHLÜSSELFUNKTION ZUR ÜBERTRAGUNG ÜBER USB
  if(SendReceivePacket(send_buf,1,receive_buf,RecvLength,100,100) = 1) then begin
    if(receive_buf[0] = READ_VERSION) then begin
      Memo1.lines.add('Firmware version : '+ IntToStr(receive_buf[3])+'.'+IntToStr(receive_buf[2]));
    end;
  end
  else
  begin
    Memo1.lines.add('USB Error');
  end;

  _MPUSBClose(myOutPipe);
  _MPUSBClose(myInPipe);
  myInPipe:= INVALID_HANDLE_VALUE;
  myOutPipe:=INVALID_HANDLE_VALUE;
end; //Firmwareversion auslesen
Meine Funktion gibt einfach eine andere Konstante (READ_IR) über den USB und verlangt keine Antwortbytes (RecvLength:=0, wodurch im Microcontroller einfach nur eine Funktion gestartet wird.




Wenn ihr mehr wissen braucht, einfach fragen!





P.S.
Wenn sich nun einer fragt, was ich vom ihm will: Natürlich verlange ich keine komplette Lösung, wie ich das Problem lösen kann, aber über Anregungen würde ich mich freuen...
Ich beherrsche in Delphi nur Basics, also bin kein Delphi-Guru...
Aber ich denke ich bin lernfähig ...

DANKE im Voraus...
Miniaturansicht angehängter Grafiken
unbenannt_154.jpg  
  Mit Zitat antworten Zitat