- Subscribe to RSS Feed
- Mark as New
- Mark as Read
- Bookmark
- Subscribe
- Printer Friendly Page
- Report Inappropriate Content
Overview
This blog will show you how to setup snapcraft.yaml to access USB devices connected to ctrlX CORE. In addition to that, it shows an example of a Python snap, which uses the PyUSB module [wrapper for libusb] to read in data from a USB mouse.
You can also download the full project, which includes the providing of the mouse data on the ctrlX Data Layer, by clicking here.
Prerequisites
- Setup development environment for ctrlX AUTOMATION
- Python USB access module
pip install pyusb
- Some basic understanding of Snapcraft
- The Vendor ID and the Product ID of the connected USB device are needed to be able to access the specific device you want to read in data from. The easiest way to find these is to connect the USB device to your PC and look it up according to your OS.
- On Linux: Type in the following command in a terminal window.
usb-devices
This will show you the information about all of your connected USB devices. Just look for the corresponding device. For this example:
T: Bus=01 Lev=01 Prnt=01 Port=01 Cnt=02 Dev#= 3 Spd=1.5 MxCh= 0 D: Ver= 2.00 Cls=00(>ifc ) Sub=00 Prot=00 MxPS= 8 #Cfgs= 1 P: Vendor=17ef ProdID=608d Rev=01.00 S: Manufacturer=PixArt S: Product=Lenovo USB Optical Mouse C: #Ifs= 1 Cfg#= 1 Atr=80 MxPwr=100mA I: If#=0x0 Alt= 0 #EPs= 1 Cls=03(HID ) Sub=01 Prot=02 Driver=usbhid
- On Windows: How do I find the USB Vendor ID and Product ID?
- On Linux: Type in the following command in a terminal window.
Implementation
Here, the setup of the snapcraft.yaml file is done before the implementation of the Python script. But you can do it the other way around as well.
Snapcraft YAML File Setup
- Open a terminal window, change the working directory to where you want to build the snap and type in the following command:
snapcraft init
This should give a YAML file similiar to this:
name: my-snap-name # you probably want to 'snapcraft register <name>' base: core20 # the base snap is the execution environment for this snap version: '0.1' # just for humans, typically '1.2+git' or '1.3.2' summary: Single-line elevator pitch for your amazing snap # 79 char long summary description: | This is my-snap's description. You have a paragraph or two to tell the most important story about your snap. Keep it under 100 words though, we live in tweetspace and your description wants to look good in the snap store. grade: devel # must be 'stable' to release into candidate/stable channels confinement: devmode # use 'strict' once you have the right plugs and slots parts: my-part: # See 'snapcraft plugins' plugin: nil
- Change grade and confinement of the snap:
grade: stable confinement: strict
- Define the parts from which the snap is built and make sure to include the following packages:
parts: provider: plugin: python source: . build-packages: - libusb-1.0-0 stage-packages: - libusb-1.0-0 python-packages: - pyusb
- Define the apps provided by the snap and make sure to include at least these three plugs in order to give this snap the permissions needed to access the USB device:
apps: provider: command: bin/main.py plugs: - network - raw-usb - hardware-observe daemon: simple passthrough: restart-condition: always restart-delay: 10s
- In addition to the snapcraft.yaml file, you need to create a setup.py script for the Python plugin to work properly and define in it which Python script is supposed to be used for this project. Simple setup.py for this example:
from setuptools import setup setup(scripts = ['main.py'])
Python Script
- Import the following modules:
import usb.core import usb.util import usb.backend.libusb1
- Reference explicitly the libusb library within the snap to get access to hardware:
backend = usb.backend.libusb1.get_backend( find_library=lambda x: "/snap/my-snap-name/current/lib/aarch64-linux-gnu/libusb-1.0.so.0")
- Find the connected USB device using the Vendor ID and the Product ID from above:
dev = usb.core.find(idVendor=0x17ef, idProduct=0x608d, backend=backend)
- Get the endpoint of the device and make sure to detach the connection to the OS kernel in order to claim it for this app:
interface = 0 endpoint = dev[0].interfaces()[0].endpoints()[0] dev.reset() if dev.is_kernel_driver_active(interface): dev.detach_kernel_driver(interface) usb.util.claim_interface(dev, interface)
- Loop to read in data from the USB device more than once:
while True: try: data = dev.read(endpoint.bEndpointAddress,endpoint.wMaxPacketSize) print(data) # put your own code here # for example datalayer access to present the data except usb.core.USBError as e: data = None if e.args == ('Operation timed out',): continue
Related Topics
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.