Jump to content
rharmon@sandia.gov

Communicate with hardware using USB HID?

Recommended Posts

Trying to communicate with a TRIPP-Lite UPS via USB port. I thought this was going to be easy, Tripp-Lite sent me the protocol, creating the words to send and what to expect for answers. I was ready to go, but now I'm seeing they use HID Protocol. Which I had never heard of, but that's not so unusual.

There is no com port, they use an ip address in the tripp-lite software. There is no network connections to the hardware so I'm guessing the ip address is being used by the software to address the USB Port.

I'm just lost, is there something in labview that addresses HID communications? Do I use VISA? Do I create a raw port and assign it a ASRL number?

Can someone point me in the right direction?

Thanks,

Bob Harmon

Share this post


Link to post
Share on other sites

So yeah I've struggled this same issue with TRIPP-Lite UPSs.  Mine luckily had a DB-9 so after investigating a bunch of time into getting a proof of concept going on the USB side, I decided to just drop it and go with the simple COM port.

NI's official method of talking to HID devices involves creating an INF driver for it, and then using that in Windows.  The problem is Windows 10 is quite restrictive when it comes to unsigned drivers, and you need to do some extra work just to install the driver, so that the hardware can be shown in MAX, so that you can start to communicate with it using raw VISA.  This isn't that big of a deal for one, but multiply this manual process by the 20+ machines I'd want to do this on and it is an issue.  Here is the process NI suggests.

At the time I did find some DLLs posted on the NI forums that wrapped communicating to HID devices so that this wasn't needed.  It was incomplete, and my knowledge of DLL calls, and C is limited so I just never found success in this method.  I don't remember the code or examples I used but here is a thread that came up when I was searching.  If you do get anything working feel free to post it.

EDIT: Oh I just saw a command line tool that might help.  I'm not in the office to test with.

Share this post


Link to post
Share on other sites

Hooovahh,

I didn't think this was going to be such a big deal... My unit also has a DB-9 so I think I'm going to go that direction.

Thanks for your help...

Bob

 

Share this post


Link to post
Share on other sites

Hooovahh,,

One quick question. When you went with the comm port (DB-9 RS232). Did you connect via com(x) and use the normal visa Write/Read commands?

Thanks,

Bob

Share this post


Link to post
Share on other sites

Yup. Just make sure you have the null of the cable correct.  Sometimes the manufacturer puts the null-ness in the device so a straight through cable should be used, some times they don't I can't remember what it is.  Some example code I posted here should get you started.

Share this post


Link to post
Share on other sites
On 5/12/2020 at 9:45 PM, rharmon@sandia.gov said:

Trying to communicate with a TRIPP-Lite UPS via USB port. I thought this was going to be easy, Tripp-Lite sent me the protocol, creating the words to send and what to expect for answers. I was ready to go, but now I'm seeing they use HID Protocol. Which I had never heard of, but that's not so unusual.

There is no com port, they use an ip address in the tripp-lite software. There is no network connections to the hardware so I'm guessing the ip address is being used by the software to address the USB Port.

I'm just lost, is there something in labview that addresses HID communications? Do I use VISA? Do I create a raw port and assign it a ASRL number?

Can someone point me in the right direction?

There is nothing out of the box. The main reason is that HID devices are normally claimed by the OS. Also HID is a low level binary protocol that says pretty much nothing at all about what data is transfered over the link, just what endpoints are involved. There are some HID sub classes such as keyboard and mice which have a specific data format to be used on the binary level but even that knows various vendor defined extensions that each vendor will implement in its own way. Other devices implementing the HID class are usually very specific to the actual device and therefore always need a custom implementation.

If you want to talk to HID devices from LabVIEW you have a few options, each with its specific drawbacks:

1) Use a shared library that implements the driver and call its functions with the Call Library Node. Advantage: No need to know the low level protocol details. Disadvantage: Shared library interface requires at least some basic C programming knowledge to be able to properly interface to it.

2) Use a HID specific shared library interface. Disadvantege: In addition to the need to know about interfacing to shared libraries you also need to implement the low level binary protocol for your device.

3) Use the VISA USB Raw protocol. Advantage: can be done all inside LabVIEW without the problems to interface to shared libraries with their non-managed C difficulties. Disadvantage: You need to implement the HID protocol and also only possible if you know the low level protocol on top of HID. You seem to have gotten that information from Tripp-Lite, so you "just" have to lookup the HID protocol specifications on usb.org and study several 100 pages of USB standard documentation to do this. The biggest drawback however is that all current desktop OSes require signed drivers in order that you can install them and that also applies to VISA INF style drivers. NI can't give you their private signing keys to let you sign such a driver and getting your own has a cost associated with it and not just a one time cost either. Disabling driver signing in the OS is still possible but requires one to jump through more and more hoops as time goes by. I expect it to soon be impossible without installing a special debug build of an OS.

4) Use of the Windows device interface API through the Call Library Node. The actual communication isn't that difficult once you have the device opened but interfacing to the setup API to enumerate, find and configure the device is a pita. The setup API is also complex enough that it pretty much requires a separate external shared library as many of the parameters are pretty complex and all but LabVIEW friendly. You still would need to implement the HID protocol itself and the also the low level device protocol in addition to the whole shared library interface for the Windows API. In terms of effort this option is by far the most complex to do.

5) using libusb or WinUSB you can communicate directly to the device too. It supports claiming devices eventhough the OS has already claimed them. libusb/WinUSB basically accesses the above mentioned Windows API and hides a lot of the complexity. You still need to interface to the shared library interface of libusb/WinUSB and you would need to implement the HID and low level device protocol on top of this.

Share this post


Link to post
Share on other sites

I'm fairly certain the purpose is to query the UPS status.  The API allows for reading the input voltage and frequency, the output voltage and frequency, the battery voltage, state of charge as a percentage, battery temperature, and if it is on battery power or not.  These UPSs have a USB port but when plugged into a Windows computer it is not recognized as a battery device like you'd typically see on a laptop.  Otherwise the normal Windows API can query the battery status.

Share this post


Link to post
Share on other sites

Thank you all for the awesome information... It is truly appreciated...

As hooovahh indicates it is to monitor the UPS health/status and know when the supply power drops out. If the power drops out, I need to safely shutdown several units before the UPS runs out of power.

As Rolf indicates it is possible to do on the USB HID port but a real pita... These units will be in distant locations and I don't want any extra complexity or reasons for it to fail.

hooovahh ended up using the DB9, RS232 port and that is the direction I intend to head.

Again, thank you all for the information... You guys are always a huge help.

Share this post


Link to post
Share on other sites

HID already tested my sanity... Sadly I failed...

Yes we looked at the relay card. I just want to get more UPS health information. These units are intended to run for years and it would be good if the user could visually see the UPS is working well.

Also as I understand it they either short or open two pins in the DB9 RS232 connector when the supply power shuts down. Again, just looking for more... As usual....

Share this post


Link to post
Share on other sites
On 5/20/2020 at 7:29 PM, rharmon@sandia.gov said:

HID already tested my sanity... Sadly I failed...

Yes we looked at the relay card. I just want to get more UPS health information. These units are intended to run for years and it would be good if the user could visually see the UPS is working well.

Also as I understand it they either short or open two pins in the DB9 RS232 connector when the supply power shuts down. Again, just looking for more... As usual....

How does the documentation look that your received from Tripp-Lite?

Share this post


Link to post
Share on other sites

very vague. I was going to enclose it, then I read I can't.

This pretty much covers configuration:

RS232 Configuration: Baud: 2400 Data: 8 bits Parity: None Start Bit: 1

This pretty much covers message format:
 
Message Format(Binary): Header Type Length Report ID Data Check Sum, Header 1byte, Type 1 byte, Length 1 byte, report ID 1 byte, Data 64 bytes max, Check Sum 1 byte.

As I understand it the header is always ~, (7E) the type is 03 (Polling command), the length is 02 (the number of bytes from report ID to data), Report ID 18 (inquire input voltage) no data so 00 and check sum is 9B (sum the bytes from header to data)

When I send (hex) 7E03 0218 009B it gets through write, but bytes returned is always 0 and read buffer is always empty. It would seem to me the UPS is not understanding the command or it's not really being written to the UPS.

I'm working from home on a laptop, so I'm using a USB to RS232 cable, I've tried two versions one from SABRENT and one from UGreen neither seems to work. Tripp-Lite told me I didn't need a null modem. So I appreciate that.
 Honestly I just noticed Message Format(Binary) so I attempted to send the request for input voltage (hex) 7E03 0218 009B as binary but that didn't work either.

As of now I'm uncertain do I have a problem with the USB to RS232 cables, the formatting of the command, or just something stupid I'm missing.  I would bet in the last one, I'm missing something stupid. Tripp-Lite refuses to get involved in any way with programming issues... Of course....

Thanks,

Bob

Share this post


Link to post
Share on other sites
11 hours ago, rharmon@sandia.gov said:

very vague. I was going to enclose it, then I read I can't.

This pretty much covers configuration:

RS232 Configuration: Baud: 2400 Data: 8 bits Parity: None Start Bit: 1

That would indicate a USB VCP, not USB HID! While the format is indeed not very descriptive as you posted, a USB VCP should be easily accessible through NI VISA.

Share this post


Link to post
Share on other sites

Yes you are right, using the RS232 com port does not utilize HID Protocol. On these UPS's if you want to use the USB port it uses HID protocol. Don't fully understand why they would make it different on the USB port.

I also agree using the RS232 port should be easy... But it's not. And that may be my fault. Working from home I don't have all the accessories I have at work. For instance since I can't communicate at all, I don't know where the fault lies. Is it my formatting of the string I'm sending, is it the USB to RS232 converter, is it something I'm not even thinking about???

My next step is to go into work and use a PXI-8430 to eliminate the USB cables.  Just straight serial cable to the UPS. If that doesn't work I'll really be lost.

I didn't state in my previous post when I write to the port it always returns 0 bytes at port and the read function times out.

Any thoughts would be appreciated...

Thanks,

Bob

418064904_UPSComms.PNG.f4d0073a86303e023da5c181138cb220.PNG

Share this post


Link to post
Share on other sites

It's always a good idea to show the code indication (Display Style) on a string constant!

 

Serial Port Initialize by default enables the message termination protocol. That is for binary protocols often not very helpful. And in that case you need to get the message length right such as reading the header until the message length, decoding the length and read the reminder plus any CRC or similar bytes.

Edited by Rolf Kalbermatter

Share this post


Link to post
Share on other sites

You did not address the other mentioned issues.1302549821_UPSComms.PNG.d3e315989f5d99c08cfc70565a032475.png.f02e6f3b14b32e290a7cba0e94c39f76.png

Assuming that the return data is constructed in the same way than the command you would need to read 3 bytes, decode the 3rd byte as length and read the remaining data + any CRC and other termination codes.

Edited by Rolf Kalbermatter

Share this post


Link to post
Share on other sites

Here is another snipit showing all the inputs and outputs.

Although the Tripp-Lite documentation doesn't address termination characters, I've tried it with and without.

I've used bytes at port and just asking for a large read, neither works

903315392_UPSComms.PNG.1a6ab315ed0367b8156bf2bf84533302.PNG

All the VI's run without errors until the Read function which in this case it gives warning about Bytes read equals bytes requested... There may still be data on the bus. Without using the Bytes at port and asking for 50 to 1024 bytes the error is a timeout.

The write return count is 6, read return count is 0

I appreciate your help... More then likely in the end I will have missed something stupid...

Thanks again,

Bob

Share this post


Link to post
Share on other sites

If you know there are no more bytes in the buffer, then you can ignore that error. That is, if the packet size is fixed, and you are receiving correctly, you don't have to reach the timeout. Also, you can set the timeout to a value less than 10 seconds, if you know that all transactions occur before the time is up. 

 

Share this post


Link to post
Share on other sites
On 5/28/2020 at 10:26 PM, rharmon@sandia.gov said:

Message Format(Binary): Header Type Length Report ID Data Check Sum, Header 1byte, Type 1 byte, Length 1 byte, report ID 1 byte, Data 64 bytes max, Check Sum 1 byte.

this is a little ambiguous.

Header Type Length Report ID Data Check Sum...Makes sense if you put commas in the right place

Header Type, Length, Report ID, Data, Check Sum.

If that was the case then a msg with no data would be something like

7E 03 02 18 9B

On 5/28/2020 at 10:26 PM, rharmon@sandia.gov said:

(sum the bytes from header to data)

Is this your interpretation or is it stated as such? Usually a checksum is a CRC. if it is a CRC-8 (there are a number of 1 byte CRCs) then the last value would be 0x29 rather than 0x9B, for example.

 

Edited by ShaunR

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.


×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.