Controling a USB device by sending HEX or ASCII commands via USB port

Hi all,
I need to control a USB connected machine with robotic arms.
And I need to say it " go this coordinate (X,Y,Z)"
However because it is not serial connected instead it is USB connected I am in trouble.
What can I do

Here is what I have
- I used USB monitor program and I exactly know which commands to send
- I have the driver (.inf) file
fatihbarutAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

warddhoogheCommented:
Do you got an SDK from the usb robotics device vendor?

Perhaps use something like this: http://www.delphipages.com/forum/showthread.php?t=211415
0
fatihbarutAuthor Commented:
hmm
0
fatihbarutAuthor Commented:
Thanks firstly,
However I heard a lot of rumors (in fact the reals) about USB ports, like they are not actual ports like serials. Because they are bus, I have to write my own device driver (which is imposible for me at the moment) and so on.

Do you really think I can send hex via the unit you referred?
0
Cloud Class® Course: SQL Server Core 2016

This course will introduce you to SQL Server Core 2016, as well as teach you about SSMS, data tools, installation, server configuration, using Management Studio, and writing and executing queries.

fatihbarutAuthor Commented:
by the way the unit you referred has some typing errors like
while i0
0
warddhoogheCommented:
i cannot guarantee it, but just lookup the usb identifier for your robotics device, set it in the USBport (in Function USBOpenDriver) and give it a try.
0
warddhoogheCommented:
i'm just trying to get you into the right direction here. i didnt make that unit, its just the missing part you need. (device driver as you call it) Have you checked with the vendor yet? they should have some SDK or examples for customers to write an interface with it.

you did install the .inf driver I assume? Check if detected and installed in device manager. you can see the identification string there.
0
fatihbarutAuthor Commented:
Yes I did actually, it is some kinda complicated.

The Vendor supports using an API of their control program instead of USB commands.
But I am not sure that API gives me the freedom I need. Therefore I am trying to use USB port
0
fatihbarutAuthor Commented:
By the way. The .inf driver is installed with no problem under Windows XP
0
Dave BaldwinFixer of ProblemsCommented:
Here http://www.faculty.iu-bremen.de/birk/lectures/PC101-2003/14usb/FINAL%20VERSION/usb_protocol.html is a description of the USB protocol.  It is a network packet protocol similar to ethernet.  You wont' be able to just send individual bytes.  If the device is connected by USB then it will receive packets.
0
fatihbarutAuthor Commented:
By the way guys

this is the function to open USB driver

Function USBOpenDriver:boolean;
begin
  // Open Device Path  \\?\USB#Vid_058b&Pid_0015#5&25ea51ff&0&1#{a5dcbf10-6530-11d2-901f-00c04fb951ed}
  USBPORT:= CreateFile('\\?\USB1', GENERIC_WRITE or GENERIC_READ,
  FILE_SHARE_WRITE or FILE_SHARE_READ, nil, OPEN_EXISTING, FILE_FLAG_OVERLAPPED OR FILE_ATTRIBUTE_NORMAL, 0);
  USBOpenDriver:= USBPORT <> INVALID_HANDLE_VALUE;
  if USBPORT = INVALID_HANDLE_VALUE then // error at open port
    begin
      result:=false;
    end else result:=true;
end;

Open in new window


and this is the path of my USB driver file

\??\USB#Vid_0c47&Pid_4000#802001789#{a5dcbf10-6530-11d2-901f-00c04fb951ed}

where and how can I implement my driver path into this function. Any idea?
0
fatihbarutAuthor Commented:
:DaveBaldwin

thanks it looks very informational, however I kinda need urgent code solution.
0
warddhoogheCommented:
line 4 USBPORT is where you will need to use your USB driver hardware identifier.
i would start with the GENERIC_READ flag and once you got it to work fine,  GENERIC_WRITE
0
fatihbarutAuthor Commented:
I thought so too however I was concerned to delete the original driver file
the function says create so if it creates that file does it deletes the old one or I am completely wrong?

in that case this would be my approach

Function USBOpenDriver:boolean;
begin
  // Open Device Path  \\?\USB#Vid_058b&Pid_0015#5&25ea51ff&0&1#{a5dcbf10-6530-11d2-901f-00c04fb951ed}
  USBPORT:= CreateFile([b]'\??\USB#Vid_0c47&Pid_4000#802001789#{a5dcbf10-6530-11d2-901f-00c04fb951ed}[/b]', GENERIC_WRITE or GENERIC_READ,
  FILE_SHARE_WRITE or FILE_SHARE_READ, nil, OPEN_EXISTING, FILE_FLAG_OVERLAPPED OR FILE_ATTRIBUTE_NORMAL, 0);
  USBOpenDriver:= USBPORT <> INVALID_HANDLE_VALUE;
  if USBPORT = INVALID_HANDLE_VALUE then // error at open port
    begin
      result:=false;
    end else result:=true;
end;

Open in new window

0
fatihbarutAuthor Commented:
I meant this

 USBPORT:= CreateFile('\??\USB#Vid_0c47&Pid_4000#802001789#{a5dcbf10-6530-11d2-901f-00c04fb951ed}', GENERIC_WRITE or GENERIC_READ,
  FILE_SHARE_WRITE or FILE_SHARE_READ, nil, OPEN_EXISTING, FILE_FLAG_OVERLAPPED OR FILE_ATTRIBUTE_NORMAL, 0);
0
warddhoogheCommented:
you arent deleting the driver file, it just enables you to 'write' or 'read' from your robotics device.

and what you just posted isnt going to compile, remove the options that you dont need. try read first.
Or better just look into using the API and save yourself alot of time.
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
Emmanuel PASQUIERFreelance Project ManagerCommented:
you crazy fool !

without a SDK and a very decent documentation from the vendor, you are NEVERgoing to reverse engineer the communication protocol needed to actually make your robot move an inch.
That is already the case with a serial COM port communication, that is all the more true with USB com. Unless you are a genius specialized in USB drivers and have insider knowledge about that specific robot, in which case you wouldn't ask for help here.

your only chance : contact the vendor and beg for a SDK (like a dll, or activeX component)
0
fatihbarutAuthor Commented:
guys this is a USB unit at least I could compile.
Do you have any idea how can I use it successfully?

unit USB;

interface
Uses SysUtils, Forms, Windows;

{******************************************************************************}
{*                       USB - Read / Write Unit                              *}
{*                          by Harald Kubovy                                  *}
{*                                                                            *}
{*  How To USE:                                                               *}
{*  Sending and Reading Data to Device:                                       *}
{*  string_result:= RWUSB('DATA TO SEND IN HEX', Read, Timeout);              *}
{*                                                                            *}
{*  EXAMPLE (ONLY SENDING):                                                   *}
{*  s:= RWUSB('FF FF FF');                                                    *}
{*                                                                            *}
{*  s is String Result of Readed Data from Device                             *}
{*  'FF FF FF' is Data to Send in Hex  (this will send FFFFFF to Device       *}
{*                                                                            *}
{*                                                                            *}
{*  EXAMPLE WITH READING AFTER WRITING:                                       *}
{*  s:= RWUSB('FFFF', 16);                                                    *}
{*                                                                            *}
(*  16 = How mutch to Read / 0 for no Reading                                 *)
{*                                                                            *}
{*  EXAMPLE WITH TIMEOUT:                                                     *}
{*  s:= RWUSB('FFFF', 16, 100);                                               *}
{*                                                                            *}
{*  100 is the Reading Timeout, Standart is 500/ms.                           *}
{*                                                                            *}
{*                                                                            *}
{* Copyright - Do whatever you whant with it  ;o)                             *}
{******************************************************************************}



type
TSetofChars = Set of Char;

  Function USBOpenDriver:boolean;
  Function USBCloseDriver:boolean;
  function USBReadText(BytesRead: cardinal; timeout: cardinal = 500): string;
  function USBReadHEX(BytesRead: cardinal; timeout: cardinal = 500): string;
  function RWUSB(frame: string; readLen:integer = 0; ReadTimeout: integer = 500; Typ : String = 'HEX') : string;
  procedure USBWriteHEX(frame: string);

implementation


{ Get Handle of DeviceDriver }
var USBPORT:Thandle = INVALID_HANDLE_VALUE;

{$HINTS OFF}
{ Open USB Driver }
Function USBOpenDriver:boolean;
begin
  // Open Device Path  \\?\USB#Vid_058b&Pid_0015#5&25ea51ff&0&1#{a5dcbf10-6530-11d2-901f-00c04fb951ed}
 USBPORT:=CreateFile('\??\USB#Vid_0c47&Pid_4000#802001789#{a5dcbf10-6530-11d2-901f-00c04fb951ed}', GENERIC_WRITE or GENERIC_READ,
  FILE_SHARE_WRITE or FILE_SHARE_READ, nil, OPEN_EXISTING, FILE_FLAG_OVERLAPPED OR FILE_ATTRIBUTE_NORMAL, 0);
  USBOpenDriver:= USBPORT <> INVALID_HANDLE_VALUE;
  if USBPORT = INVALID_HANDLE_VALUE then // error at open port
    begin
      result:=false;
    end else result:=true;
end;
{$HINTS ON}


Function USBCloseDriver:boolean;
begin
  USBCloseDriver := CloseHandle(USBPORT);
  USBPORT := INVALID_HANDLE_VALUE;
end;


function NurBestimmteZeichen (const aValue : String; aChars : TSetofChars) : String;
var
  i: Integer;
  newString : string;
begin
  newString := '';
  for i := 0 to Length(aValue) do
  begin
    if aValue[i] in aChars then
    begin
      newString := newString + aValue[i];
    end;
  end;
  result := newString;
end;



Function HexToStr(s: String): String;
Var
 i : Integer;
Begin
  Result:=''; i:=1;
  While i<Length(s) Do
  Begin
    Result:=Result+Chr(StrToIntDef('$'+Copy(s,i,2),0));
    Inc(i,2);
  End;
End;


Function StrToHex(s: String): String;
Var
  i : Integer;
Begin
  Result:='';
  If Length(s)>0 Then
    For i:=1 To Length(s) Do Result:=Result+IntToHex(Ord(s[i]),2);
End;



Function USBReadTEXT(BytesRead : dWord; timeout: cardinal = 500) : string;
var
  d: array[0..10000] of byte; {Readed Data}
  s, buffer: string;
  i, Tmp: Integer;
  Ovr : TOverlapped;
  count :cardinal; {Count = How mutch Readed Bytes}
begin
  Result := '';
  count:=0;
  Fillchar( d, sizeof(d), 0 );
  FillChar(Ovr, SizeOf(TOverlapped), 0);
  Ovr.hEvent := CreateEvent(nil, true, FALSE, nil);
  if not ReadFile(USBPORT, d, BytesRead, count, @ovr) then
    if GetLastError=Error_IO_Pending then
      if WaitForSingleObject(ovr.hEvent, timeout) = WAIT_OBJECT_0 then
        GetOverlappedResult(USBPORT, ovr, count, false)
  else CancelIo(USBPORT);
  CloseHandle(Ovr.hEvent);
  s := '';
  for i := 0 to count-1 do
  begin
    Tmp:=ord(d[i]);
    s := s + Char(Tmp);
  end;
  {Convert to String Text}
  s := strtohex(s);
  buffer:='';
  for i:=1 to length(s) do
  begin
    if Odd(i) then
    begin
      buffer := '';
      buffer := hextostr(s[i] + s[i+1]);
      buffer := NurBestimmteZeichen(buffer,['0'..'9','a'..'z','A'..'Z','.'..':',' '..'?']);
      result := result+buffer;
    end;
  end;
end;



Function USBReadHEX(BytesRead : dWord; timeout: cardinal = 500) : string;
var
  d: array[0..10000] of byte; {Readed Data}
  s: string;
  i, Tmp: Integer;
  Ovr : TOverlapped;
  count :cardinal; {Count = How mutch Readed Bytes}
begin
  Result := '';
  count:=0;
  Fillchar( d, sizeof(d), 0 );
  FillChar(Ovr, SizeOf(TOverlapped), 0);
  Ovr.hEvent := CreateEvent(nil, true, FALSE, nil);
  if not ReadFile(USBPORT, d, BytesRead, count, @ovr) then
    if GetLastError=Error_IO_Pending then
      if WaitForSingleObject(ovr.hEvent, timeout) = WAIT_OBJECT_0 then
        GetOverlappedResult(USBPORT, ovr, count, false)
  else CancelIo(USBPORT);
  CloseHandle(Ovr.hEvent);
  s := '';
  for i := 0 to count-1 do
  begin
    Tmp:=ord(d[i]);
    s := s + Char(Tmp);
  end;
  Result := strtohex(s);
end;



Function _USBWritePointerA(bp : Pointer; SizeToSend : DWord; timeout: integer) : Cardinal;
var
  Ovr : TOverlapped;
begin
    Result := 0;
    FillChar(Ovr, SizeOf(TOverlapped), 0);
    Ovr.hEvent := CreateEvent(nil, true, FALSE, nil);
    if not WriteFile(USBPort, bp^, SizeToSend, Result, @ovr) then
        if GetLastError=Error_IO_Pending then
            if WaitForSingleObject(ovr.hEvent, timeout) = WAIT_OBJECT_0 then
                GetOverlappedResult(USBPORT, ovr, Result, false)
            else CancelIo(USBPORT);
    CloseHandle(Ovr.hEvent);
end;



procedure USBWriteHEX(frame: string);
var
  BytesWritten: DWord;
begin
  while Pos(' ', FRAME) > 0 do Delete(FRAME,Pos(' ', FRAME),1);
  frame:=hextostr(frame);
  WriteFile(USBPORT, (Pchar(frame))^, SizeOf(frame), BytesWritten, nil);
end;




Function USBWritePointerA(bp : Pointer; SizeToSend : DWord) : boolean;
begin
  Result := _USBWritePointerA(bp, SizeToSend, $688) = SizeToSend;
end;



Function USBWriteStringA(SendString : String) : boolean;
var
  StrSize : Word;
begin
  StrSize := Length(SendString);
  Result := _USBWritePointerA(@SendString[1], StrSize, $688) = StrSize;
end;


function RWUSB(frame: string; readLen:integer = 0; ReadTimeout: integer = 500; Typ : String = 'HEX') : string;
begin
  while Pos(' ', FRAME) > 0 do Delete(FRAME,Pos(' ', FRAME),1);
  if length(frame) >0 then USBWriteStringA(hextostr(frame));
  Application.ProcessMessages;
  sleep(ReadTimeout);
  if (ReadLen >0) and (Typ='HEX')    then result:=USBReadHEX(readLen, ReadTimeout);
  if (ReadLen >0) and (Typ='STRING') then result:=USBReadText(readLen, ReadTimeout);
end;


end.

Open in new window

0
fatihbarutAuthor Commented:
I am not crazy fool,
I am just enthusiastic adventurer,
Besides I was feeling that I was doing something wrong,
it is good to hear it. (not in that way though)
anyway.
I have api of the device I think I should go that way

however before closing this one can anyone say the reason "Why they made USB unreachable contrary to serial bus we loved?
Any idea?
0
Emmanuel PASQUIERFreelance Project ManagerCommented:
You mean you have the API and your first move was to try and hack your way through USB direct communication ?
That is way beyond enthusiastic adventurer, I will stick with my original opinion : you crazy fool ! :o)

"Why they made USB unreachable contrary to serial bus we loved?"
there are probably a lot of very good reasons related to the technical fact that USB can hold many channels of communication in the same serial line, and that one channel for a single hardware can hold many function levels. think about hybrid hardware, that will pup-up more than one device when connected.

But one reason that is probably not the least, is that precisely that ensure that only hardware drivers developers from the vendor company can make the product work because they know precisely what to do, so support teams have much less problems with sunday developpers doing things that where not supported by the hardware limitations.
And that is good for the developper too, because with Serial COM ports vendors tended to produce only a protocol documentation and did nothing of the kind of high level object-oriented API that we now enjoy through well designed SDK, at least with the serious vendors that want to actually sell their hardware and not just show off in meetings.
0
fatihbarutAuthor Commented:
and I will stick with my opinion as Enthusiastisism, realism and know what I want.
I have searched the functions  in the API, all are designed to standart parts of the machine
But that standart parts not suitable for us and I have to move the robotic arm using X,Y,Z coordinates instead of using the api function which can just say "go to the right corner of the standart partX"
Therefore I had to dare to dive into the this deep ocean.

Hope to see you my next subject. Because I couldn't solve my problem I am just sharing the points....
0
fatihbarutAuthor Commented:
it was unlucky question
0
Dave BaldwinFixer of ProblemsCommented:
Thanks for the points.  I think you should contact the manufacturer and tell them what you want to do.  They may have an alternate way for you to do it.
0
warddhoogheCommented:
@epasquier: it's anthousiasts like fatihbarut who dont give up and want to find out all there is to find out, that end up working for the vendors making the SDK once they finish their uni :)
0
fatihbarutAuthor Commented:
at the end, yes I am doing that
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Delphi

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.