Close
0%
0%

USSSSSB: Talking USB From Python (SuperCon 2015)

This page will hold details of my workshop at Hackaday SuperCon 2015.

Similar projects worth following
Despite the low cost and wide availability of USB microcontrollers, many new designs are still using brain-dead 'USB to Serial' as a basis for their connectivity. There's a variety of reasons for this including unfamiliarity with the embedded side, the computer software, and concerns about the end-user installing drivers. This talk aims to demonstrate practical methods of achieving USB connectivity with simple and low-cost devices, along with writing cross-platform software using Python. This will include everything from simple communications to high-speed streaming on USB 2.0 (with a cameo by USB 3.0), including how to sign drivers for distribution.

By attending the workshop, you will get an Atmel D21 Evaluation Board + 2x Micro USB cables.

To follow along bring a Windows laptop with the following installed (WARNING: install can be very slow, do not attempt to do this during the workshop):
* Atmel Studio
* WinPython 2.7
* LibUSB Tools
More details:

Download the Slides

You can see the slides right here.

What you Get

You get a SAMD21 Xplained Pro board, thanks to Atmel for giving us a bunch! You also get 2x Micro USB cables for the board (not included in the standard dev kit).

What to Bring

I recommended bringing a laptop to follow along, but the workshop will move at a very rapid pace so you can also sit in and then experiment on your own time if you wish. If you don't use Windows you'll have to experiment on your own time (there is insufficient time during the workshop to cover compiling for the dev-board on Mac/Linux). Note the Python aspect is entirely cross-platform, and can run on Linux/Mac. The only issue is compiling the firmware for the SAMD21 Xplained Pro board.

If you want to follow along in the workshop, bring a Windows laptop with the following installed:

  1. Atmel Studio 7 (6.2 would also work):
  2. WinPython-2.7
  3. libusb-win32-devel-filter (NB: No need to open the filter install wizard when done)
  4. USBView
  5. Using 'pip', install pyusb & pyside (see project log for details).

As I'm trying to cover a lot of material, depending on how quickly everyone is able to follow along the workshop may not be entirely hands-on. All material will be available before, during, and after the workshop however so you will not be left out! You get to keep the SAMD21 Xplained Pro dev-kit so are free to work on this at your own leisure.

  • Update Nov 12/2015 - Install pyusb & pyside

    Colin O'Flynn11/12/2015 at 18:29 0 comments

    As a note: during the workshop, I was using live installation of PyUSB & PySide. Rather than risk errors on the network, please do this ahead of time. To do so:

    1. Navigate to your WinPython install directory
    2. Run the 'WinPython Command Prompt'
    3. Run the following commands:
      1. pip install pyusb
      2. pip install pyside

View project log

  • 1
    Step 1

    Code to find device

    import usb.core
    dev = usb.core.find(idVendor=0x03eb, idProduct=0x2402)
    print dev

    Control Endpoint Read (Slide 94)

    import usb.core
    dev = usb.core.find(idVendor=0x03eb, idProduct=0x2402)
    dev.set_configuration()
    
    data = dev.ctrl_transfer(0b10100001, 0x01, 3<<8, 0, 4)
    
    print data

    Sending Output Report

    import usb.core
    dev = usb.core.find(idVendor=0x03eb, idProduct=0x2402)
    print dev
    
    dev.set_configuration()
    
    data = [ord('1'), ord('1'), 0, 0, 0, 0, 0, 0]
    dev.write(0x02, data)

    Getting Input Report (Press "user" button for things to happen)

    import usb.core
    dev = usb.core.find(idVendor=0x03eb, idProduct=0x2402)
    print dev
    
    dev.set_configuration()
    
    for i in range(0, 10):
        while True:
            try:
                test = dev.read(0x81, 8, timeout=50)
                break
            except usb.core.USBError, e:            
                if str(e).find("timeout") >= 0:
                    pass
                else:
                    raise IOError("USB Error: %s"%str(e))
         
        print test

    Full-on GUI

    #Public domain - simple USB GUI Example by Colin O'Flynn
    
    from PySide.QtCore import *
    from PySide.QtGui import *
    import usb.core
    import sys
    
    class USBForm(QDialog):
        def __init__(self, parent=None):
            super(USBForm, self).__init__(parent)
            self.setWindowTitle("SuperCon 2015 Demo")
    
            layout = QVBoxLayout()
            self.setLayout(layout)
    
            self.pbConnect = QPushButton("Connect")
            self.pbConnect.clicked.connect(self.con)
            self.isConnected = False
    
            self.pbLED = QPushButton("LED Blinking")
            self.pbLED.setCheckable(True)
            self.pbLED.clicked.connect(self.changeLED)
            self.pbLED.setEnabled(False)
    
            layout.addWidget(self.pbConnect)
            layout.addWidget(self.pbLED)
    
            self.swStatus = QLineEdit()
            self.swStatus.setReadOnly(True)
            layout.addWidget(self.swStatus)
    
            self.butTimer = QTimer(self)
            self.butTimer.timeout.connect(self.pollButton)
    
    
        def con(self):
            if self.isConnected == False:
                #Do USB Connect Here
                self.dev = usb.core.find(idVendor=0x03eb, idProduct=0x2402)
                self.dev.set_configuration()
    
                #Sync changeLED
                self.changeLED()
                
                self.isConnected = True
                self.pbConnect.setText("Disconnect")
                self.pbLED.setEnabled(True)
                self.butTimer.start(100)
            else:
                self.isConnected = False
                self.pbConnect.setText("Connect")
                self.pbLED.setEnabled(False)
                self.butTimer.stop()
    
        def changeLED(self):
            if self.pbLED.isChecked():
                #Send command to make LED on
                self.dev.write(0x02, [ord('1'), ord('1'), 0, 0, 0, 0, 0, 0])
    
                self.pbLED.setText("LED On")            
            else:
                #Send command to make LED blink
                self.dev.write(0x02, [ord('0'), ord('1'), 0, 0, 0, 0, 0, 0])
                self.pbLED.setText("LED Blinking")
    
        def pollButton(self):
            try:
                data = self.dev.read(0x81, 8, timeout=50)
                if data[0]:
                    self.swStatus.setText("Button Pressed")
                else:
                    self.swStatus.setText("Button Released")
                    
            except usb.core.USBError, e:
                if str(e).find("timeout") >= 0:
                    pass
                else:
                    raise IOError("USB Error: %s"%str(e))
    
    
    if __name__ == "__main__":
        app = QApplication(sys.argv)
        form = USBForm()
        form.show()
        sys.exit(app.exec_())

View all instructions

Enjoy this project?

Share

Discussions

Michael Harris wrote 11/15/2015 at 18:57 point

When installing Atmel Studio, there's the option to install the toolchains (8bit, 32bit, and ARM) packs separately. Since the SAMD21 is an ARM, do we need the other two sets of tools? (not installing saves some download time/install space)

  Are you sure? yes | no

Colin O'Flynn wrote 11/15/2015 at 22:39 point

Not sure if it's too late... but you only do need the ARM tools!

  Are you sure? yes | no

Kenny Koller wrote 11/15/2015 at 04:05 point

Sorry. I'm out for tomorrow. After a couple of hours  installing Windows software I decided it's not worth it. I'll use the slides and see if I can get something working on Linux or OSX. Also, I suggest that folks learn to  use Miniconda for Python package management.  It's lightweight and you can use `conda install pip` to add pip for things it does not manage.

  Are you sure? yes | no

Colin O'Flynn wrote 11/15/2015 at 07:00 point

Ah sorry to hear it was such a hassle - at any rate if you already signed up be sure to at least grab your dev kit, as it's a fairly good dev kit for the price! If I had more time could have focused on the cross-platform development, but will be craming a ton into the time already...

  Are you sure? yes | no

Kenny Koller wrote 11/15/2015 at 16:15 point

I'll see if I can get over my Windows sulking. I do like those Atmel parts.

  Are you sure? yes | no

Matt Mills wrote 10/29/2015 at 19:37 point

Will it be possible to do this with a mac laptop and avrgcc/avrdude? Otherwise I'll need to set up a VM.  

  Are you sure? yes | no

Colin O'Flynn wrote 10/29/2015 at 20:36 point

Ah a VM is safer... it's possible for sure, BUT if you want to fully follow along there isn't time to go through that setup. I'm using the example projects from Atmel Studio 7 during the workshop, and also talk a little about debugging some of the USB stuff in Atmel Studio as well.

If the VM doesn't work, you can always try getting stuff working afterwards. The workshop is fairly fast-paced, so you won't be too bored even if just watching (I hope!).

  Are you sure? yes | no

Anthony May wrote 10/29/2015 at 18:54 point

hey Colin, I've never programmed in Python before, just microcontrollers in C & assembler. is it feasible for me to attend this?

  Are you sure? yes | no

Colin O'Flynn wrote 10/29/2015 at 20:33 point

Absolutely - some of the slides are an intro to Python! You can check out the previous slides to get an idea. Depending how much time we end up having you might need to do more on your own afterwards, I think the schedule is still a little in flux...

  Are you sure? yes | no

Anthony May wrote 10/29/2015 at 20:44 point

awesome, i'll try to do some python 101 before the day.

  Are you sure? yes | no

Similar Projects

Does this project spark your interest?

Become a member to follow this project and never miss any updates