forked from todbot/blink1
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
python: added two examples from community (this is so great!)
- Loading branch information
Showing
3 changed files
with
210 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
|
||
Using Python to control blink(1) | ||
================================ | ||
|
||
There are two ways to get Python to access blink(1): | ||
|
||
- Use the PyUSB library to construct USB HID requests | ||
- Wrap the "blink1-lib" C-library located in blink1/commandline | ||
|
||
The PyUSB is very easy to use, but creates an additional dependency for shipped code. | ||
Wrapping the C-library means you need to deal with platform-specific issues. | ||
|
||
Thanks to members of the blink(1) community, both of these techniques have working examples: | ||
|
||
- Aaron Blondeau's script "blink1hid-demo.py" shows how to construct raw HID reports | ||
that send commands to blink(1) | ||
|
||
- Stephen Youndt's script "blink1-ctypes.py" shows how to wrap the C library | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,125 @@ | ||
#/usr/bin/python | ||
""" | ||
blink1.py -- Python interface to libblink1 through the magic of ctypes | ||
import blink1 | ||
dev = blink1.open() | ||
blink1.setRGB(d, 255,0,0) # Red | ||
... | ||
Do not: | ||
from blink1 import * | ||
or you will polute your namespace with some very common names (i.e. File I/O) | ||
Make sure the "blink1-lib" shared library / DLL is in your path | ||
for more info see: | ||
https://getsatisfaction.com/thingm/topics/more_comprehensive_python_support | ||
Thanks to Stephen Youndt for this | ||
""" | ||
|
||
from ctypes import * | ||
from ctypes.util import find_library | ||
import inspect, os | ||
import glob | ||
# Find the library | ||
localpath = os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe()))) | ||
libname = find_library("blink1") | ||
if libname is None: | ||
libname = find_library("Blink1") | ||
if libname is None: | ||
libname = find_library("blink1-lib") | ||
if libname is None: | ||
libname = glob.glob(os.path.join(localpath, '[Bb]link1-lib.so'))[-1] | ||
if libname is None: | ||
libname = glob.glob(os.path.join(localpath, 'blink1-lib.dll'))[-1] | ||
if libname is None: | ||
libname = glob.glob(os.path.join(localpath, 'lib[Bb]link1*'))[-1] | ||
# If we found the library, load it | ||
assert libname is not None | ||
libblink1 = CDLL(libname) | ||
vid = libblink1.blink1_vid | ||
vid.restype = c_int | ||
pid = libblink1.blink1_pid | ||
pid.restype = c_int | ||
sortPaths = libblink1.blink1_sortPaths | ||
sortSerials = libblink1.blink1_sortSerials | ||
enumerate = libblink1.blink1_enumerate | ||
enumerate.restype = c_int | ||
enumerateByVidPid = libblink1.blink1_enumerateByVidPid | ||
enumerateByVidPid.restype = c_int | ||
enumerateByVidPid.argtypes = [c_int, c_int] | ||
getCachedPath = libblink1.blink1_getCachedPath | ||
getCachedPath.restype = c_char_p | ||
getCachedPath.argtypes = [c_int] | ||
getCachedSerial = libblink1.blink1_getCachedSerial | ||
getCachedSerial.restype = c_wchar_p | ||
getCachedSerial.argtypes = [c_int] | ||
getCachedCount = libblink1.blink1_getCachedCount | ||
getCachedCount.restype = c_int | ||
open = libblink1.blink1_open | ||
open.restype = c_void_p | ||
openByPath = libblink1.blink1_openByPath | ||
openByPath.restype = c_void_p | ||
openByPath.argtypes = [c_char_p] | ||
openBySerial = libblink1.blink1_openBySerial | ||
openBySerial.restype = c_void_p | ||
openBySerial.argtypes = [c_wchar_p] | ||
openById = libblink1.blink1_openById | ||
openById.restype = c_void_p | ||
openById.argtypes = [c_int] | ||
close = libblink1.blink1_close | ||
close.argtypes = [c_void_p] | ||
write = libblink1.blink1_write | ||
write.restype = c_int | ||
write.argtypes = [c_void_p, c_void_p, c_int] | ||
read = libblink1.blink1_read | ||
read.restype = c_int | ||
read.argtypes = [c_void_p, c_void_p, c_int] | ||
getSerialNumber = libblink1.blink1_getSerialNumber | ||
getSerialNumber.restype = c_int | ||
getSerialNumber.argtypes = [c_void_p, c_char_p] | ||
getVersion = libblink1.blink1_getVersion | ||
getVersion.restype = c_int | ||
getVersion.argtypes = [c_void_p] | ||
fadeToRGB = libblink1.blink1_fadeToRGB | ||
fadeToRGB.restype = c_int | ||
fadeToRGB.argtypes = [c_void_p, c_ushort, c_ubyte, c_ubyte, c_ubyte] | ||
setRGB = libblink1.blink1_setRGB | ||
setRGB.restype = c_int | ||
setRGB.argtypes = [c_void_p, c_ubyte, c_ubyte, c_ubyte] | ||
eeread = libblink1.blink1_eeread | ||
eeread.restype = c_int | ||
eeread.argtypes = [c_void_p, c_ushort, c_void_p] | ||
eewrite = libblink1.blink1_eewrite | ||
eewrite.restype = c_int | ||
eewrite.argtypes = [c_void_p, c_ushort, c_void_p] | ||
serialnumread = libblink1.blink1_serialnumread | ||
serialnumread.restype = c_int | ||
serialnumread.argtypes = [c_void_p, c_void_p] | ||
serialnumwrite = libblink1.blink1_serialnumwrite | ||
serialnumwrite.restype = c_int | ||
serialnumwrite.argtypes = [c_void_p, c_void_p] | ||
serverdown = libblink1.blink1_serverdown | ||
serverdown.restype = c_int | ||
serverdown.argtypes = [c_void_p, c_ubyte, c_ushort] | ||
play = libblink1.blink1_play | ||
play.restype = c_int | ||
play.argtypes = [c_void_p, c_ubyte, c_ubyte] | ||
writePatternLine = libblink1.blink1_writePatternLine | ||
writePatternLine.restype = c_int | ||
writePatternLine.argtypes = [c_void_p, c_ushort, c_ubyte, c_ubyte, c_ubyte, c_ubyte] | ||
readPatternLine = libblink1.blink1_readPatternLine | ||
readPatternLine.restype = c_int | ||
readPatternLine.argtypes = [c_void_p, c_void_p, c_void_p, c_void_p, c_void_p, c_void_p] | ||
error_msg = libblink1.blink1_error_msg | ||
error_msg.restype = c_char_p | ||
error_msg.argtypes = [c_int] | ||
enableDegamma = libblink1.blink1_enableDegamma | ||
disableDegamma = libblink1.blink1_disableDegamma | ||
degamma = libblink1.blink1_degamma | ||
degamma.restype = c_int | ||
degamma.argtypes = [c_int] | ||
sleep = libblink1.blink1_sleep | ||
sleep.argtypes = [c_ushort] | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
#!/usr/bin/python | ||
""" | ||
blink1hid-demo.py -- Low-level HID access with Python | ||
Thanks to Aaron Blondeau for this | ||
As he says: | ||
"I am working on controlling a Blink1 from an Android. | ||
In order to understand how the set feature calls work without wearing out | ||
the usb port on my Android I have created a python script that uses the pyusb library. | ||
The code is as follows if you wish to share and save some time for other folks." | ||
""" | ||
|
||
import usb # https://github.com/walac/pyusb | ||
# + "brew install libusb" on osx | ||
# + libusb-win32 (inf method) on windows | ||
|
||
#Find the Blink1 | ||
dev = usb.core.find(idVendor=0x27b8, idProduct=0x01ed) | ||
assert dev is not None | ||
|
||
#The Blink1 takes 8 bytes of input | ||
# 1=report_id (0) | ||
# 2=action (c = fade to rgb, n = set rgb now) | ||
# 3=red | ||
# 4=green | ||
# 5=blue | ||
# 6=th : time/cs high (T >>8) where time 'T' is a number of 10msec ticks | ||
# 7=tl : time/cs low (T & 0xff) | ||
# 8=step (0) | ||
|
||
# once a buffer is set with these bytes, we need to do what blink1_write / hid_send_feature_report does | ||
# https://github.com/todbot/blink1/blob/master/commandline/blink1-lib.c | ||
# https://github.com/signal11/hidapi/blob/master/libusb/hid.c | ||
|
||
#set color to red | ||
bmRequestTypeOut = usb.util.build_request_type(usb.util.CTRL_OUT, usb.util.CTRL_TYPE_CLASS, usb.util.CTRL_RECIPIENT_INTERFACE) | ||
action = 0x6E # ='n' (set rgb now) | ||
red = 0xFF | ||
green = 0x00 | ||
blue = 0x00 | ||
dev.ctrl_transfer(bmRequestTypeOut, 0x09, (3 << 8) | 0x01, 0, [0x00, action, red, green, blue, 0x00, 0x00, 0x00, 0x00]) | ||
|
||
#then fade to blue | ||
action = 0x63 # ='c' (fade to rgb) | ||
red = 0x00 | ||
green = 0x00 | ||
blue = 0xFF | ||
T = 5000/10 #5 seconds worth of 10msec tics | ||
th = (T & 0xff00) >> 8 | ||
tl = T & 0x00ff | ||
dev.ctrl_transfer(bmRequestTypeOut, 0x09, (3 << 8) | 0x01, 0, [0x00, action, red, green, blue, th, tl, 0x00, 0x00]) | ||
|
||
#get version number | ||
import time | ||
import string | ||
action = 0x76 # ='v' (version) | ||
dev.ctrl_transfer(bmRequestTypeOut, 0x09, (3 << 8) | 0x01, 0, [0x00, action, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]) | ||
time.sleep(.05) | ||
bmRequestTypeIn = usb.util.build_request_type(usb.util.CTRL_IN, usb.util.CTRL_TYPE_CLASS, usb.util.CTRL_RECIPIENT_INTERFACE) | ||
version_raw = dev.ctrl_transfer(bmRequestTypeIn, 0x01, (3 << 8) | 0x01, 0, 8) | ||
version = ''.join(chr(i) for i in version_raw) # items in the array should correspond to ascii codes for something like "v 100" | ||
version = filter(lambda x: x in string.printable, version) | ||
print version #the c code must tack on an extra 0? | ||
|