【问题标题】:Jedi USB project read and write DelphiJedi USB项目读写Delphi
【发布时间】:2012-10-24 15:59:45
【问题描述】:

我正在使用 Jedi usb hid 组件连接到 HID 设备,并从中读取和写入。我一直无法写入设备。我一直在使用这个代码。

type
TReport = Packed record
 ReportID: byte;
 Data: array [0..64] of byte;
 end;

procedure TForm1.Button1Click(Sender: TObject);
var
 I:integer;
 HidData:TReport;
 written:DWORD;
begin
hiddata.ReportID:=0;
hiddata.Data[0]:=0;
hiddata.Data[1]:=$80;
  for I := 2 to 64 do
    hiddata.Data[I]:=$FF;
currentdevice.WriteFile(hiddata,currentdevice.Caps.OutputReportByteLength,written);
end;

【问题讨论】:

  • 您需要提供更多信息。你怎么知道你不写?怎么了?是否有错误消息、异常、GetLastError() 的值?我看到有人在没有解释原因的情况下对您投了反对票,这对他们来说不是很友好,但这就是原因 - 就目前而言,这个问题没有足够的信息来回答。
  • 在设备数据上,我输入了 label7.Caption:= hiddev.ProductName+' - '+floattostr(size) 这样我就可以检查以确保它是正确的设备,当我只运行标签时说“65”,并且他的设备没有收到命令,我知道这是因为设备可以与其他程序一起使用。

标签: delphi usb hid jedi


【解决方案1】:

我做了一个你可以使用的测试平台:

unit BasicMain; 

interface 

uses 
Windows, Messages, SysUtils, Classes, Graphics, Controls, StdCtrls, Forms, Dialogs,
JvHidControllerClass, JvComponentBase; 

type 

TReport = packed record 
  ReportID: byte; 
  Data: array [0..64] of byte; 
end; 

TMainForm = class(TForm) 
  HidCtl: TJvHidDeviceController; 
  DeviceList: TListBox; 
  Label1: TLabel; 
  Label2: TLabel; 
  Button1: TButton; 
  procedure HidCtlDeviceChange(Sender: TObject); 
  function HidCtlEnumerate(HidDev: TJvHidDevice;const Idx: Integer): Boolean; 
  procedure Button1Click(Sender: TObject); 
  procedure FormCreate( Sender : TObject);
  procedure DeviceRemoval(HidDev: TJvHidDevice); 
  procedure DeviceArrival(HidDev: TJvHidDevice); 
  public 
end; 

var 
  MainForm: TMainForm; 
  MyDevice: TJvHidDevice; 

implementation 

{$R *.dfm} 
{ ***************************************************************************** } 

Const 
  MyVendorID = $04D8;   // Put in your matching VendorID
  MyProductID = $003F;  // Put in your matching ProductID

procedure TMainForm.FormCreate( Sender : TObject);
begin
  HidCtl.OnArrival:= DeviceArrival; 
  HidCtl.OnRemoval:= DeviceRemoval; 
end;

procedure TMainForm.DeviceRemoval(HidDev: TJvHidDevice); 
begin 
  if ((Assigned(MyDevice)) and (NOT MyDevice.IsPluggedIn)) then 
  begin 
    HidCtl.CheckIn(MyDevice); 
  end; 
end; 

procedure TMainForm.DeviceArrival(HidDev: TJvHidDevice); 
begin 
  if ((HidDev.Attributes.VendorID = MyVendorID) AND 
     (HidDev.Attributes.ProductID = MyProductID) AND 
     (HidDev.Caps.OutputReportByteLength = SizeOf(TReport)) ) then 
  begin 
    if HidDev.CheckOut then 
    begin 
      MyDevice := HidDev; 
    end; 
  end; 
end; 

procedure TMainForm.HidCtlDeviceChange(Sender: TObject); 
begin 
  Label1.Caption := '-'; 
  Label2.Caption := '-'; 
  MyDevice := nil; 
  DeviceList.Clear; 
  HidCtl.Enumerate; 
end; 

function TMainForm.HidCtlEnumerate(HidDev: TJvHidDevice;const Idx: Integer): Boolean; 
begin 
  DeviceList.Items.Add( 
  Format('%.4x/%.4x', [HidDev.Attributes.VendorID,HidDev.Attributes.ProductID])); 
  if (HidDev.Attributes.VendorID = MyVendorID) and (HidDev.Attributes.ProductID =         MyProductID) then 
  begin 
    HidCtl.CheckOut(HidDev);
    MyDevice := HidDev; 
    Label1.Caption := Format('%.4x/%.4x', [MyDevice.Attributes.VendorID ,   MyDevice.Attributes.ProductID]); 
    Label2.Caption := 'Length = '+ IntToStr(MyDevice.Caps.OutputReportByteLength) + ' ' + IntToStr(MyDevice.Caps.InputReportByteLength); 
  end; 
  Result := True; 
end; 

procedure TMainForm.Button1Click(Sender: TObject); 
var 
  HidData : TReport; 
  written : DWORD; 
begin 
  HidData.ReportID:=0; 
  HidData.Data[0]:=$80;
  // Fill with more data 

  MyDevice.WriteFile(HidData, MyDevice.Caps.OutputReportByteLength, Written); 
  MyDevice.ReadFile(HidData, MyDevice.Caps.InputReportByteLength, Written); 
end; 

end. 

object MainForm: TMainForm
  Left = 0
  Top = 0
  Caption = 'MainForm'
  ClientHeight = 341
  ClientWidth = 535
  Color = clBtnFace
  Font.Charset = DEFAULT_CHARSET
  Font.Color = clWindowText
  Font.Height = -11
  Font.Name = 'Tahoma'
  Font.Style = []
  OldCreateOrder = False
  OnCreate = FormCreate
  PixelsPerInch = 96
  TextHeight = 13
  object Label1: TLabel
    Left = 48
    Top = 8
    Width = 31
    Height = 13
    Caption = 'Label1'
  end
  object Label2: TLabel
    Left = 48
    Top = 27
    Width = 31
    Height = 13
    Caption = 'Label2'
  end
  object Button1: TButton
    Left = 48
    Top = 46
    Width = 75
    Height = 25
    Caption = 'Button1'
    TabOrder = 0
    OnClick = Button1Click
  end
  object ListBox1: TListBox
    Left = 48
    Top = 96
    Width = 465
    Height = 97
    ItemHeight = 13
    TabOrder = 1
  end
end

填写您的 VendorID 和 ProductID 以及输出数据。

【讨论】:

  • 谢谢,但是 readfile 命令使程序冻结,它仍然没有到达设备。
  • 删除 ReadFile 行。将 OnDeviceData 方法和输出大小添加到某个文本标签。请告诉我们更多关于设备和状态输出数据大小和输入数据大小的信息。
  • label3.Caption:= hiddev.ProductName+' - '+Floattostr(size);我把这一行放在 OnDeviceData 中,标签标题没有改变。我的设备是 18F2550,它在收到命令时会打开或关闭继电器。我有一个可用的 VC++ 演示,这里是链接。 link
  • MyDevice.Caps.OutputReportByteLength 和 MyDevice.Caps.InputReportByteLength 的报告大小是多少?
  • 好的,那么我没有合理的解释了。您是否有 USB 协议分析仪来监控流量?有这样的软件,比如usb-monitor
【解决方案2】:

有效地用一行来判断是否接受 writefile 方法:

ToWrite := TheDev.Caps.OutputReportByteLength;
TheDev.WriteFile(buffer,towrite,written);

设备只接受正确缓冲区长度的写入。如果只写缓冲区长度的一部分,它是行不通的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-12-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-06-29
    • 1970-01-01
    相关资源
    最近更新 更多