Python Usb Example

  

  1. Python Ftdi Usb Example
  2. Python Usb Camera Example

The following example code queries the various descriptors for the USB device that is specified by the WinUSB interface handle. The example function retrieves the types of supported endpoints and their pipe identifiers. The example stores all three PipeId values for later use. Aug 08, 2021 Download USB MASTER Using Python -Tkinter desktop application project in Python with source code.USB MASTER Using Python -Tkinter program for student, beginner and beginners and professionals.This program help improve student basic fandament and logics.Learning a basic consept of Python program with best example. Python notwithstanding, this was actually harder because I had to start from scratch without any directions:-) The code examples below will show the various blocks that are needed, and how they work together. Enabling the USB HIB keyboard mode. This is well documented, but worth mentioning: The boot.py file needs to be modified like this. The sample source code outlines the basics of communicating directly with an ADU device on Linux and OS X using Python and libhidapi. Basics of opening a USB device handle, writing and reading data, as well as closing the handle of the ADU usb device is provided as an example.

If you are a Python programmer, and need a simple USB interface for some hardware, read on…

FTDI are well known for their USB-to-serial chips, but the later models (such as FT2232C and FT232H) have various other capabilities; when combined with Python, you get a simple yet powerful method of controlling & monitoring a wide variety of hardware devices.

Hardware

Various FTDI-equipped modules and cables are available.

A few points to bear in mind:

  • The module may need to have some of its pins linked together, otherwise it won’t power up.
  • If the module has a 5 Volt output pin, take care when connecting it up; if mis-connected, a sizeable current may flow, causing significant damage.
  • Each FTDI device has a unique set of capabilities; check the datasheet to make sure the part has the facilities you need.

Device driver

Python Ftdi Usb Example

As standard, when an FTDI device is plugged into a Windows PC, the operating system loads the default Virtual Com Port driver, that can only handle asynchronous serial (RS232-type) protocols. However, we want to be a bit more adventurous, so need to substitute the ‘d2xx’ driver, available from the FTDI drivers page. A quick way to check which driver is active is to look at the Device Manager; if the FTDI part appears as a COM port, it is asynchronous-only.

Use ‘pip’ to install a Python library that will access the d2xx driver; there are several available (such as pyftdi, pylibftdi) but the only one that worked seamlessly with Python 2.7 and 3.x on my systems was the simplest: ftd2xx, which is just a CTYPES wrapper round the d2xx API

A quick check to see if all is well (Python 2.7 or 3.x):

This should print some dictionary entries for the device, e.g.

If this fails, it is usually because the device is still using the VCP driver, or the Python library can’t find the necessary FTDI files (ftd2xx.lib, and ftd2xx.dll or ftd2xx64.dll); they need to be somewhere on the executable PATH.

Linux drivers are discussed in the next post.

Example

Pinout

Before sending any data to the device, we need to establish which pins does what, as all pin functions are pre-assigned. Each chip has 1 or more ‘channels’, i.e. protocol engines, so a 2-channel device can drive 2 separate protocol streams, though there may be a limitation on the protocols a channel can handle. Each channel is assigned to one or more ports, which are usually 8-bit, but may have as many as 10 or as few as 4 bits. The first port of the first channel is identified as ADBUS; if that channel has a second port, it would be ACBUS. The first port of the second channel (if present) is BDBUS, the second port of that channel would be BCBUS.

The serial I/O functions are generally constrained to the lower few bits of the first port, the rest of the lines act as general status or handshake I/O. For example, the 2-channel FT2232C device channel A has pins ADBUS 0 – 7 and ACBUS 0 – 3:

The GPIOL and GPIOH prefixes refer to the low & high byte output commands that we’ll encounter later when using MPSSE mode for synchronous protocols; also note that channel B is unusable in that mode.

A possible source of confusion is that pins 1 and 2 in MPSSE mode are identified as TDI/DO and TDO/DI, implying that they can act as inputs or outputs. This is incorrect: in MPSSE mode, pin 1 is normally an output, and pin 2 is an input. The reason for the TDI and TDO labels is that they refer to the JTAG protocol, which is defined from the point of view of the device being controlled, not the controller – so the DO and DI labels apply in normal usage.

Python

Also note that the device has a tendency to keep its previous settings, even after a reset. For this reason, all programs using the ftd2xx library normally start by clearing everything in the device to zero, just in case a preceding program has left some settings active. For simplicity, the code given below ignores this requirement, and assumes the device has been re-plugged just before the code was run.

Bitbang mode: toggling an I/O pin

Python Usb Camera Example

‘bitbashing’ which FTDI call ‘bitbanging’, refers to driving the I/O pins directly, rather than using an I/O protocol embedded in the device.

The FTDI device powers up in ‘reset mode’ and must be set to bitbang mode using the setBitmode function. One advantage of using the Python ftd2xx library is that the function arguments are as documented in the FTDI ‘D2XX Programmers Guide’:

Having set our chosen pin as an output, and enabled bitbang mode, writing a string to the device handle will set its state. The ‘write’ functions returns the number of characters written, which is 1 in this case. If your application involves sending out a succession of O/P pulses, you’ll want to know how fast the operation is; sending the following commands:

results in a positive pulse somewhere between 500 microseconds and 2 milliseconds wide. This will be too variable and too slow for many applications, so an alternative is to write a string containing multiple data values, e.g.

This results in a pulse 50 nanoseconds wide, which is probably too narrow for most applications, however in theory you can just duplicate a command to stretch it out, for example to generate a pulse of 200 nanoseconds:

This approach is somewhat inefficient, and works fine on Python 2.7, but not on Python 3.x; if you connect an oscilloscope to the output, you’ll see a couple of cycles of 10 MHz square-wave, instead of a single broad pulse. Using a USB analyser to monitor the data, it is apparent that the code is sending the bytes 01 00 01 00 01 instead of 01 01 01 01 00; the length is correct, but the data values are wrong, because of the different ways Python 2.7 and 3.x store their strings.

Byte values in Python 2.7 and 3.x

The default string type can’t be used for byte data in 3.x, as the characters are 16-bit Unicode values, not bytes. There are various ways round the problem, the simplest is to force the string type to binary:

This is fine for preformatted strings, but gets rather messy if the data is being computed on-the-fly. There are plenty of alternative suggestions on the Internet, but many don’t work in special cases, such as bit 7 being set. The ‘bytearray’ type would be useful, except that it is rejected as an unknown type by the ftd2xx library. The ‘bytes’ datatype is good on v3, but works very differently on v2.7, so for my development I reluctantly decided to store all outgoing data as lists of integers, with a version-dependant conversion function on writing, e.g.

Slowing down output transitions

Sending multiple output commands to slow down the output transitions is quite inefficient, and unworkable for really long pulses. A better alternative is to program the baud rate generator (the same generator as used for serial communications), which synchronises the transitions, e.g.

The FTDI Application Note states that the output is clocked at 16 times the baud rate, so 9600 baud should result in a timing of 6.51 microseconds per bit. However, on an FT2232H module the time was measured as 20.825 microseconds, so that logic seemingly doesn’t apply to all modules.

Reading input pins

Finally we get to read some data in:

The length of 1 returns an 8-bit value corresponding to the I/O pin states; as before, the returned type depends on the Python version, so I convert it to a list of integers:

Unused inputs float high, and the last output command drove the ADBUS0 output low, so the value printed is 254 in a list, [254].

You can implement quite complex protocols using simple I/ O commands; write-cycles can be chained to output complex sequences, but there is quite a speed-penalty every time a read-cycle has to be interleaved. In recognition of this, many FTDI chips have a more complex capability, which they call MPSSE (Multi-Protocol Synchronous Serial Engine); that’ll be the subject of a later blog post…

See the next post to run the code on Linux…

Python Usb Example

Copyright (c) Jeremy P Bentham 2018. Please credit this blog if you are using the information or software in it.