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?
USB Command Sending
15 posts
- Posts: 8
- Joined: Tue Dec 11, 2012 3:00 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: 74
- Joined: Thu Nov 22, 2012 9:38 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.
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.
Its an HID compliant device.
- Posts: 8
- Joined: Tue Dec 11, 2012 3:00 pm
Check out libusb (http://www.libusb.org/). It has wrappers/bindings for various programming languages.
- Posts: 175
- Joined: Fri Sep 23, 2011 12:29 pm
- Location: Netherlands
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
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
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!
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: 175
- Joined: Fri Sep 23, 2011 12:29 pm
- Location: Netherlands
A bit more info. You can see the idVendor and idProduct by typing 'lsusb', or even 'lsusb -v' in the terminal.
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'.
Copy the file to /etc/udev/rules.d, and restart udev services to reload the rules:
Unplug the device and plug it back in again, and you can run the application as a regular user.
- 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: 175
- Joined: Fri Sep 23, 2011 12:29 pm
- Location: Netherlands
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!
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
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?
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
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
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.
There's a little bit on: http://pyusb.sourceforge.net/docs/1.0/tutorial.html (see the 'Talk to me, honey' part).
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.
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: 175
- Joined: Fri Sep 23, 2011 12:29 pm
- Location: Netherlands
ok i officially give up
- Posts: 8
- Joined: Tue Dec 11, 2012 3:00 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!!
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: 31
- Joined: Fri Jul 06, 2012 8:51 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 ?
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: 295
- Joined: Sun Aug 05, 2012 3:12 pm