Support »
Pololu Isolated USB-to-I²C Adapter User’s Guide
View document on multiple pages.
- 1. Overview
- 2. Contacting Pololu
- 3. Installing Windows drivers
- 4. Connecting the adapter
- 5. Writing PC software to control the adapter
- 6. LED feedback
- 7. Command reference
- 8. Error codes
- 9. Upgrading firmware
1. Overview
This section is coming soon.
1.1. Supported operating systems
The Pololu Isolated USB-to-I²C Adapter works on Microsoft Windows 11, Windows 10, Linux, and macOS without any driver installation. The Windows driver we provide in Section 3 should allow the adapter to work on older versions of Windows, but we have not tested that. Driver installation is not required on Windows 10 and later, but installing the driver is recommended because it allows you to see the correct product name in the Device Manager instead of “USB Serial Device”.
2. Contacting Pololu
We would be delighted to hear from you about any of your projects and about your experience with the USB-to-I²C adapter. You can contact us directly or post on our forum. Tell us what we did well, what we could improve, what you would like to see in the future, or anything else you would like to say!
3. Installing Windows drivers
If you use Windows on an Arm-based PC, Windows will refuse to install these drivers due to different requirements for digital signatures. You should be able to skip this section and still use the device.
Before you connect your Pololu Isolated USB-to-I²C Adapter to a computer running Microsoft Windows, we recommend installing its drivers. Driver installation is not required on Windows 10 and later, but installing the driver is recommended because it allows you to see the correct product name in the Device Manager instead of “USB Serial Device”.
- Download the Pololu Isolated USB-to-I²C Adapter drivers for Windows (14k zip) and extract the ZIP file to a temporary folder on your computer. (These files are also available in the “drivers” directory in the Pololu Isolated USB-to-I²C Adapter repository.)
- Open the “pololu-usb-i2c-adapter-windows” folder. Right-click on “pololu-usb-i2c-adapter.inf” and select “Install”.
- Windows might ask you whether you want to open the file because it was dowloaded from the Internet. Click “Open”.
- Windows will ask you whether you want to allow the Microsoft “INF Default Install” app to make changes to your device. Click “Yes”.
- Windows might ask you if you want to install the drivers. Click “Install”.
- Finally, Windows will display “The operation completed successfully.”.
COM port details
After installing the drivers and plugging in an adapter, in the “Ports (COM & LPT)” category of the Device Manager, you should see a COM port for the adapter named either “Pololu Isolated USB-to-I2C Adapter” or “Pololu Isolated USB-to-I2C Adapter with Isolated Power”, depending on which product you have.
You might see that the COM port is named “USB Serial Device” in the Device Manager instead of having a descriptive name. The port will still be usable, but it will be hard to tell if it is the right one because of the generic name. We recommend fixing the names in the Device Manager by right-clicking on each “USB Serial Device” entry, selecting “Update Driver Software…”, and then selecting “Search automatically for updated driver software”. Windows should find the drivers you already installed using the instructions above, which contain the correct name for the port.
If you are using Windows 10 or later and choose not to install the drivers, the adapter will still be usable. To tell which “USB Serial Device” in your Device Manager is the adapter, double-click on each one and look at the “Hardware Ids” property in the “Details” tab. If you see USB\VID_1FFB&PID_2502
or USB\VID_1FFB&PID_2503
listed, that COM port is the adapter.
If you want to change the COM port number assigned to your adapter, you can do so using the Device Manager. Double-click a COM port to open its properties dialog, and click the “Advanced…” button in the “Port Settings” tab.
4. Connecting the adapter
|
|
The Pololu Isolated USB-to-I²C Adapter connects to a computer’s USB port via a USB C cable (not included). You can connect I²C target devices to the adapter through either a JST SH-style 4-pin connector (compatible with Qwiic and STEMMA QT) or four 0.1″-pitch through-holes that are compatible with standard 0.1″ male headers and female headers.
Pin | Cable color | Name | ![]() Function (Isolated USB-to-I²C Adapter) |
![]() Function (Isolated USB-to-I²C Adapter with Isolated Power) |
---|---|---|---|---|
1 | Black | GND | I²C ground; this pin is NOT connected to USB GND | |
2 | Red | VCC | I²C bus voltage input (2.25 V to 5.5 V) |
I²C bus voltage output (3.3 V or 5 V, set by slide switch at start-up) |
3 | Blue | SDA | I²C data line | |
4 | Yellow | SCL | I²C clock line |
The adapter’s GND pin should be connected to the ground of your I²C target device(s). Because the adapter provides full galvanic isolation, the I²C side does not share a common ground with the USB connection.
The adapter’s VCC pin is either an input or an output, depending on the model of adapter you have:
- The Pololu Isolated USB-to-I²C Adapter (green board) has a VCC (IN) pin, and you must supply 2.25 V to 5.5 V across this pin and GND. This should match the logic level voltage of your I²C target(s).
- The Pololu Isolated USB-to-I²C Adapter with Isolated Power (blue board) has a VCC (OUT) pin. When the adapter’s VCC output is enabled (controllable by the Enable VCC Out command), this pin supplies 3.3 V or 5 V power (up to 200 mA) through the adapter’s isolated DC-DC power module. The voltage level is set by the position of the slide switch at start-up.
The adapter pulls the SCL and SDA lines of the I²C bus up to VCC when they are not being driven low. Depending on your setup, you might need to add pull-up resistors from SCL and SDA to VCC to ensure that the signals rise fast enough. The adapter has 10 kΩ on-board pull-up resistors, and many I²C target boards will have pull-ups too, but that might not be enough, especially if you want to use speeds faster than 400 kHz or have long wires. The I²C-bus specification and user manual (1MB pdf) has some information about picking pull-up resistors in the “Pull-up resistor sizing” section.
5. Writing PC software to control the adapter
To successfully use the adapter, you will likely have to write some software that runs on your computer, connects to the adapter’s serial port, sends commands to it, and interprets the responses from the adapter. We provide a Pololu Isolated USB-to-I²C Adapter library for Python that can do all of that.
Here is some example code that uses the Python library to read the “Model ID” and “Model Type” registers from a VL53L1X time-of-flight distance sensor:
#!/usr/bin/env python3 import pololu_usb_i2c_adapter i2c = pololu_usb_i2c_adapter.Adapter('/dev/ttyACM0') address = 0b0101001 i2c.write_to(address, b'\x01\x0F') data = i2c.read_from(address, 2) print(data)
Alternatively, you can use the Pololu Isolated USB-to-I²C Adapter from any programming environment that allows writing and reading binary data from a serial port. Basic applications only need to implement two simple serial commands: I²C Read and I²C Write. Those two commands are documented at the top of Section 7.
6. LED feedback
The Pololu Isolated USB-to-I²C Adapter has several LEDs to indicate its status as shown in the pictures below.
|
|
Status LEDs
The green USB status LED indicates the state of the USB connection. When you connect the adapter to a computer via a USB cable, the green LED will start blinking slowly. The blinking continues until the adapter gets a particular message from the computer that indicates that the adapter is recognized. After the adapter gets that message, the green LED will be on, but it will flicker briefly when there is USB activity. During suspend mode (e.g. when the computer has gone to sleep), the green LED will blink very briefly once per second.
The yellow status LED blinks rapidly when the adapter reads data or acknowledgments from a target device.
The red status LED blinks rapidly when the adapter attempts to write data or acknowledgments to a target device. Also, if the last I²C read or write command resulted in an error, and the command was not zero-length I²C write, then the red LED blinks once per second with a 50% duty cycle.
When the yellow and red LEDs are both blinking rapidly, the relative durations of the blinks reflect the ratio of read events to write events.
Power indicator LEDs
On an adapter without isolated power, the green VCC (IN) LED turns on when power is supplied to VCC. It is directly connected between VCC and GND, so the brightness of the LED is higher when the VCC voltage is higher.
On an adapter with isolated power, the green VCC (OUT) = 3.3V LED turns on when power is supplied to VCC and VCC is less than approximately 4.38 V. This green power LED also turns on for 200 ms after VCC goes from being unpowered to powered. The blue VCC (OUT) = 5V LED turns on when power is supplied to VCC and the green power LED is not on.
7. Command reference
The Pololu Isolated USB-to-I²C Adapter supports several different commands on its USB virtual serial port interface. This section describes the details of what each command does, and how the commands and their responses are encoded as serial bytes.
List of commands
- I²C write
- I²C read
- Set I²C mode
- Set I²C timeout
- Clear bus
- Set STM32 timing
- Digital read
- Enable VCC Out
- Get device info
I²C write
Arguments | address: a 7-bit I²C address between 0 and 127 data: a list of 0 to 255 bytes to write to the device |
---|---|
Serial encoding |
|
Response | Error code (1 byte) |
Python method | i2c.write_to(address, data) |
This command writes a series of bytes to the I²C target identified by the given 7-bit address.
To send this command to the adapter’s virtual serial port, you must first send a 3-byte header consisting of 0x91 followed by I²C address (0 to 127) and then the number of bytes to write (0 to 255). After that, send the bytes that you want to write to the target device.
The adapter responds to this command by sending back a single byte. The response is either zero to indicate that the adapter wrote the data successfully and received all the expected acknowledgments from the target device, or the response is a non-zero error code (see Section 8). The most common error code returned by this command is 8, which indicates that no target device acknowledged the address byte that the adapter transmitted to the bus. This error can happen if the target device is not powered, if the target device is not properly connected to the I²C bus, or—for adapters that do not provide power to the bus—if the adapter’s VCC (IN) pin is not powered. See Section 8 for more information about the adapter’s error codes and how to troubleshoot them.
A zero-length I²C write is valid and allows you to check if a device is present at the given address without actually writing any data to it. You can use this to scan the bus for devices: this is how the Python library implements its scan()
method.
I²C read
Arguments | address: a 7-bit I²C address between 0 and 127 count: the number of bytes to read, from 1 to 255 |
---|---|
Serial encoding |
|
Response | Error code (1 byte), followed by the bytes read |
Python method | i2c.read_from(address, count) |
This command reads a series of bytes from the I²C target identified by the given 7-bit address.
This command consists of three bytes: 0x92, the I²C address (0 to 127), and the number of bytes to read (1 to 255).
The first byte of the response is either zero to indicate that the adapter read the data successfully or a non-zero error code (see Section 8). The length of the remainder of the adapter’s response is equal to the number of bytes specified in the command, regardless of whether an error occurred or not. The remainder of the response contains the data read from the device, or other bytes with unspecified values if there was an error.
Set I²C mode
Arguments | mode: one of four supported I²C modes |
---|---|
Serial encoding |
|
Response | none |
Python method | i2c.set_i2c_frequency(frequency_khz) |
This command tells the adapter what I²C mode to operate in, which determines the clock speed and other settings. The mode number should be one of:
- 0: Standard-mode (100 kHz)
- 1: Fast-mode (400 kHz)
- 2: Fast-mode Plus (1000 kHz)
- 3: 10 kHz mode
The first three modes are defined in the I²C-bus specification and user manual by NXP. The 10 kHz mode is a slower version of Standard-mode that could be useful for systems with long wires or other issues preventing 100 kHz clock speeds from working.
By default, the adapter operates in Standard-mode (100 kHz). If you send this command with an invalid mode number, the adapter switches to Standard-mode.
The communication speed is not solely determined by the specified I²C mode: it is also determined by the rise and fall times of the signals on SDA and SCL. If you use Fast-mode (400 kHz) or Fast-mode Plus (1000 kHz), adding pull-up resistors to your bus’s SDA and SCL can potentially speed up data transfer significantly (see Section 4 for more information about pull-ups).
For direct control over the parameters set by this command, see the Set STM32 timing command.
Set I²C timeout
Arguments | timeout: a number of milliseconds from 1 to 65535 |
---|---|
Serial encoding |
|
Response | none |
Python method | i2c.set_i2c_timeout(timeout_ms) |
This command sets the maximum time allowed for I²C write and I²C read commands. If the total time taken by I²C communication in one of those commands takes longer than the specified time, the adapter aborts the command and returns the timeout error code (3).
The default I²C timeout is 50 ms.
Clear bus
Arguments | none |
---|---|
Serial encoding |
|
Response | none |
Python method | i2c.clear_bus() |
This command transmits 10 low pulses on the SCL line at a frequency of 10 kHz. These pulses allow the bus to recover from cases where one of the target devices is in the wrong state and driving the SDA line low.
Set STM32 timing
Arguments | timingr: 32-bit value for the STM32’s TIMINGR register gpio_fmp_mode: 0 or 1 |
---|---|
Serial encoding |
|
Response | none |
Python method | i2c.set_stm32_timing(timingr, gpio_fmp_mode) |
This command is another way to set the parameters set by the Set I²C mode command. It allows fine control over the I²C clock speed and enables the adapter to achieve speeds higher than 1000 kHz.
The timingr argument is a 32-bit unsigned integer. This parameter corresponds to the TIMINGR register of the I²C module on its STM32C071 microcontroller. You can use the STM32CubeIDE or STM32CubeMx software from ST to generate values for this register based on your desired I²C mode, clock speed, and rise and fall times.
The gpio_fmp_mode parameter should be 0 or 1. A value of 1 enables Fast-mode Plus driving capability on the I²C pins of adapter’s STM32C071 microcontroller. This parameter corresponds to the I2C1_FMP bit in the CFGR1 register of the SYSCFG module.
Digital read
Arguments | none |
---|---|
Serial encoding |
|
Response | 1 byte: bit 0 is SCL, bit 1 is SDA |
Python method | i2c.digital_read() |
This command retrieves digital readings of the adapter’s internal SCL and SDA signals, which can be useful for troubleshooting. Normally the bus will be idle when the adapter executes this command, so both readings will be high (1). If the SDA reading is low (0), the Clear bus command might restore your bus to a working state.
Enable VCC Out
Arguments | enabled: 0 or 1 |
---|---|
Serial encoding |
|
Response | Error code (1 byte) |
Python method | i2c.enable_vcc_out(enabled) |
On adapters that have a “VCC (OUT)” pin, this command enables or disables the isolated DC-DC power module responsible for supplying USB power to the I²C bus. The VCC power output is enabled by default whenever the adapter powers on, so disabling it with this command does not have a permanent effect. The voltage of the VCC power supply (3.3 V or 5 V) is determined by the position of the voltage selection switch and is latched when the power supply turns on.
The adapter responds to this command by either sending 0 to indicate success or by sending error code 13 to indicate that the command is not supported because the adapter does not supply power.
Get device info
Arguments | none |
---|---|
Serial encoding |
|
Response | see below |
Python method | i2c.get_device_info() |
This command returns identifying information about the adapter and the firmware running on it.
Byte 0 (the first byte) of the response data is the total size of the data, in bytes. This allows future versions of the firmware to add more information at the end of the data without breaking older software.
Byte 1 is a version number for format of the data. For now, this version number is always 0, and software parsing the data should raise an error if it is non-zero.
Bytes 2 through 5 are the USB vendor ID (VID) followed by the USB product ID (PID). Both numbers are 16-bit and little endian. This table shows the known VID/PID combinations you can expect:
Vendor ID | Product ID | Name |
---|---|---|
0x1FFB | 0x2502 | Pololu Isolated USB-to-I2C Adapter |
0x1FFB | 0x2503 | Pololu Isolated USB-to-I2C Adapter with Isolated Power |
Bytes 6 and 7 are the firmware version. It is a 16-bit little endian number and holds 4 digits of binary-coded decimal. For example, if bytes 5 and 6 are 0x02 and 0x01 respectively, that corresponds to 0x0102, which indicates firmware version 1.02. This is the same as the bcdDevice field from the device’s USB descriptor. See Section 9 for information about the different firmware versions.
The next 8 bytes (bytes 8 to 15) are a null-terminated ASCII string that describes any special modifications that were made to the firmware. A single hyphen (“-”) indicates no special modifications, and should not be displayed.
The final 12 bytes of the response (bytes 16 to 27) are the unique ID of the device. These are arbitrary binary bytes, and they are the same bytes that the adapter uses to generate its USB serial number.
8. Error codes
The adapter responds to some of the commands in Section 7 with an error code. The error code will either be zero to indicate success or it will be one of the following values:
Error code 1: Protocol error
This error code indicates that the command itself was invalid. Double check the bytes you are sending if you get this error.
Error code 3: Timeout
This error code indicates that the command took longer than the configurable I²C timeout period, so it was aborted. If this error or any of the other timeout errors occur, you might consider using the “Set I²C timeout” command to raise the timeout, which is 50 ms by default.
Error code 4: Timeout while sending address
This error code indicates that a timeout happened while transmitting the first byte of an I²C transfer, which contains the device address.
Error code 5: Timeout while transmitting
This error code indicates that a timeout happened while transmitting a data byte during an I²C write.
Error code 6: Timeout while receiving
This error code indicates that a timeout happened while receiving a data byte during an I²C read.
Error code 8: Target device did not respond
This error code indicates that the adapter received a NACK (Not Acknowledge) while transmitting the address byte to the I²C bus. This error can happen if the target device is not powered, if the target device is not properly connected to the I²C bus, or—for adapters that do not provide power to the bus—if the adapter’s VCC (IN) pin is not powered.
Error code 9: Received NACK for TX data
This error code indicates that the adapter received a NACK while transmitting a byte of data to the target I²C device.
Error code 10: Bus error
This error code indicates that the adapter detected an unexpected START or STOP condition on the I²C bus
Error code 11: Arbitration lost
This error code indicates that the adapter tried to send a high level on the I²C SDA line, but it detected a low level. This could happen if another I²C controller is connected to the same bus and initiates communication at the same time as the adapter.
Error code 13: Operation not supported
This error code indicates that the adapter recognized the command but it does not support it (e.g. due to lacking necessary hardware).
9. Upgrading firmware
The Pololu Isolated USB-to-I²C Adapter runs open source firmware that you can replace with new versions from Pololu or third-party developers.
Currently, the only official firmware version is version 1.00.
Determining firmware version
You can determine what firmware version the adapter is running using the “Get device info” command documented in Section 7.
On a computer running Microsoft Windows, you can find the firmware version by double-clicking on the adapter’s port in the Device Manager, opening the Details tab, and selecting “Hardware Ids”. The firmware version appears after “REV_” in one of the hardware IDs. For example, “REV_0102” indicates firmware version 1.02. On Linux, you can find the firmware version by installing the lsusb
utility, running lsusb -d 1ffb:
, and looking for the bcdDevice value.
Getting into bootloader mode
To update the firmware on the adapter, you must first get it into bootloader mode, which means it is running the bootloader in the STM32’s system memory instead of the usual firmware.
The simplest way to start the bootloader is to open the adapter’s virtual serial port with a serial terminal program, set the baud rate to 600, and then close it. Some general-purpose terminal programs that work for this are Google Chrome Labs serial terminal, Tera Term, and PuTTY.
If that method does not work, you can short together the two exposed pads labeled “Boot” in the diagrams below while powering up the adapter to force it into bootloader mode. Hold a screwdriver or other conductive tool across the pads while plugging the adapter into USB. If this works, you will see the bootloader turn the red LED turn on briefly and then it off, and the other LEDs on the USB side of the adapter will not turn on.
|
|
Upgrade instructions
- Download the latest official firmware from Pololu: firmware version 1.00 (21k elf). This single file works for both versions of the adapter.
- Install the STM32CubeProgrammer software from ST.
- Get the adapter into bootloader mode as described above.
- Run the STM32CubeProgrammer software.
- In the upper right corner of the window, select “USB” in the blue dropdown box. The software should automatically detect the board and display “USB1” in the “Port” dropdown box.
- Click “Connect”.
- Click the menu icon in the upper left and then select “Erasing & programming”.
- Click the “Browse” button and select the ELF firmware file you downloaded earlier.
- Check the “Run after programming” checkbox and then click “Start Programming”.
- You might see a warning box that says “Warning: Connection to device 0x493 is lost”. If the log pane says “Start operation achieved successfully”, then this message is normal and expected.
If the update was successful, the new firmware should now be running. The adapter’s green LED should be on and the computer should recognize it.
Alternatively, you can also update the firmware using ST’s command-line utility with a command like this:
STM32_Programmer_CLI -c port=USB1 -w firmware.elf --go