I used to bit-bang I2C on PC LPT printer ports, which are long obsolete.
A USB-to-I2C module allows me to talk to I2C devices again.
FTDI provide source-code libraries to talk to this module.
I gave it a try, and got it talking to an I2C EEPROM.
I compiled the Linux program that reads and writes to an I2C EEPROM, and it worked straight away.
I thought this looked like a good working starting point for controlling other devices such as the MCP32017 chip, but I ended up wasting a lot of time trying to convert it. They are significantly different in the way they are accessed. Eventually, after a lot of Google AI prompting, I got some working code.
Python is popular for writing test scripts so I tried getting this going first.
I am fairly new to Python, so some of this log will be common knowledge to many. On the plus side, it will be useful to newbies like myself.
I asked Google AI for help getting started. It told me install various libraries using pip, but my Linux Mint version 22 did not have pip, so I installed pip. Then I got messages refusing to use pip, saying installation is externally managed.
Google AI explained that this is done for good software management reasons. Suppose you have two programs that need two different versions of the same library. One of them is going to have a problem. If one of those programs is the operating system, it is a big problem. It is impractical to force many different Python programs to use identical libraries.
This probably explains why my Linux has a Software Manager program. Presumably it has checked the programs it knows about for incompatibilities.
The solution to the Python library issue is to give projects their own programming environment to store their own libraries. This is called a "virtual environment". I presume the "real environment" is the actual operating system.
My first thoughts were that this was going to use a lot of memory to create the environment, and that all the libraries would need reloading every time it was initialised.
To start a project, commands like this are needed:
# Navigate to your home directory or a projects foldercd ~
# Create a new directory for your project
mkdir mcp_project
cd mcp_project
# Create a virtual environment named 'venv_mcp'
python3 -m venv venv_mcp
# Activate the virtual environmentsource venv_mcp/bin/activate
On my PC, this creates a directory called venv_mcp which has 13.8 megabytes of files in it. Which is "a lot" to oldies like myself that remember home computers with 64K memory spaces. But my PC has gigabytes of RAM and terabytes of disk space. It is not a lot anymore. If you want to be frugal, you can always delete that directory afterwards because it doesn't take more than a second to recreate and reload the libraries.
# mcp_blink.pyimport time
# The 'board' module is provided by Adafruit-Blinka, installed in your venvfrom board import I2C
import busio
import digitalio
# The MCP23017 library is also installed in your venvfrom adafruit_mcp230xx.mcp23017 import MCP23017
# 1. Initialize the I2C bus using pyftdi backendtry:
# This automatically finds the FTDI device (UMFT4222EV)
i2c = busio.I2C(I2C()._clock, I2C()._data)
except Exception as e:
print(f"Error initializing I2C bus: {e}")
print("Please ensure the UMFT4222EV is connected, configured for I2C, and recognized by the system.")
exit()
# 2. Initialize the MCP23017 (default address 0x20)try:
mcp = MCP23017(i2c, address=0x20)
except ValueError:
print("Could not find MCP23017 at address 0x20. Check your I2C connections and address pins (A0, A1, A2).")
i2c.deinit()
exit()
# 3. Configure a pin (e.g., GPB0, which is index 8) as an output
led_pin_index = 8
led_pin = mcp.get_pin_by_number(led_pin_index)
led_pin.direction = digitalio.Direction.OUTPUT
print(f"Blinking LED on MCP23017 pin GPB0 (index {led_pin_index})...")
print("Press Ctrl+C to stop.")
# 4. Blink the LEDtry:
whileTrue:
led_pin.value = True# Turn on
time.sleep(0.5)
led_pin.value = False# Turn off
time.sleep(0.5)
except KeyboardInterrupt:
print("\nBlink program stopped by user.")
finally:
# Clean up resources
i2c.deinit()
and try to run it:
pythonmcp_blink.py
but then I got this:
(venv_mcp) keith@mister-biggie:~/mcp_project$ python mcp_blink.py
Traceback (most recent calllast):
File"/home/keith/mcp_project/mcp_blink.py", line 4, in <module>
from board import I2C
ImportError: cannot importname'I2C'from'board' (/home/keith/mcp_project/venv_mcp/lib/python3...
After wading through documentation, this was very easy.
Some documentation said that all you need to do is plug the module in and Windows 10 would install the software. I didn't get the expected pop-up windows saying 'new device detected'.
Fortunately the documentation said you could install the drivers simply by running a single setup.exe program. I did this without problems.
The module is now visible in the device manager, as a USB device with two FT2223 ports.
for i in $(seq 0 8); do sudo i2cdetect -y $i ; done
The program 'i2cdetect'is currently not installed. You can install it by typing:
sudo apt-get install i2c-tools
This installation command worked. Tried to detect devices again, but got permission denied. Had to become a super user with the 'su' command. This allowed devices to be detected. I don't have any devices attached yet, so all I got was ten lots of this:
I checked that my video card has a VGA output, as these are going obsolete. Fortunately, mine does.
Time to look for an old VGA cable...
2020-11-17
Ordered two UMFT4222EV-D modules from Mouser. Despatched from Germany, they arrived 2 days later.
2020-11-22
Compiled and ran the example code that gets the hardware version from the module. Success!
The I2C master example writes and reads a serial EEPROM. I have one but VCC is 5V, not the necessary 3V3. That code would simply prove the interface works. I shall examine the code and see how I could get it talking to one of the I2C slave modules I have.
2020-11-23
I had expected my USB-to-I2C module to show up as an I2C bus in the Linux file system., and wondered why it did not. On my laptop, I listed the busses found like so:
None of these have FTDI in the name. There is one with vga in the name, and two with DDC in the name. I could scan those buses, then attach an I2C device to the VGA port, and see which bus had changed. The easiest way was to connect my laptop to the VGA port of my monitor. No soldering needed!
My laptop LCD panel blinked briefly. If I go to the system settings, it now knows it has two displays. Even if my desktop monitor is in use through its DVI port. I also see that devices appear at addresses 30, 37, 4a, 4b and 50 responded on i2c-7 (the DPDDC-A bus). 50 is the configuration ROM.