I want to establish a UART communication between an FPGA equipped with an FTD2232H chip and a PC, and for that, I am using the Python ftd2xx module. I do not know how to use the setBitMode function of this module to adjust the mode as UART.
I have written the following example code:
import ftd2xx as ftd
device = ftd.open(0)
device.setBaudRate(9600)
device.setBitMode(mask, enable)
device.write("01010101")
device.close()
How should the parameters mask and enable be chosen in order to have a UART communication?
The FT2232H defaults to a mode depending on if an EEPROM is present and the stored setup. If no EEPROM is present UART is the default. Else the setup stored in the EEPROM determins the mode. It can be UART or any other of the allowed modes. You can change the setup using FT_PROG.
If the FT2232H is in UART mode, there is no need to change anything via D2XX. Actually in that case the device can simply be opened as a com port if thethe Virtual Com Port (VCP) is loaded. The py_serial module is an easy solution to open the device in that case.
If you really want (or need) to use the ftd2xx module (note: the project page states "I don’t have time to maintain this project, so I am looking for a maintainer."), you can find the corresponding descripts in "D2XX Programmer's Guide" (Document Reference No.: FT_000071 ). However, you can only enter specific modes using the D2XX driver. If you entered one of them (e.g. to use an alternative protocol for a short time), you can issue a reset using mode = 0x0 to revert the device state to the EEPROM configurated mode. But this is a very specific use case which mostlikely does not apply here.
Since ftd2xx is simply a wrapper for the D2XX DLL from FTDI, you should consult the documentation for that.
Related
I am using XBee PRO S3B for wireless radio communication.
Currently I am configuring it by XCTU, however, sometimes I need to reset or re configure with non graphical interface.
Using digi module with python seemed good alternative to me. So here is my source code.
import digi
from digi.xbee.devices import XBeeDevice
xbee0=XBeeDevice("/dev/ttyUSB0",9600)
xbee0.open(force_settings=True)
xbee0.reset()
In this way I can reset my destination mac address. However, there is one critical drawback using this method. xbee0.open() is only supported by API mode, however, I am always using AT mode. So the command force_settings=True enables my AT mode to change into API mode, however, I am not sure how can I get back to AT mode. My device only works with AT mode so I need to go back to AT mode to do something. Is there any good solution for this?
from digi.xbee.devices import XBeeDevice
from digi.xbee.models.mode import OperatingMode
xbee0=XBeeDevice("/dev/ttyUSB0",9600)
xbee0.open(force_settings=True)
xbee0.reset()
xbee0.set_parameter(('AP'),bytearray([OperatingMode.AT_MODE.code]))
I have 2 identical USB-to-serial adapter cables (pretty much like this one) to connect a desktop PC under Ubuntu and some RS232 devices.
I develop a python software to pilot these devices.
I need to find a way to identify which one of the 2 adapters I am connected to.
I know about python's serial.tools.list_ports.comports() function, but all the settings are the exact same for both adapters (see capture below). Except the device, but it may change depending on the plugging order.
How can I change some settings' field to make both adapter pythonically distinguishable? Is it possible to write my own serial_number for example?
To solve this problem there are some alternative paths to serial devices in Linux.
There's either
/dev/serial/by-id/ and /dev/serial/by-path
variant to access your devices.
If this is always for a specific serial device, the normal way to do this is to use the udev program to create symlinks for you in /dev. There's a lot of different options for how to do this, either based on what physical port it's plugged into or based off of attributes of the device(e.g. serial number).
FTDI based devices all have a serial number associated with them, but since yours is a Prolific they don't have a serial number, so this becomes a bit harder. However, since we can use udev to create a symlink based on where it is plugged in, something like the following should work(put this in a file seen by udev, e.g. /etc/udev/rules.d/80-my-converter.rules):
SUBSYSTEM=="usb", KERNELS=="2-1.8.3", SYMLINK+="device_1"
SUBSYSTEM=="usb", KERNELS=="2-1.8.1.3", SYMLINK+="device_2"
The KERNELS parameter will have to change depending on where exactly you plug the serial device into and will be specific to your system. You can get a list of the udev parameters on your device by running the following:
udevadm info -a -n /dev/ttyUSB2
This page has more information on writing udev rules.
The solution to this problem is probably pretty simple, but I am new to interfacing with a device dynamically. What I'm doing is I am making a python executable code, so the user doesn't have to have Idle on their computer or any kind of python interpreter, which means I don't know which USB port the device will be plugged in to. The program needs to be able to open a connection to a device that is connected through a serial to usb converter. How can I determine which connected device is the correct device to open a port to? I am using pySerial to interact with the device. Any help would be greatly appreciated.
No matter how you configure your device, at some point you're probably going to have to ask the user where the port is, or poll all serial devices for a known response. (Polling has it's pitfalls though, so read on!). Unlike USB devices, there is no vendor/device ID that is made known to the OS when you attach a plain-old serial device.
First you need to find the serial ports. Here's a question that might help: What is the cross-platform method of enumerating serial ports in Python (including virtual ports)?.
Once you have a list of serial ports, you could ask the user whether they know which one to use. If they do, problem solved!
If they don't, you could offer to poll ALL serial devices with some data that you know will yield a certain response from your device. Keep in mind though that if the user has other serial devices attached, your string of "hello" bytes might actually be the self-destruct sequence for some other device! Hence, you should warn the user that polling may interfere with other devices, and always prompt them before you do so.
Without knowing more about your code (eg. what comms framework, if any, you're using; are you doing this in the console or are you using a GUI toolkit, etc), it's impossible to say what the best way to code this might be. In the simplest case, you could just loop over all of your serial devices, send the greeting and check for a response. (You could also do this in parallel: loop once for the greeting, and loop again to check what's in the buffer. If you're going to get more fancy than that, use a proper library.)
Side note: You might be able to get around this if you have a built-in converter that you can set the vendor/device ID for, but the converter will still be automatically detected by any modern OS and enumerated as a serial port; you won't get to talk to it directly as a USB device. It could be possible to figure out which port goes with which ID, but I've never tried to do that. But this approach is useless if you're not the one who gets to pick the converter (eg. if it's a user-supplied cable).
This is the way that I used for identify Serial-USB conveter device like Arduino.
It checks 'USB' String of device description.
import serial as ser
import serial.tools.list_ports as prtlst
global COMs
COMs=[]
def getCOMs():
global COMs
pts= prtlst.comports()
for pt in pts:
if 'USB' in pt[1]: #check 'USB' string in device description
COMs.append(pt[0])
The only way I can think to get around the problem with probing unknown devices is to have the device send unsolicited "hello" responses continually. That was you can just connect to all serial devices and listen for the "hellos". Connecting and listening to a serial device shouldn't ever mess it up.
The downside is you have these messages cluttering up your serial stream. You could have a "I'm here now, stfu" command but then you can only connect to it once.
FTDI chips have a method of identification but you have to use their library to access the data.
I have an 2-port signal relay connected to my computer via a USB serial interface. Using the pyserial module I can control these relays with ease. However, this is based on the assumption that I know beforehand which COM-port (or /dev-node) the device is assigned to.
For the project I'm doing that's not enough since I don't want to assume that the device always gets assigned to for example COM7 in Windows. I need to be able to identify the device programatically across the possible platforms (Win, Linux, OSX (which I imagine would be similar to the Linux approach)), using python. Perhaps by, as the title suggests, enumerate USB-devices on the system and somehow get more friendly names for them. Windows and Linux being the most important platforms to support.
Any help would be greatly appreciated!
EDIT:
Seems like the pyudev-module would be a good fit for Linux-systems. Has anyone had any experience with that?
Regarding Linux, if all you need is to enumerate devices, you can even skip pyudev dependency for your project, and simply parse the output of /sbin/udevadm info --export-db command (does not require root privileges). It will dump all information about present devices and classes, including USB product IDs for USB devices, which should be more then enough to identify your USB-to-serial adapters. Of course, you can also do this with pyudev.
I know this is an older post, but I was struggling with it today.
Ultimately I used the wmi library for python as I'm on a Windows machine (sorry, I know my answer only applies to Windows, but maybe it'll help someone).
Install the package using pip first:
pip install wmi
then
import wmi
c = wmi.WMI()
wql = "Select * From Win32_USBControllerDevice"
for item in c.query(wql):
print item.Dependent.Caption
Should result with something like:
USB Root Hub
USB Root Hub
Prolific USB-to-Serial Comm Port (COM9)
USB Root Hub
USB Root Hub
USB Composite Device
USB Video Device
USB Audio Device
USB Root Hub
...snip...
In this case, you'd have to string parse the Caption to find the COM port. You can also take a look at just the item. Dependent object to see other attributes of the USB device beside Caption that you may find relevant:
instance of Win32_PnPEntity
{
Caption = "USB Root Hub";
ClassGuid = "{36fc9e60-c465-11cf-8056-444553540000}";
ConfigManagerErrorCode = 0;
ConfigManagerUserConfig = FALSE;
CreationClassName = "Win32_PnPEntity";
Description = "USB Root Hub";
DeviceID = "USB\\ROOT_HUB\\4&32F13EF0&1";
HardwareID = {"USB\\ROOT_HUB&VID8086&PID3A36&REV0000",
"USB\\ROOT_HUB&VID8086&PID3A36", "USB\\ROOT_HUB"};
Manufacturer = "(Standard USB Host Controller)";
Name = "USB Root Hub";
PNPDeviceID = "USB\\ROOT_HUB\\4&32F13EF0&1";
Service = "usbhub";
Status = "OK";
SystemCreationClassName = "Win32_ComputerSystem";
SystemName = "001fbc0934d1";
};
At least for linux, you can use some dummy hacks to determine your /dev node, by inspecting for example the output of "ls /dev | grep ttyUSB" before and after you attach your device. This somehow must apply as well for the OSX case. A good idea is to inspect those commands using something like the subprocess.Popen() command. As for windows, this might be helpful.
Windows: you can pull USB information from WMI, but you need to be administrator. The examples are in .NET, but you should be able to use the Python WMI module. This will give you access to USB identification strings, which may contain useful information. For FTDI serial devices there is a short cut using FTDI's DLL, which does not require privileged access.
Linux: all the available information is under /sys/bus/usb, and also available through udev. This looks like a good answer.
As far as Windows goes, you could scan the registry:
import _winreg as reg
from itertools import count
key = reg.OpenKey(reg.HKEY_LOCAL_MACHINE, 'HARDWARE\\DEVICEMAP\\SERIALCOMM')
try:
for i in count():
device, port = reg.EnumValue(key, i)[:2]
print device, port
except WindowsError:
pass
It will be great if this is possible, but in my experience with commercial equipments using COM ports this is not the case. Most of the times you need to set manually in the software the COM port. This is a mess, specially in windows (at least XP) that tends to change the number of the com ports in certain cases. In some equipment there is an autodiscovery feature in the software that sends a small message to every COM port and waits for the right answer. This of course only works if the instrument implements some kind of identification command. Good luck.
I'm writing a program that converts OSC into MIDI, allowing OSC enabled applications (like touchOSC on my iPhone) to control MIDI enabled applications (Sibelius, Ableton Live and so on).
I'm using Python to create an OSC server and convert from OSC to MIDI. To get MIDI to the application in question, I'm outputting MIDI to the Apple IAC driver, which is then enabled as an input within the program in question.
Does anyone know of a means to programmatically configure Mac MIDI devices programmatically? In particular, I need to enable the IAC driver, which is disabled by default.
Using FileMon, I have observed that Audio Midi Setup.app modifies this file when enabling/disabling the IAC driver:
~/Preferences/ByHost/com.apple.MIDI.0017f2cxxxxx.plist
The number 0017f2cxxxxx is my system IOPlatformUUID. It's a simple XML property list, but I'm wary of writing to it directly. Even if I did, presumably I would need to cajole the midi server process into re-reading it somehow?
Finally, I'm becoming more and more aware that using the IAC driver at all is a pretty naff solution - for a start it only works on Mac! Ideally, I would write a loopback MIDI driver and all my problems would be solved...
Your hunch about writing directly to the plist is correct -- you probably shouldn't do it. I'm not 100% sure about this, but I have a feeling that the plist reflects the state of the MIDI device, but altering it will not open or close that MIDI device as you need.
To actually open the MIDI device, you could use something like pygame. I have used it for some audio-related projects, and the SDK is very straightforward and easy to work with. As python doesn't have great support for MIDI directly, this is probably your best bet (short of writing the python C module yourself, which would be rather painful).
As for IAC, it's a shame that other OS's don't come with virtual MIDI devices like this. IAC is very useful and good at what it does. So while relying on IAC for something like this would not be cross-platform, you could write an abstraction layer for manipulating the loopback device. For Windows users, you could recommend a free MIDI loopback device to be used with your software.
If you want to send OSC to MIDI then you're best off creating a Virtual Midi port in software rather trying to remotely configure an IAC. This virtual port will show up in Ableton etc so you can then have it control things programmatically.
You can do this using the rtmidi-python library (or older and slightly different pyrtmidi) - both based on the cross-platform rtmidi lib which provides for straightforward sending of MIDI Control and Notes:
import rtmidi_python as rtmidi
vmidi_out = rtmidi.MidiOut()
vmidi_out.open_virtual_port('My Virtual MIDI Output Port')
vmidi_out.send_message([0x90, 48, 100]) # Note on
vmidi_out.send_message([176, 7, 100]) # Control Change - Volume
PyGame itself uses PortMidi under the hood. If you don't need all PyGame library, maybe this can be useful for you.