Welcome to pylibftdi’s documentation!

pylibftdi is a simple library interacting with FTDI devices to provide serial and parallel IO from Python.

Examples:

>>> from pylibftdi import BitBangDevice
>>> with BitBangDevice('FT0123') as dev:
...     dev.port |= 1
>>> # Send a MIDI 'note on' message
>>> from pylibftdi import Device
>>> with Device() as dev:
...     dev.baudrate = 31250
...     dev.write('\x90\x64\x64')

The two main use cases it serves are:

  • the need to control or monitor external equipment, for which a FTDI module may be a cheap and reliable starting point.
  • the need to interact with existing devices which are known to contain FTDI chipsets for their USB interface.

FTDI (http://www.ftdichip.com) create devices (chipsets, modules, cables etc) to interface devices to the USB port of your computer.

libftdi (http://www.intra2net.com/en/developer/libftdi/) is an open source driver to communicate with these devices, and runs on top of libusb. It works on Windows, Linux, and Mac OS X, and likely other systems too.

pylibftdi is a pure Python module which interfaces (via ctypes) to libftdi, exposing a simple file-like API to connected devices. It supports serial and parallel IO in a straight-forward way, and aims to be one of the simplest ways of interacting with the world outside your PC.

Contents

Introduction

pylibftdi is a minimal Pythonic interface to FTDI devices using libftdi.

Features:
  • Supports Python 2 and Python 3
  • Supports parallel and serial devices
  • Support for multiple devices
  • File-like interface wherever appropriate
  • Cross-platform
Limitations:
  • The API might change prior to reaching a 1.0 release.

Usage

The primary interface is the Device class in the pylibftdi package; this gives serial access on relevant FTDI devices (e.g. the UM232R), providing a file-like interface (read, write). Baudrate is controlled with the baudrate property.

If a Device instance is created with mode='t' (text mode) then read() and write() can use the given encoding (defaulting to latin-1). This doesn’t make a lot of difference on Python 2 (and can be omitted), but allows easier integration with passing unicode strings between devices in Python 3.

Multiple devices are supported by passing the desired device serial number (as a string) in the device_id parameter - this is the first parameter in both Device() and BitBangDevice() constructors. Alternatively the device ‘description’ can be given, and an attempt will be made to match this if matching by serial number fails.

Examples

>>> from pylibftdi import Device
>>>
>>> with Device(mode='t') as dev:
...     dev.baudrate = 115200
...     dev.write('Hello World')

The pylibftdi.BitBangDevice wrapper provides access to the parallel IO mode of operation through the port and direction properties. These provide an 8 bit IO port including all the relevant bit operations to make things simple.

>>> from pylibftdi import BitBangDevice
>>>
>>> with BitBangDevice('FTE00P4L') as bb:
...     bb.direction = 0x0F  # four LSB are output(1), four MSB are input(0)
...     bb.port |= 2         # set bit 1
...     bb.port &= 0xFE      # clear bit 0

There is support for a number of external devices and protocols, including interfacing with HD44780 LCDs using the 4-bit interface.

History & Motivation

This package is the result of various bits of work using FTDI’s devices, primarily for controlling external devices. Some of this is documented on the codedstructure blog, codedstructure.blogspot.com

Several other open-source Python FTDI wrappers exist, and each may be best for some projects. Some aim at closely wrapping the libftdi interface, others use FTDI’s own D2XX driver (ftd2xx) or talk directly to USB via libusb or similar (such as pyftdi).

The aim for pylibftdi is to work with libftdi, but to provide a high-level Pythonic interface. Various wrappers and utility functions are also part of the distribution; following Python’s batteries included approach, there are various interesting devices supported out-of-the-box - or at least there will be soon!

Plans

  • Add more examples: SPI devices, knight-rider effects, input devices, MIDI…
  • Perhaps add support for D2XX driver, though the name then becomes a slight liability ;)

License

Copyright (c) 2010-2015 Ben Bass <benbass@codedstructure.net>

pylibftdi is released under the MIT licence; see the file “LICENSE.txt” for information.

All trademarks referenced herein are property of their respective holders. libFTDI itself is developed by Intra2net AG. No association with Intra2net is claimed or implied, but I have found their library helpful and had fun with it…

Quick Start

Install pylibftdi

See the installation instructions for more detailed requirements, but hopefully things will work by just running the following:

$ pip install pylibftdi

Connect and enumerate FTDI devices

Connect the FTDI device to a free USB port. Run the list_devices example to enumerate connected FTDI devices:

$ python -m pylibftdi.examples.list_devices

For each connected device, this will show manufacturer, model identifier, and serial number. With a single device connected, the output maybe something like the following:

FTDI:UM232H:FTUBIOWF

Though hopefully with a different serial number, or else you’ve either stolen mine, or you are me…

Test some actual IO

Output example

Connect an LED between D0 of your bit-bang capable device and ground, via a 330 - 1K ohm resistor as appropriate.

Test the installation and functioning of pylibftdi with the following:

$ python -m pylibftdi.examples.led_flash

The LED should now flash at approximately 1Hz.

Input example

To test some input, remove any connections from the port lines initially, then run the following, which reads and prints the status of the input lines regularly:

$ python -m pylibftdi.examples.pin_read

The pin_read example is a complete command line application which can be used to monitor for particular values on the attached device pins, and output an appropriate error code on match. Repeat the above with a trailing --help for info.

Installation

Unsurprisingly, pylibftdi depends on libftdi, and installing this varies according to your operating system. Chances are that following one of the following instructions will install the required prerequisites. If not, be aware that libftdi in turn relies on libusb.

Installing pylibftdi itself is straightforward - it is a pure Python package (using ctypes for bindings), and has no dependencies outside the Python standard library for installation. Don’t expect it to work happily without libftdi installed though :-)

$ pip install pylibftdi

Depending on your environment, you may want to use either the --user flag, or prefix the command with sudo to gain root privileges.

Windows

I perform only limited testing of pylibftdi on Windows, but it should work correctly provided the requirements of libftdi and libusb are correctly installed.

Recent libftdi binaries for Windows seem to be available from the picusb project on Sourceforge. Download libftdi1-1.1_devkit_x86_x64_21Feb2014.zip or later from that site, which includes the required

Installing libraries on Windows is easier with recent versions of Python (2.7.9, 3.4+) installing pip directly, so the standard approach of pip install pylibftdi will now easily work on Windows.

Mac OS X

I suggest using homebrew to install libftdi:

$ brew install libftdi

On OS X Mavericks (and presumably future versions) Apple include a driver for FTDI devices. This needs unloading before libftdi can access FTDI devices directly. See the Troubleshooting section for instructions.

Linux

There are two steps in getting a sensible installation in Linux systems:

  1. Getting libftdi and its dependencies installed
  2. Ensuring permissions allow access to the device without requiring root privileges. Symptoms of this not being done are programs only working properly when run with sudo, giving ‘-4’ or ‘-8’ error codes in other cases.

Each of these steps will be slightly different depending on the distribution in use. I’ve tested pylibftdi on Debian Wheezy (on a Raspberry Pi), Ubuntu (various versions, running on a fairly standard ThinkPad laptop), and Arch Linux (running on a PogoPlug - one of the early pink ones).

Debian (Raspberry Pi) / Ubuntu etc

On Debian like systems (including Ubuntu, Mint, Debian, etc), the package libftdi-dev should give you what you need as far as the libftdi library is concerned:

$ sudo apt-get install libftdi-dev

The following works for both a Raspberry Pi (Debian Wheezy) and Ubuntu 12.04, getting ordinary users (e.g. ‘pi’ on the RPi) access to the FTDI device without needing root permissions:

  1. Create a file /etc/udev/rules.d/99-libftdi.rules. You will need sudo access to create this file.

  2. Put the following in the file:

    SUBSYSTEMS=="usb", ATTRS{idVendor}=="0403", ATTRS{idProduct}=="6001", GROUP="dialout", MODE="0660"
    SUBSYSTEMS=="usb", ATTRS{idVendor}=="0403", ATTRS{idProduct}=="6014", GROUP="dialout", MODE="0660"
    

Some FTDI devices may use other USB PIDs. You could try removing the match on idProduct altogether, just matching on the FTDI vendor ID. Or Use lsusb or similar to determine the exact values to use (or try checking dmesg output on device insertion / removal). udevadm monitor --environment is also helpful, but note that the environment ‘keys’ it gives are different to the attributes (filenames within /sys/devices/…) which the ATTRS will match. Perhaps ENV{} matches work just as well, though I’ve only tried matching on ATTRS.

Note that changed udev rules files will be picked up automatically by the udev daemon, but will only be acted upon on device actions, so unplug/plug in the device to check whether you’re latest rules iteration actually works :-)

See http://wiki.debian.org/udev for more on writing udev rules.

Arch Linux

The libftdi package (sensibly enough) provides the libftdi library:

$ sudo pacman -S libftdi

Similar udev rules to those above for Debian should be included (again in /etc/udev/rules.d/99-libftdi.rules or similar), though the GROUP directive should be changed to set the group to ‘users’:

SUBSYSTEMS=="usb", ATTRS{idVendor}=="0403", ATTRS{idProduct}=="6001", GROUP="users", MODE="0660"
SUBSYSTEMS=="usb", ATTRS{idVendor}=="0403", ATTRS{idProduct}=="6014", GROUP="users", MODE="0660"

Testing installation

Connect your device, and run the following (as a regular user):

$ python -m pylibftdi.examples.list_devices

If all goes well, the program should report information about each connected device. If no information is printed, but it is when run with sudo, a possibility is permissions problems - see the section under Linux above regarding udev rules.

If the above works correctly, then try the following:

$ python -m pylibftdi.examples.led_flash

Even without any LED connected, this should ‘work’ without any error - quit with Ctrl-C. Likely errors at this point are either permissions problems (e.g. udev rules not working), or not finding the device at all - although the earlier stage is likely to have failed if this were the case.

Feel free to contact me (@codedstructure) if you have any issues with installation, though be aware I don’t have much in the way of Windows systems to test.

Basic Usage

pylibftdi is a minimal Pythonic interface to FTDI devices using libftdi. Rather than simply expose all the methods of the underlying library directly, it aims to provide a simpler API for the main use-cases of serial and parallel IO, while still allowing the use of the more advanced functions of the library.

General

The primary interface is the Device class in the pylibftdi package; this gives serial access on relevant FTDI devices (e.g. the UM232R), providing a file-like interface (read, write). Baudrate is controlled with the baudrate property.

If a Device instance is created with mode='t' (text mode) then read() and write() can use the given encoding (defaulting to latin-1). This doesn’t make a lot of difference on Python 2 (and can be omitted), but allows easier integration with passing unicode strings between devices in Python 3.

Multiple devices are supported by passing the desired device serial number (as a string) in the device_id parameter - this is the first parameter in both Device() and BitBangDevice() constructors. Alternatively the device ‘description’ can be given, and an attempt will be made to match this if matching by serial number fails.

In the event that multiple devices (perhaps of identical type) have the same description and serial number, the device_index parameter may be given to open matching devices by numerical index; this defaults to zero, meaning the first matching device.

Examples

>>> from pylibftdi import Device
>>>
>>> with Device(mode='t') as dev:
...     dev.baudrate = 115200
...     dev.write('Hello World')

The pylibftdi.BitBangDevice wrapper provides access to the parallel IO mode of operation through the port and direction properties. These provide an 8 bit IO port including all the relevant bit operations to make things simple.

>>> from pylibftdi import BitBangDevice
>>>
>>> with BitBangDevice('FTE00P4L') as bb:
...     bb.direction = 0x0F  # four LSB are output(1), four MSB are input(0)
...     bb.port |= 2         # set bit 1
...     bb.port &= 0xFE      # clear bit 0

There is support for a number of external devices and protocols, specifically for interfacing with HD44780 LCDs using the 4-bit interface.

Bit-bang mode

Bit-bang mode allows the programmer direct access (both read and write) to the state of the IO lines from a compatible FTDI device.

The interface provided by FTDI is intended to mirror the type of usage on a microcontroller, and is similar to the ‘user port’ on many old 8-bit computers such as the BBC Micro and Commodore 64.

The basic model is to have two 8 bit ports - one for data, and one for ‘direction’. The data port maps each of the 8 bits to 8 independent IO signals, each of which can be configured separately as an ‘input’ or an ‘output’.

In pylibftdi, the data port is given by the port attribute of a BitBangDevice instance, and the direction control is provided by the direction attribute. Both these attributes are implemented as Python properties, so no method calls are needed on them - simple read and write in Python-land converts to read and write in the physical world seen by the FTDI device.

The direction register maps to

where each bit maps to a separate digital signal,

Read-Modify-Write

Port vs Latch

Via the augmented assignment operations, pylibftdi BitBangDevice instances support read-modify-write operations, such as arithmetic (+= etc), bitwise (&=), and other logical operations such as shift (<<=)

Examples

>>> from pylibftdi import BitBangDevice
>>>
>>> with BitBangDevice('FTE00P4L') as bb:
...     bb.direction = 0x0F  # four LSB are output(1), four MSB are input(0)
...     bb.port |= 2         # set bit 1
...     bb.port &= 0xFE      # clear bit 0


>>> with BitBangDevice() as bb:
...     bb.port = 1
...     while True:
...         # Rotate the value in bb.port
...         bb.port = ((bb.port << 1) | ((bb.port >> 8) & 1)) & 0xFF
...         time.sleep(1)

The Bus class

Dealing with bit masks and shifts gets messy quickly. Some languages such as C and C++ provide direct support for accessing bits - or series of consecutive bits - with bitfields. The Bus class provides the facility to provide a similar level of support to pylibftdi BitBangDevice classes.

As an example, consider an HD44780 LCD display. These have a data channel of either 4 or 8 bits, and a number of additional status lines - rs which acts as a register select pin - indicating whether a data byte is a command (0) or data (1), and e - clock enable.:

class LCD(object):
    """
    The UM232R/245R is wired to the LCD as follows:
       DB0..3 to LCD D4..D7 (pin 11..pin 14)
       DB6 to LCD 'RS' (pin 4)
       DB7 to LCD 'E' (pin 6)
    """
    data = Bus(0, 4)
    rs = Bus(6)
    e = Bus(7)

Serial mode

The default mode of pylibftdi devices is to behave as a serial UART device, similar to the ‘COM1’ device found on older PCs. Nowadays most PCs operate with serial devices over USB-serial adapters, which may often include their own FTDI chips. To remain compatible with the RS232 standard however, these adapters will often include level-shifting circuitry which is of no benefit in communicating with other circuits operating at the 3.3 or 5 volt levels the FTDI hardware uses.

The default serial configuration is 9600 baud, 8 data bits, 1 stop bit and no parity (sometimes referred to as 8-N-1). This is the default configuration of the old ‘COM’ devices back to the days of the original IBM PC and MS-DOS.

Setting line parameters

Changing line parameters other than the baudrate is supported via use of the underlying FTDI function calls.

The SerialDevice class

While the standard Device class supports standard read and write methods, as well as a baudrate property, further functionality is provided by the SerialDevice class, available either as a top-level import from pylibftdi or through the serial_device module. This subclasses Device and adds additional properties to access various control and handshake lines.

The following properties are available:

property meaning direction
cts Clear To Send Input
rts Ready To Send Output
dsr Data Set Ready Input
dtr Data Transmit Ready Output
ri Ring Indicator Input

Note that these lines are normally active-low, and pylibftdi makes no attempt to hide this from the user. It is impractical to try to ‘undo’ this inversion in any case, since it can be disabled in the EEPROM settings of the device. Just be aware if using these lines as GPIO that the electrical sense will be the opposite of the value read. The lines are intended to support handshaking rather than GPIO, so this is not normally an issue; if CTS is connected to RTS, then values written to RTS will be reflected in the value read from CTS.

Subclassing Device - A MIDI device

To abstract application code from the details of any particular interface, it may be helpful to subclass the Device class, providing the required configuration in the __init__ method to act in a certain way. For example, the MIDI protocol used by electronic music devices is an asynchronous serial protocol operating at 31250 baud, and with the same 8-N-1 parameters which pylibftdi defaults to.

Creating a MidiDevice subclass of Device is straightforward:

class MidiDevice(Device):
    "subclass of pylibftdi.Device configured for MIDI"

    def __init__(self, *o, **k):
        Device.__init__(self, *o, **k)
        self.baudrate = 31250

Note it is important that the superclass __init__ is called first; calling it on an uninitialised Device would fail, and even if it succeeded, the superclass __init__ method resets baudrate to 9600 anyway to ensure a consistent setup for devices which may have been previously used with different parameters.

Use of the MidiDevice class is simple - as a pylibftdi Device instance, it provides a file-based API. Simply read() and write() the data to an instance of the class:

>>> m = MidiDevice()
>>> m.write('\x90\x80\x80')
>>> time.sleep(1)
>>> m.write('\x80\x00')

Advanced Usage

libftdi function access

Three attributes of Device instances are documented which allow direct access to the underlying libftdi functionality.

  1. fdll - this is a reference to the loaded libftdi library, loaded via ctypes. This should be used with the normal ctypes protocols.

  2. ctx - this is a reference to the context of the current device context. It is managed as a raw ctypes byte-string, so can be modified if required at the byte-level using appropriate ctypes methods.

  3. ftdi_fn - a convenience function wrapper, this is the preferred method for accessing library functions for a specific device instance. This is a function forwarder to the local fdll attribute, but also wraps the device context and passes it as the first argument. In this way, using device.ftdi_fn.ft_xyz is more like the D2XX driver provided by FTDI, in which the device context is passed in at initialisation time and then the client no longer needs to care about it. A call to:

    >>> device.ftdi_fn.ft_xyz(1, 2, 3)
    

    is equivalent to the following:

    >>> device.fdll.ft_xyz(ctypes.byref(device.ctx), 1, 2, 3)
    

    but has the advantages of being shorter and not requiring ctypes to be in scope.

    incorrect operations using any of these attributes of devices are liable to crash the Python interpreter

Examples

The following example shows opening a device in serial mode, switching temporarily to bit-bang mode, then back to serial and writing a string. Why this would be wanted is anyone’s guess ;-)

>>> from pylibftdi import Device
>>>
>>> with Device() as dev:
>>>    dev.ftdi_fn.ftdi_set_bitmode(1, 0x01)
>>>    dev.write('\x00\x01\x00')
>>>    dev.ftdi_fn.ftdi_set_bitmode(0, 0x00)
>>>    dev.write('Hello World!!!')

The libftdi documentation should be consulted in conjunction with the ctypes reference for guidance on using these features.

pylibftdi questions

None of these are yet frequently asked, and perhaps they never will be… But they are still questions, and they relate to pylibftdi.

Using pylibftdi - General

Can I use pylibftdi with device XYZ?

If the device XYZ is (or uses as it’s ) an FTDI device, then possibly. A large number of devices will work, but won’t be recognised due to the limited USB Vendor and Product IDs which pylibftdi checks for.

To see the vendor / product IDs which are supported, run the following:

>>> from pylibftdi import USB_VID_LIST, USB_PID_LIST
>>> print(map(hex, USB_VID_LIST))
['0x403']
>>> print(map(hex, USB_PID_LIST))
['0x6001', '0x6010', '0x6011', '0x6014']

If a FTDI device with a VID / PID not matching the above is required, then the device’s values should be appended to the appropriate list after import:

>>> from pylibftdi import USB_PID_LIST, USB_VID_LIST, Device
>>> USB_PID_LIST.append(0x1234)
>>>
>>> dev = Device()  # will now recognise a device with PID 0x1234.

Using pylibftdi - Programming

How do I set the baudrate?

In both serial and parallel mode, the internal baudrate generator (BRG) is set using the baudrate property of the Device instance. Reading this will show the current baudrate (which defaults to 9600); writing to it will attempt to set the BRG to that value.

On failure to set the baudrate, it will remain at its previous setting.

In parallel mode, the actual bytes-per-second rate of parallel data is 16x the programmed BRG value. This is an effect of the FTDI devices themselves, and is not hidden by pylibftdi.

How do I send unicode over a serial connection?

If a Device instance is created with mode='t', then text-mode is activated. This is analogous to opening files; after all, the API is intentionally modelled on file objects whereever possible.

When text-mode is used, an encoding can be specified. The default is latin-1 for the very practical reason that it is transparent to 8-bit binary data; by default a text-mode serial connection looks just like a binary mode one.

An alternative encoding can be used provided in the same constructor call used to instantiate the Device class, e.g.:

>>> dev = Device(mode='t', encoding='utf-8')

Read and write operations will then return / take unicode values.

Whether it is sensible to try and send unicode over a ftdi connection is a separate issue… At least consider doing codec operations at a higher level in your application.

How do I use multiple-interface devices?

Some FTDI devices have multiple interfaces, for example the FT2232H has 2 and the FT4232H has four. In terms of accessing them, they can be considered as independent devices; once a connection is established to one of them, it is isolated from the other interfaces.

To select which interface to use when opening a connection to a specific interface on a multiple-interface device, use the interface_select parameter of the Device (or BitBangDevice) class constructor. The value should be one of the following values. Symbolic constants are provided in the pylibftdi namespace.

interface_select Meaning
INTERFACE_ANY (0) Any interface
INTERFACE_A (1) INTERFACE A
INTERFACE_B (2) INTERFACE B
INTERFACE_C (3) INTERFACE C
INTERFACE_D (4) INTERFACE D

You should be able to open multiple Devices with different interface_select settings. Thanks to Daniel Forer for testing multiple device support.

What is the difference between the port and latch BitBangDevice properties?

latch reflects the current state of the output latch (i.e. the last value written to the port), while port reflects input states as well. Writing to either port or latch has an identical effect, so when pylibftdi is used only for output, there is no effective difference, and port is recommended for simplicity and consistency.

The place where it does make a difference is during read-modify-write operations. Consider the following:

>>> dev = BitBangDevice()  # 1
>>> dev.direction = 0x81   # 2   # set bits 0 and 7 are output
>>> dev.port = 0           # 3
>>> for _ in range(255):   # 4
>>>     dev.port += 1      # 5   # read-modify-write operation

In this (admittedly contrived!) scenario, if one of the input lines D1..D6 were held low, then they would cause the counter to effectively ‘stop’. The += 1 operation would never actually set the bit as required (because it is an input at 0), and the highest output bit would never get set.

Using dev.latch in lines 3 and 5 above would resolve this, as the read-modify-write operation on line 5 is simply working on the in-memory latch value, rather than reading the inputs, and it would simply count up from 0 to 255 in steps of one, writing the value to the device (which would be ignored in the case of input lines).

Similar concepts exist in many microcontrollers, for example see http://stackoverflow.com/a/2623498 for a possibly better explanation, though in a slightly different context :)

If you aren’t using read-modify-write operations (e.g. augmented assignment), or you have a direction on the port of either ALL_INPUTS (0) or ALL_OUTPUTS (1), then just ignore this section and use port :)

What is the purpose of the chunk_size parameter?

While libftdi is performing I/O to the device, it is not really running Python code at all, but C library code via ctypes. If there is a significant amount of data, especially at low baud-rates, this can be a significant delay during which no Python bytecode is executed. The most obvious result of this is that no signals are delivered to the Python process during this time, and interrupt signals (Ctrl-C) will be ignored.

Try the following:

>>> dev = Device()
>>> dev.baudrate = 120  # nice and slow!
>>> dev.write('helloworld' * 1000)

This should take approximately 10 seconds prior to returning, and crucially, Ctrl-C interruptions will be deferred for all that time. By setting chunk_size on the device (which may be set either as a keyword parameter during Device instantiation, or at a later point as an attribute of the Device instance), the I/O operations are performed in chunks of at most the specified number of bytes. Setting it to 0, the default value, disables this chunking.

Repeat the above command but prior to the write operation, set dev.chunk_size = 10. A Ctrl-C interruption should now kick-in almost instantly. There is a performance trade-off however; if using chunk_size is required, set it as high as is reasonable for your application.

Using pylibftdi - Interfacing

How do I control an LED?

pylibftdi devices generally have sufficient output current to sink or source the 10mA or so which a low(ish) current LED will need. A series resistor is essential to protect both the LED and the FTDI device itself; a value between 220 and 470 ohms should be sufficient depending on required brightness / LED efficiency.

How do I control a higher current device?

FTDI devices will typically provide a few tens of milli-amps, but beyond that things either just won’t work, or the device could be damaged. For medium current operation, a standard bipolar transistor switch will suffice; for larger loads a MOSFET or relay should be used. (Note a relay will require a low-power transistor switch anyway). Search online for something like ‘mosfet logic switch’ or ‘transistor relay switch’ for more details.

What is the state of an unconnected input pin?

This depends on the device and the EEPROM configuration values. Most devices will have weak (typ. 200Kohm) pull-ups on input pins, so there is no harm leaving them floating. Consult the datasheet for your device for definitive information, but you can always just leave an (unconnected) device and read it’s pins when set as inputs; chances are they will read 255 / 0xFF:

>>> dev = BitBangDevice(direction=0)
>>> dev.port
255

While not recommended for anything serious, this does allow the possibility of reading a input switch state by simply connecting a switch between an input pin and ground (possibly with a low value - e.g. 100 ohm - series resistor to prevent accidents should it be set to an output and set high…). Note that with a normal push-to-make switch, the value will read ‘1’ when the switch is not pressed; pressing it will set the input line value to ‘0’.

Developing pylibftdi

How do I checkout and use the latest development version?

pylibftdi is currently developed with a Mercurial repository on bitbucket. To use / develop on that version, it must first be cloned locally, after which it can be ‘installed’. Clone the repository to a local directory and install (with the ‘develop’ target ideally) as follows:

$ hg clone http://bitbucket.org/codedstructure/pylibftdi
$ cd pylibftdi
$ python setup.py develop

If permission-related issues occur, then consider using the --user flag to setup.py to install for only the local user, or try prefixing the above command with sudo.

Note for now there is only the master branch, so need to worry about which branch is required.

How do I run the tests?

Tests aren’t included in the distutils distribution, so clone the repository and run from there. pylibftdi supports Python 2.6/2.7 as well as Python 3.2+, so these tests can be run for each Python version:

$ hg clone http://bitbucket.org/codedstructure/pylibftdi
<various output stuff>
$ cd pylibftdi
$ python2.7 -m unittest discover
................
----------------------------------------------------------------------
Ran 17 tests in 0.011s

OK
$ python3.3 -m unittest discover
................
----------------------------------------------------------------------
Ran 17 tests in 0.015s

OK
$

How can I determine and select the underlying libftdi library?

Since pylibftdi 0.12, the Driver exposes a libftdi_version method, which returns a tuple whose first three entries correspond to major, minor, and micro versions of the libftdi driver being used.

With the recent (early 2013) release of libftdi1 - which can coexist with the earlier 0.x versions - it is now possible to select which library to load when instantiating the Driver:

Python 2.7.2 (default, Jun 20 2012, 16:23:33)
[GCC 4.2.1 Compatible Apple Clang 4.0 (tags/Apple/clang-418.0.60)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> from pylibftdi import Driver
>>> Driver().libftdi_version()
(1, 0, 0, '1.0', 'v1.0-6-gafb9082')
>>> Driver('ftdi').libftdi_version()
(0, 99, 0, '0.99', 'v0.17-305-g50d77f8')
>>> Driver('libftdi1').libftdi_version()
(1, 0, 0, '1.0', 'v1.0-6-gafb9082')
>>> Driver(('libftdi1', 'libftdi')).libftdi_version()
(1, 0, 0, '1.0', 'v1.0-6-gafb9082')
>>> Driver(('libftdi', 'libftdi1')).libftdi_version()
(0, 99, 0, '0.99', 'v0.17-305-g50d77f8')
>>> Driver(('libftdi', 'libftdi1')).libftdi_version()

pylibftdi now prefers libftdi1 over libftdi, if both are installed. Since different OSs require different parameters to be given to find a library, the default search list given to ctypes.util.find_library is as follows:

Driver._dll_list = ('ftdi1', 'libftdi1', 'ftdi', 'libftdi')

This covers Windows (which requires the ‘lib’ prefix), Linux (which requires its absence), and Mac OS X, which is happy with either.

pylibftdi troubleshooting

Once up-and-running, pylibftdi is designed to be very simple, but sometimes getting it working in the first place can be more difficult.

Error messages

FtdiError: unable to claim usb device. Make sure the default FTDI driver is not in use (-5)

This indicates a conflict with FTDI’s own drivers, and is (as far as I know) mainly a problem on Mac OS X, where they can be disabled (until reboot) by unloading the appropriate kernel module.

OS X Mavericks, Yosemite and later

Starting with OS X Mavericks, OS X includes kernel drivers which will reserve the FTDI device by default. This needs unloading before libftdi will be able to communicate with the device:

sudo kextunload -bundle-id com.apple.driver.AppleUSBFTDI

Similarly to reload it:

sudo kextload -bundle-id com.apple.driver.AppleUSBFTDI

OS X Mountain Lion and earlier

Whereas Mavericks includes an FTDI driver directly, earlier versions of OS X did not, and if this issue occurred it would typically as a result of installing some other program - for example the Arduino IDE.

As a result, the kernel module may have different names, but FTDIUSBSerialDriver.kext is the usual culprit. Unload the kernel driver as follows:

sudo kextunload /System/Library/Extensions/FTDIUSBSerialDriver.kext

To reload the kernel driver, do the following:

sudo kextload /System/Library/Extensions/FTDIUSBSerialDriver.kext

If you aren’t using whatever program might have installed it, the driver could be permanently removed (to prevent the need to continually unload it), but this is dangerous:

sudo rm /System/Library/Extensions/FTDIUSBSerialDriver.kext

Scripts are installed to perform these actions which are installed with pylibftdi; run ftdi_osx_driver_unload to unload the kernel driver and ftdi_osx_driver_reload to reload it. These commands are useful when other programs require frequent access to FTDI devices; the Arduino IDE running with FTDI devices (note many newer Arduino models use native USB rather than FTDI interfaces).

Diagnosis

Getting a list of USB devices

Mac OS X

Start ‘System Information’, then select Hardware > USB, and look for your device. On the command line, system_profiler SPUSBDataType can be used. In the following example I’ve piped it into grep -C 7 FTDI, to print 7 lines either side of a match on the string ‘FTDI’:

ben$ system_profiler SPUSBDataType | grep -C 7 FTDI
        UM232H:

          Product ID: 0x6014
          Vendor ID: 0x0403  (Future Technology Devices International Limited)
          Version: 9.00
          Serial Number: FTUBIOWF
          Speed: Up to 480 Mb/sec
          Manufacturer: FTDI
          Location ID: 0x24710000 / 7
          Current Available (mA): 500
          Current Required (mA): 90

        USB Reader:

          Product ID: 0x4082

Linux

Use lsusb. Example from my laptop:

ben@ben-laptop:~$ lsusb
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 002 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 003 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 004 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 005 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 006 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 007 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 008 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 008 Device 011: ID 0a5c:217f Broadcom Corp. Bluetooth Controller
Bus 002 Device 009: ID 17ef:481d Lenovo
Bus 002 Device 016: ID 0403:6014 Future Technology Devices International, Ltd FT232H Single HS USB-UART/FIFO IC

Where did my ttyUSB devices go?

When a pylibftdi.Device() is opened, any kernel device which was previously present will become unavailable. On Linux for example, a serial-capable FTDI device will (via the ftdi_sio driver) create a device node such as /dev/ttyUSB0 (or ttyUSB1,2,3 etc). This device allows use of the FTDI device as a simple file in the Linux filesystem which can be read and written. Various programs such as the Arduino IDE (at least when communicating with some board variants) and libraries such as PySerial will use this device. Once libftdi opens a device, the corresponding entry in /dev/ will disappear. Prior to pylibftdi version 0.16, the simplest way to get the device node to reappear would be to unplug and replug the USB device itself. Starting from 0.16, this should no longer be necessary as the kernel driver (which exports /dev/ttyUSB…) is reattached when the pylibftdi device is closed. This behaviour can be controlled by the auto_detach argument (which is defaulted to True) to the Device class; setting it to False reverts to the old behaviour.

Note that on recent OS X, libftdi doesn’t ‘steal’ the device, but instead refuses to open it. The kernel devices can be seen as /dev/tty.usbserial-xxxxxxxx, where xxxxxxxx is the device serial number. FTDI’s Application Note AN134 details this further (see section ‘Using Apple-provided VCP or D2XX with OS X 10.9 & 10.10’). See the section above under Installation for further details on resolving this.

Gathering information

Starting with pylibftdi version 0.15, an example script to gather system information is included, which will help in any diagnosis required.

Run the following:

python -m pylibftdi.examples.info

this will output a range of information related to the versions of libftdi libusb in use, as well as the system platform and Python version, for example:

pylibftdi version     : 0.16.1
libftdi version       : libftdi_version(major=1, minor=3, micro=0, version_str=b'1.3', snapshot_str=b'unknown')
libftdi library name  : /usr/local/lib/libftdi1.dylib
libusb version        : libusb_version(major=1, minor=0, micro=21, nano=11156, rc=b'', describe=b'http://libusb.info')
libusb library name   : /usr/local/lib/libusb-1.0.dylib
Python version        : 3.6.2
OS platform           : Darwin-16.7.0-x86_64-i386-64bit

pylibftdi Package

pylibftdi Package

pylibftdi - python wrapper for libftdi

Copyright (c) 2010-2017 Ben Bass <benbass@codedstructure.net> See LICENSE file for details and (absence of) warranty

pylibftdi: http://bitbucket.org/codedstructure/pylibftdi

libftdi can be found at: http://www.intra2net.com/en/developer/libftdi/

Neither libftdi nor Intra2net are associated with this project; if something goes wrong here, it’s almost definitely my fault rather than a problem with the libftdi library.

_base Module

pylibftdi - python wrapper for libftdi

Copyright (c) 2010-2015 Ben Bass <benbass@codedstructure.net> See LICENSE file for details and (absence of) warranty

pylibftdi: http://bitbucket.org/codedstructure/pylibftdi

exception pylibftdi._base.FtdiError[source]

Bases: exceptions.Exception

exception pylibftdi._base.LibraryMissingError[source]

Bases: pylibftdi._base.FtdiError

device Module

pylibftdi.device - access to individual FTDI devices

Copyright (c) 2010-2018 Ben Bass <benbass@codedstructure.net> See LICENSE file for details and (absence of) warranty

pylibftdi: http://bitbucket.org/codedstructure/pylibftdi

class pylibftdi.device.Device(device_id=None, mode='b', encoding='latin1', interface_select=None, device_index=0, **kwargs)[source]

Bases: object

Represents a connection to a single FTDI device

__init__(device_id=None, mode='b', encoding='latin1', interface_select=None, device_index=0, **kwargs)[source]

Device([device_id[, mode, [OPTIONS …]]) -> Device instance

represents a single FTDI device accessible via the libftdi driver. Supports a basic file-like interface (open/close/read/write, context manager support).

Parameters:
  • device_id – an optional serial number of the device to open. if omitted, this refers to the first device found, which is convenient if only one device is attached, but otherwise fairly useless.
  • mode – either ‘b’ (binary) or ‘t’ (text). This primarily affects Python 3 calls to read() and write(), which will accept/return unicode strings which will be encoded/decoded according to the given…
  • encoding – the codec name to be used for text operations.
  • interface_select – select interface to use on multi-interface devices
  • device_index – optional index of the device to open, in the event of multiple matches for other parameters (PID, VID, device_id). Defaults to zero (the first device found).

The following parameters are only available as keyword parameters and override class attributes, so may be specified in subclasses.

Parameters:
  • lazy_open – if True, then the device will not be opened immediately - the user must perform an explicit open() call prior to other operations.
  • chunk_size – if non-zero, split read and write operations into chunks of this size. With large or slow accesses, interruptions (i.e. KeyboardInterrupt) may not happen in a timely fashion.
  • auto_detach – default True, whether to automatically re-attach the kernel driver on device close.
close()[source]

close our connection, free resources

flush(flush_what=1)[source]

Instruct the FTDI device to flush its FIFO buffers

By default both the input and output buffers will be flushed, but the caller can selectively chose to only flush the input or output buffers using flush_what:

Parameters:flush_what – select what to flush: FLUSH_BOTH (default); FLUSH_INPUT (just the rx buffer); FLUSH_OUTPUT (just the tx buffer)
flush_input()[source]

flush the device input buffer

flush_output()[source]

flush the device output buffer

get_error_string()[source]
Returns:error string from libftdi driver
next()
open()[source]

open connection to a FTDI device

read(length) → bytes/string of up to `length` bytes.[source]

read upto length bytes from the FTDI device :param length: maximum number of bytes to read :return: value read from device :rtype: bytes if self.mode is ‘b’, else decode with self.encoding

readline(size=0)[source]

readline() for file-like compatibility.

Parameters:size – maximum amount of data to read looking for a line
Returns:a line of text, or size bytes if no line-ending found

This only works for mode=’t’ on Python3

readlines(sizehint=None)[source]

readlines() for file-like compatibility.

write(data) → count of bytes actually written[source]

write given data string to the FTDI device

Parameters:data (string or bytes) – string to be written
Returns:count of bytes written, which may be less than len(data)
writelines(lines)[source]

writelines for file-like compatibility.

Parameters:lines – sequence of lines to write
auto_detach = True
baudrate

get or set the baudrate of the FTDI device. Re-read after setting to ensure baudrate was accepted by the driver.

chunk_size = 0
closed

The Python file API defines a read-only ‘closed’ attribute

ftdi_fn

this allows the vast majority of libftdi functions which are called with a pointer to a ftdi_context struct as the first parameter to be called here preventing the need to leak self.ctx into the user code (and import byref from ctypes):

>>> with Device() as dev:
...     # set 8 bit data, 2 stop bits, no parity
...     dev.ftdi_fn.ftdi_set_line_property(8, 2, 0)
...
lazy_open = False
softspace = 0
class pylibftdi.device.ftdi_context_partial[source]

Bases: _ctypes.Structure

libusb_context

Structure/Union member

libusb_device_handle

Structure/Union member

driver Module

pylibftdi.driver - interface to the libftdi library

Copyright (c) 2010-2014 Ben Bass <benbass@codedstructure.net> See LICENSE file for details and (absence of) warranty

pylibftdi: http://bitbucket.org/codedstructure/pylibftdi

class pylibftdi.driver.Driver(libftdi_search=None)[source]

Bases: object

This is where it all happens… We load the libftdi library, and use it.

__init__(libftdi_search=None)[source]
Parameters:libftdi_search (string or sequence of strings) – force a particular version of libftdi to be used can specify either library name(s) or path(s)
libftdi_version()[source]
Returns:the version of the underlying library being used
Return type:tuple (major, minor, micro, version_string, snapshot_string)
libusb_version()[source]
Returns:namedtuple containing version info on libusb
list_devices()[source]
Returns:(manufacturer, description, serial#) for each attached device, e.g.:

[(‘FTDI’, ‘UM232R USB <-> Serial’, ‘FTE4FFVQ’), (‘FTDI’, ‘UM245R’, ‘FTE00P4L’)]

Return type:a list of string triples

the serial number can be used to open specific devices

fdll

ctypes DLL referencing the libftdi library

This is the main interface to FTDI functionality.

class pylibftdi.driver.ftdi_device_list[source]

Bases: _ctypes.Structure

dev

Structure/Union member

next

Structure/Union member

class pylibftdi.driver.ftdi_version_info[source]

Bases: _ctypes.Structure

major

Structure/Union member

micro

Structure/Union member

minor

Structure/Union member

snapshot_str

Structure/Union member

version_str

Structure/Union member

class pylibftdi.driver.libftdi_version(major, minor, micro, version_str, snapshot_str)

Bases: tuple

major

Alias for field number 0

micro

Alias for field number 2

minor

Alias for field number 1

snapshot_str

Alias for field number 4

version_str

Alias for field number 3

class pylibftdi.driver.libusb_version(major, minor, micro, nano, rc, describe)

Bases: tuple

describe

Alias for field number 5

major

Alias for field number 0

micro

Alias for field number 2

minor

Alias for field number 1

nano

Alias for field number 3

rc

Alias for field number 4

class pylibftdi.driver.libusb_version_struct[source]

Bases: _ctypes.Structure

describe

Structure/Union member

major

Structure/Union member

micro

Structure/Union member

minor

Structure/Union member

nano

Structure/Union member

rc

Structure/Union member

bitbang Module

pylibftdi - python wrapper for libftdi

Copyright (c) 2010-2014 Ben Bass <benbass@codedstructure.net> See LICENSE file for details and (absence of) warranty

pylibftdi: http://bitbucket.org/codedstructure/pylibftdi

class pylibftdi.bitbang.BitBangDevice(device_id=None, direction=255, lazy_open=False, sync=True, bitbang_mode=1, interface_select=None, **kwargs)[source]

Bases: pylibftdi.device.Device

simple subclass to support bit-bang mode

Internally uses async mode at the moment, but provides a ‘sync’ flag (defaulting to True) which controls the behaviour of port reading and writing - if set, the FIFOs are ignored (read) or cleared (write) so operations will appear synchronous

Adds three read/write properties to the base class:

direction: 8 bit input(0)/output(1) direction control. port: 8 bit IO port, as defined by direction. latch: 8 bit output value, allowing e.g. bb.latch += 1 to make sense

when there is a mix of input and output lines
__init__(device_id=None, direction=255, lazy_open=False, sync=True, bitbang_mode=1, interface_select=None, **kwargs)[source]

Device([device_id[, mode, [OPTIONS …]]) -> Device instance

represents a single FTDI device accessible via the libftdi driver. Supports a basic file-like interface (open/close/read/write, context manager support).

Parameters:
  • device_id – an optional serial number of the device to open. if omitted, this refers to the first device found, which is convenient if only one device is attached, but otherwise fairly useless.
  • mode – either ‘b’ (binary) or ‘t’ (text). This primarily affects Python 3 calls to read() and write(), which will accept/return unicode strings which will be encoded/decoded according to the given…
  • encoding – the codec name to be used for text operations.
  • interface_select – select interface to use on multi-interface devices
  • device_index – optional index of the device to open, in the event of multiple matches for other parameters (PID, VID, device_id). Defaults to zero (the first device found).

The following parameters are only available as keyword parameters and override class attributes, so may be specified in subclasses.

Parameters:
  • lazy_open – if True, then the device will not be opened immediately - the user must perform an explicit open() call prior to other operations.
  • chunk_size – if non-zero, split read and write operations into chunks of this size. With large or slow accesses, interruptions (i.e. KeyboardInterrupt) may not happen in a timely fashion.
  • auto_detach – default True, whether to automatically re-attach the kernel driver on device close.
open()[source]

open connection to a FTDI device

read_pins()[source]

read the current ‘actual’ state of the pins

Returns:8-bit binary representation of pin state
Return type:int
direction

get or set the direction of each of the IO lines. LSB=D0, MSB=D7 1 for output, 0 for input

latch

latch property - the output latch (in-memory representation of output pin state)

Note _latch is not masked by direction (except on initialisation), as otherwise a loop incrementing a mixed input/output port would not work, as it would ‘stop’ on input pins. This is the primary use case for ‘latch’. It’s basically a port which ignores input.

Returns:the state of the output latch
port

get or set the state of the IO lines. The value of output lines is persisted in this object for the purposes of reading, so read-modify-write operations (e.g. drv.port+=1) are valid.

serial_device Module

pylibftdi - python wrapper for libftdi

Copyright (c) 2010-2014 Ben Bass <benbass@codedstructure.net> See LICENSE file for details and (absence of) warranty

pylibftdi: http://bitbucket.org/codedstructure/pylibftdi

class pylibftdi.serial_device.SerialDevice(device_id=None, mode='b', encoding='latin1', interface_select=None, device_index=0, **kwargs)[source]

Bases: pylibftdi.device.Device

simple subclass to support serial(rs232) lines

cts, dsr, ri - input dtr, rts - output modem_status - return a two byte bitfield of various values

Note: These lines are all active-low by default, though this can be changed in the EEPROM settings. pylibftdi does not attempt to hide these settings, and simply writes out the given values (i.e. ‘1’ will typically make an output line ‘active’ - and therefore low)

cts

get the state of CTS (1 = ‘active’)

dsr

get the state of DSR (1 = ‘active’)

dtr

set (or get the previous set) state of the DTR line

Returns:the state of the DTR line; None if not previously set
modem_status

Layout of the first byte: B0..B3 - must be 0 B4 Clear to send (CTS) 0 = inactive 1 = active B5 Data set ready (DTS) 0 = inactive 1 = active B6 Ring indicator (RI) 0 = inactive 1 = active B7 Receive line signal detect (RLSD) 0 = inactive 1 = active

Layout of the second byte: B0 Data ready (DR) B1 Overrun error (OE) B2 Parity error (PE) B3 Framing error (FE) B4 Break interrupt (BI) B5 Transmitter holding register (THRE) B6 Transmitter empty (TEMT) B7 Error in RCVR FIFO

‘{:016b}’.format(d.modem_status) ‘0110000000000001’ - b5,b6 set in MSB (‘2nd byte’), b0 set in first byte (despite the libftdi docs saying this shouldn’t be set)

ri

get the state of RI (1 = ‘active’)

rts

set (or get the previous set) state of the RTS line

Returns:the state of the RTS line; None if not previously set

util Module

pylibftdi - python wrapper for libftdi

Copyright (c) 2010-2014 Ben Bass <benbass@codedstructure.net> See LICENSE file for details and (absence of) warranty

pylibftdi: http://bitbucket.org/codedstructure/pylibftdi

class pylibftdi.util.Bus(offset, width=1)[source]

Bases: object

This class is a descriptor for a bus of a given width starting at a given offset (0 = LSB). The device which does the actual reading and writing is assumed to be a BitBangDevice instance in the ‘device’ attribute of the object to which this is attached.

__init__(offset, width=1)[source]

x.__init__(…) initializes x; see help(type(x)) for signature

Subpackages

examples Package

examples Package

pylibftdi examples

bit_server Module

bit_server.py - remote HTTP interface to bit-bangged FTDI port This runs as a web server, connect to port 8008

Change HTTP_PORT for different port number or supply alternate as args[1]

Requires:
  • pylibftdi
class pylibftdi.examples.bit_server.ReqHandler(request, client_address, server)[source]

Bases: BaseHTTPServer.BaseHTTPRequestHandler

do_GET()[source]
do_POST()[source]
send_head()[source]
class pylibftdi.examples.bit_server.ThreadingServer(server_address, RequestHandlerClass, bind_and_activate=True)[source]

Bases: SocketServer.ThreadingMixIn, BaseHTTPServer.HTTPServer

pylibftdi.examples.bit_server.get_page()[source]
pylibftdi.examples.bit_server.runserver(port=8008)[source]
lcd Module

Write a string (argv[1] if run from command line) to a HD44780 LCD module connected via a FTDI UM232R/245R module using pylibftdi

example usage:

# while true; > do python lcd.py $( awk ‘{print $1}’ /proc/loadavg); > sleep 5; > done

Copyright (c) 2010-2014 Ben Bass <benbass@codedstructure.net> All rights reserved.

class pylibftdi.examples.lcd.LCD(device)[source]

Bases: object

The UM232R/245R is wired to the LCD as follows:
DB0..3 to LCD D4..D7 (pin 11..pin 14) DB6 to LCD ‘RS’ (pin 4) DB7 to LCD ‘E’ (pin 6)
__init__(device)[source]

x.__init__(…) initializes x; see help(type(x)) for signature

init_four_bit()[source]

set the LCD’s 4 bit mode, since we only have 8 data lines and need at least 2 to strobe data into the module and select between data and commands.

write_cmd(x)[source]
write_data(x)[source]
data

This class is a descriptor for a bus of a given width starting at a given offset (0 = LSB). The device which does the actual reading and writing is assumed to be a BitBangDevice instance in the ‘device’ attribute of the object to which this is attached.

e

This class is a descriptor for a bus of a given width starting at a given offset (0 = LSB). The device which does the actual reading and writing is assumed to be a BitBangDevice instance in the ‘device’ attribute of the object to which this is attached.

rs

This class is a descriptor for a bus of a given width starting at a given offset (0 = LSB). The device which does the actual reading and writing is assumed to be a BitBangDevice instance in the ‘device’ attribute of the object to which this is attached.

pylibftdi.examples.lcd.display(string, device_id=None)[source]

Display the given string on an attached LCD an optional device_id can be given.

led_flash Module

Flash an LED connected via a FTDI UM232R/245R module using pylibftdi

Optionally supply a flash rate (in Hz, default 1) as an argument

Copyright (c) 2010-2014 Ben Bass <benbass@codedstructure.net> All rights reserved.

pylibftdi.examples.led_flash.flash_forever(rate)[source]

toggle bit zero at rate Hz

pylibftdi.examples.led_flash.main()[source]
list_devices Module

Report connected FTDI devices. This may be useful in obtaining serial numbers to use as the device_id parameter of the Device() constructor to communicate with a specific device when more than one is present.

example usage:

$ python pylibftdi/examples/list_devices.py FTDI:UB232R:FTAS1UN5 FTDI:UM232R USB <-> Serial:FTE4FFVQ

To open a device specifically to communicate with the second of these devices, the following would be used:

>>> from pylibftdi import Device
>>> dev = Device(device_id="FTE4FFVQ")
>>>

Copyright (c) 2011-2014 Ben Bass <benbass@codedstructure.net> All rights reserved.

pylibftdi.examples.list_devices.get_ftdi_device_list()[source]

return a list of lines, each a colon-separated vendor:product:serial summary of detected devices

pylibftdi.examples.list_devices.main()[source]
magic_candle Module
Magic Candle - light falling on the LDR turns on the LED, which due
to arrangement keeps the LED on until LDR/LED path is blocked

LDR (via a transistor switch - dark = ‘1’) - D0 LED (via series resistor) - D1

pylibftdi - codedstructure 2013-2014

class pylibftdi.examples.magic_candle.Candle[source]

Bases: object

__init__()[source]

x.__init__(…) initializes x; see help(type(x)) for signature

run()[source]
be_light

This class is a descriptor for a bus of a given width starting at a given offset (0 = LSB). The device which does the actual reading and writing is assumed to be a BitBangDevice instance in the ‘device’ attribute of the object to which this is attached.

is_dark

This class is a descriptor for a bus of a given width starting at a given offset (0 = LSB). The device which does the actual reading and writing is assumed to be a BitBangDevice instance in the ‘device’ attribute of the object to which this is attached.

midi_output Module
class pylibftdi.examples.midi_output.MidiDevice(*o, **k)[source]

Bases: pylibftdi.device.Device

__init__(*o, **k)[source]

Device([device_id[, mode, [OPTIONS …]]) -> Device instance

represents a single FTDI device accessible via the libftdi driver. Supports a basic file-like interface (open/close/read/write, context manager support).

Parameters:
  • device_id – an optional serial number of the device to open. if omitted, this refers to the first device found, which is convenient if only one device is attached, but otherwise fairly useless.
  • mode – either ‘b’ (binary) or ‘t’ (text). This primarily affects Python 3 calls to read() and write(), which will accept/return unicode strings which will be encoded/decoded according to the given…
  • encoding – the codec name to be used for text operations.
  • interface_select – select interface to use on multi-interface devices
  • device_index – optional index of the device to open, in the event of multiple matches for other parameters (PID, VID, device_id). Defaults to zero (the first device found).

The following parameters are only available as keyword parameters and override class attributes, so may be specified in subclasses.

Parameters:
  • lazy_open – if True, then the device will not be opened immediately - the user must perform an explicit open() call prior to other operations.
  • chunk_size – if non-zero, split read and write operations into chunks of this size. With large or slow accesses, interruptions (i.e. KeyboardInterrupt) may not happen in a timely fashion.
  • auto_detach – default True, whether to automatically re-attach the kernel driver on device close.
pylibftdi.examples.midi_output.scale()[source]
pylibftdi.examples.midi_output.volume(beat)[source]
pin_read Module

Display values on input pins of a BitBangDevice.

TODO:
  • ANSI colours / display differences in bold
example - beep on pin 1 going high:
$ pylibftdi/examples/pin_read.py -n 0.01 -m 1 -k 1 && beep

Copyright (c) 2011-2014 Ben Bass <benbass@codedstructure.net> All rights reserved.

pylibftdi.examples.pin_read.display_loop(interval=1, count=0, match=None, mask=255)[source]

display and compare the value

Parameters:
  • interval – polling interval in seconds
  • count – number of polls to do, or infinite if 0
  • match – value to look for to exit early
  • mask – mask of read value before comparing to match
Returns:

‘ok’. either a match was made or none was requested

Return type:

bool

pylibftdi.examples.pin_read.display_value(value)[source]

display the given value

pylibftdi.examples.pin_read.get_value()[source]

get the value of the pins

pylibftdi.examples.pin_read.main(args=None)[source]
serial_loopback Module

test serial loopback; assumes Rx and Tx are connected

Copyright (c) 2010-2015 Ben Bass <benbass@codedstructure.net> All rights reserved.

class pylibftdi.examples.serial_loopback.LoopbackTester[source]

Bases: object

__init__()[source]

x.__init__(…) initializes x; see help(type(x)) for signature

bisect()[source]
main()[source]
test_iter(lengths)[source]
test_loopback(l)[source]
pylibftdi.examples.serial_loopback.test_string(length)[source]
info Module

Report environment info relevant to pylibftdi

example usage:

$ python3 -m pylibftdi.examples.info
pylibftdi version     : 0.15.0
libftdi version       : libftdi_version(major=1, minor=1, micro=0, version_str=b'1.1', snapshot_str=b'unknown')
libftdi library path  : /usr/local/lib/libftdi1.dylib
libusb version        : libusb_version(major=1, minor=0, micro=19, nano=10903, rc=b'', describe=b'http://libusb.info')
libusb library path   : /usr/local/lib/libusb-1.0.dylib
Python version        : 3.4.0
OS platform           : Darwin-14.1.0-x86_64-i386-64bit

Copyright (c) 2015 Ben Bass <benbass@codedstructure.net>

pylibftdi.examples.info.ftdi_info()[source]

Return (ordered) dictionary contianing pylibftdi environment info

Designed for display purposes only; keys and value types may vary.

Indices and tables