USB Command Sending

General programming chat and advice for beginners

15 posts
by webbaldo » Tue Dec 11, 2012 3:04 pm
Hello there!, been playing around with my Pi with web servers etc for a few weeks and now im looking to do the following,

I want to send USB hex commands to a usb relay I have. (Eventual home automation) I have managed to capture the Hexcode and commands for each usb function but Im not sure how to send them via the pi? Ive captured the hex info from a windows machine.

I eventually want to command the relay via webpage, but sending commands over SSH would do.

Ive been reading up, but have yet to find how to just send commands?
Posts: 8
Joined: Tue Dec 11, 2012 3:00 pm
by Schorschi » Tue Dec 11, 2012 4:15 pm
I am trying to figure this out as well, but have a much simpler scenario. I just want to turn on and off the USB port (power signal). I have a USB controlled power strip, the power strip senses the power state of the USB port it is connected into, so if I can turn on and off one of the Raspberry Pi USB ports, I can control the powerscript on and off state.
Posts: 121
Joined: Thu Nov 22, 2012 9:38 pm
by mahjongg » Tue Dec 11, 2012 4:22 pm
The power port of the PI's USB port (VCC) is hard wired to the 5V supply, you cannot control it in software. Its also not really related to the original problem of sending commands.

As for the OP, it depends on what the actual "end point" type is of the USB, is it a legacy (serial or printer-port) device, or a "human interface" device? different end points act as different virtual devices for the PI, so you have to know which virtual device you want to control.
User avatar
Moderator
Posts: 4492
Joined: Sun Mar 11, 2012 12:19 am
by webbaldo » Tue Dec 11, 2012 7:49 pm
Its an HID compliant device.
Posts: 8
Joined: Tue Dec 11, 2012 3:00 pm
by panik » Wed Dec 12, 2012 9:14 am
Check out libusb (http://www.libusb.org/). It has wrappers/bindings for various programming languages.
Posts: 222
Joined: Fri Sep 23, 2011 12:29 pm
Location: Netherlands
by webbaldo » Sat Dec 15, 2012 5:14 pm
Some progress on this, by using a windows usb logger ive got the usb device vendor and item id's.

Ive also got some hex and binary codes to send which do what I want , eg

10 80 00 00 00 00 00 00 F0 turns my item on

10 80 00 00 00 00 00 00 F0 turns it off

Ive tried having a read up with libusb but to be honest im clueless

Ive heard you can use python to send commands as well. But ive not found any example code.

So little progress but still clueless
Posts: 8
Joined: Tue Dec 11, 2012 3:00 pm
by panik » Sat Dec 15, 2012 7:36 pm
The idVendor and idProduct, and the bytes you need to send, are all you need to know. So good progress!

I'm away from my Pi at the moment, and not up to scratch with python (I use libusb directly from c++). I believe pyusb is installed with 'sudo apt-get install python-usb'.

To get started, read: http://pyusb.sourceforge.net/docs/1.0/tutorial.html

To send bytes instead of a string, read: http://stackoverflow.com/questions/6361 ... sing-pyusb (someone asked that before in another thread. I don't know how that ended).

I hope this works out for you!
Posts: 222
Joined: Fri Sep 23, 2011 12:29 pm
Location: Netherlands
by panik » Sun Dec 16, 2012 12:58 am
A bit more info. You can see the idVendor and idProduct by typing 'lsusb', or even 'lsusb -v' in the terminal.
Code: Select all
pi@raspberrypi ~ $ lsusb
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 001 Device 002: ID 0424:9512 Standard Microsystems Corp.
Bus 001 Device 003: ID 0424:ec00 Standard Microsystems Corp.
Bus 001 Device 012: ID 1337:F055 ACME corp. My USB device
pi@raspberrypi ~ $

Also, if your script or application only works with 'sudo ./scriptname.py', you can create a udev rule to make it accessible to regular users. Assuming the idVendor is '0x1337', and the idProduct '0xF055', create a text file with the following content, and name it '98-my-usb-device.rules'.
Code: Select all
SUBSYSTEM=="usb", ACTION=="add", ATTR{idVendor}=="1337", ATTR{idProduct}=="F055", GROUP="plugdev", MODE="660″

Copy the file to /etc/udev/rules.d, and restart udev services to reload the rules:
Code: Select all
sudo cp 98-my-usb-device.rules /etc/udev/rules.d/
sudo service udev restart

Unplug the device and plug it back in again, and you can run the application as a regular user.
Posts: 222
Joined: Fri Sep 23, 2011 12:29 pm
Location: Netherlands
by webbaldo » Sun Dec 16, 2012 12:29 pm
Well ive installed pyusb and can get the device detected by using

import usb.core
dev = usb.core.find(idVendor=0x12BF, idProduct=0xFF03)

Now I just need to find how to send hex commands to this device

PyUsb has less documentation and example code than most Open Source stuff!
Posts: 8
Joined: Tue Dec 11, 2012 3:00 pm
by webbaldo » Mon Dec 17, 2012 2:25 pm
Ok I assume something like

dev.ctrl_transfer(0x21,0x09,0,0,[0x02,0x20,0x00,0x00,0x00,0x00,0x00,0x00])

would work, but I dont understand what the '0x21,0x09,0,0' is, I know the rest is the hex command but what precedes it?
Posts: 8
Joined: Tue Dec 11, 2012 3:00 pm
by webbaldo » Mon Dec 17, 2012 3:20 pm
Also if it helps lsusb -v gives

Code: Select all
Bus 001 Device 007: ID 12bf:ff03
Device Descriptor:
  bLength                18
  bDescriptorType         1
  bcdUSB               1.10
  bDeviceClass            0 (Defined at Interface level)
  bDeviceSubClass         0
  bDeviceProtocol         0
  bMaxPacketSize0         8
  idVendor           0x12bf
  idProduct          0xff03
  bcdDevice            1.00
  iManufacturer           1 Matrix Multimedia Ltd.
  iProduct                2 Flowcode USB HID
  iSerial                 0
  bNumConfigurations      1
  Configuration Descriptor:
    bLength                 9
    bDescriptorType         2
    wTotalLength           41
    bNumInterfaces          1
    bConfigurationValue     1
    iConfiguration          0
    bmAttributes         0x80
      (Bus Powered)
    MaxPower               50mA
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        0
      bAlternateSetting       0
      bNumEndpoints           2
      bInterfaceClass         3 Human Interface Device
      bInterfaceSubClass      0 No Subclass
      bInterfaceProtocol      0 None
      iInterface              0
        HID Device Descriptor:
          bLength                 9
          bDescriptorType        33
          bcdHID               1.10
          bCountryCode            0 Not supported
          bNumDescriptors         1
          bDescriptorType        34 Report
          wDescriptorLength      54
          Report Descriptor: (length is 54)
            Item(Global): Usage Page, data= [ 0xa0 0xff ] 65440
                            (null)
            Item(Local ): Usage, data= [ 0x01 ] 1
                            (null)
            Item(Main  ): Collection, data= [ 0x01 ] 1
                            Application
            Item(Local ): Usage, data= [ 0x02 ] 2
                            (null)
            Item(Main  ): Collection, data= [ 0x00 ] 0
                            Physical
            Item(Global): Usage Page, data= [ 0xa1 0xff ] 65441
                            (null)
            Item(Local ): Usage, data= [ 0x03 ] 3
                            (null)
            Item(Local ): Usage, data= [ 0x04 ] 4
                            (null)
            Item(Global): Logical Minimum, data= [ 0x00 ] 0
            Item(Global): Logical Maximum, data= [ 0xff 0x00 ] 255
            Item(Global): Physical Minimum, data= [ 0x00 ] 0
            Item(Global): Physical Maximum, data= [ 0xff ] 255
            Item(Global): Report Size, data= [ 0x08 ] 8
            Item(Global): Report Count, data= [ 0x08 ] 8
            Item(Main  ): Input, data= [ 0x02 ] 2
                            Data Variable Absolute No_Wrap Linear
                            Preferred_State No_Null_Position Non_Volatile Bitfield
            Item(Local ): Usage, data= [ 0x05 ] 5
                            (null)
            Item(Local ): Usage, data= [ 0x06 ] 6
                            (null)
            Item(Global): Logical Minimum, data= [ 0x00 ] 0
            Item(Global): Logical Maximum, data= [ 0xff 0x00 ] 255
            Item(Global): Physical Minimum, data= [ 0x00 ] 0
            Item(Global): Physical Maximum, data= [ 0xff ] 255
            Item(Global): Report Size, data= [ 0x08 ] 8
            Item(Global): Report Count, data= [ 0x08 ] 8
            Item(Main  ): Output, data= [ 0x02 ] 2
                            Data Variable Absolute No_Wrap Linear
                            Preferred_State No_Null_Position Non_Volatile Bitfield
            Item(Main  ): End Collection, data=none
            Item(Main  ): End Collection, data=none
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x81  EP 1 IN
        bmAttributes            3
          Transfer Type            Interrupt
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0008  1x 8 bytes
        bInterval               5
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x01  EP 1 OUT
        bmAttributes            3
          Transfer Type            Interrupt
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0008  1x 8 bytes
        bInterval               5
Device Status:     0xd4b8
  (Bus Powered)
Posts: 8
Joined: Tue Dec 11, 2012 3:00 pm
by panik » Mon Dec 17, 2012 5:19 pm
Wow. You're right about the lack of pyusb documentation. The documentation on libusb itself might make things more clear, but it's still a minefield.
webbaldo wrote:[...]but I dont understand what the '0x21,0x09,0,0' is, I know the rest is the hex command but what precedes it?

There's a little bit on: http://pyusb.sourceforge.net/docs/1.0/tutorial.html (see the 'Talk to me, honey' part).
The first four parameters are the bmRequestType, bmRequest, wValue and wIndex fields of the standard control transfer structure.

Those are explained here: http://www.beyondlogic.org/usbnutshell/usb6.shtml

I'm sending the same values to my USB HID, so I think you're alright with the ones you have there. The bmRequestType is 0x21 (type = out to send data), and wIndex is 0x00, the first interface (your device has 1 interface). That is, if I read the lsusb -v output you posted correctly. I'm really not a USB expert, so I think I got lucky with the examples I found for libusb.
Posts: 222
Joined: Fri Sep 23, 2011 12:29 pm
Location: Netherlands
by webbaldo » Thu Dec 20, 2012 7:42 pm
ok i officially give up
Posts: 8
Joined: Tue Dec 11, 2012 3:00 pm
by tenochtitlanuk » Sat Dec 22, 2012 1:18 pm
Surely most usb devices like relay boards just need a string of ASCII codes sending.
That's just a serial-print command in Python or w.h.y. ( including any serial terminal)
I send such commands to my USB devices & run relays, LEDs & stepper motors.
It's UNUSUAL to try to program at the USB interface level. HID makes usb devices appear as serial ports (like COM ports on PC) and you read/write directly.
My current project uses such a board to step a rotating turntable to photograph objects like vases as an inverse panorama photo. Only a few lines of Python needed...
See http://www.diga.me.uk/360degreeCamera.html
Don't give up!!
Posts: 89
Joined: Fri Jul 06, 2012 8:51 pm
Location: Taunton, Somerset, UK
by gordon77 » Sat Dec 22, 2012 1:42 pm
I use an Arduino Uno and I send commnds to that via USB, it maybe a similar process ?

at terminal enter ls /dev/tty* and plug / unplug your device and see if an extra line appers, for the Uno this is ttyACM0, then modify the code to that entry.

Then try entering you string instead of ':Mgn1000' in the code, and you may need to experiment with the encode('ascii')

worth a try ?

Code: Select all
import serial
ser = serial.Serial('/dev/ttyACM0',9600)

Vcorrt = ":Mgn1000"

ser.write(bytes(Vcorrt.encode('ascii')))
Posts: 688
Joined: Sun Aug 05, 2012 3:12 pm