Hi, I recently purchased a TCT-40/qwiic ultrasonic sensor with the intention of adding it to the XRP robot platform that I have been successfully operating via python via the XRPCode web-based interface. I also have the OTOS qwiic sensor, which works fine with python. However, I’m having trouble finding if there’s support for the TCT-40/qwiic sensor for micropython, similar to what’s available for the OTOS sensor.
Any help is appreciated.
We don’t have a micropython library ready-made for that sensor, though they are compatible and you can certainly write some micropython code to use the TCT40 over qwiic/i2c on the XRP; here’s a thread with some links to get started TCT40 I2C command documentation?
So if I buy another blue sensor (that comes with the XRP kit), i should be able to run two of those with python, correct?
Sure - you can wire it to either ‘qwiic’ or ‘extra’ port using one of these Flexible Qwiic Cable - Female Jumper (4-pin) and communicate with it that way…just remember to adjust the new ultrasonic’s rear jumper pads if you use i2c (default is GPIO mode)
Edit: If using the OTOS as well I’d wire it to ‘extra’ and put the OTOS on the ‘qwiic’ port 
Great, thanks for the help!
I have written a python interface for the sparkfun/qwiic ultrasonic sensor (red SEN-17777). It’s pretty basic, but here’s the code. No license or attribution needed. Feel free to use / modify / distribute in any way you see fit. I’m open to recommendations for improvement as well. I wrote this to work as a second ultrasonic sensor on the XRP platform.
import qwiic_i2c
import time
class QwiicRangefinder:
"""
A class for an I2C-based rangefinder (SparkFun Qwiic Ultrasonic)
connected to Qwiic at address 0x2F.
"""
_DEFAULT_I2C_ADDRESS = 0x2F # Default I2C address
_CMD_MEASURE_DISTANCE = 0x01 # Command to trigger and read distance
def __init__(self, address=None, i2c_driver=None):
"""
Initializes the rangefinder on I2C.
:param address: I2C address of the rangefinder (default: 0x2F).
:param i2c_driver: Optional I2C driver instance.
"""
self.address = address if address else self._DEFAULT_I2C_ADDRESS
# Load I2C driver
if i2c_driver is None:
self._i2c = qwiic_i2c.getI2CDriver()
if self._i2c is None:
print("Error: Unable to load I2C driver.")
return
else:
self._i2c = i2c_driver
def is_connected(self):
"""
Check if the rangefinder is connected via I2C.
:return: True if device responds, False otherwise.
"""
return self._i2c.isDeviceConnected(self.address)
def begin(self):
"""
Initializes the rangefinder.
:return: True if the device is ready, False otherwise.
"""
return self.is_connected()
def get_distance(self):
"""
Triggers a measurement and reads the previous distance.
:return: Distance in millimeters (mm), or -1 if read fails.
"""
try:
# Send the command to trigger a new measurement
self._i2c.writeCommand(self.address, self._CMD_MEASURE_DISTANCE)
# Wait for measurement to complete
time.sleep(0.1)
# Request 2 bytes from the sensor
data = self._i2c.readBlock(self.address, self._CMD_MEASURE_DISTANCE, 2)
if data is None or len(data) < 2:
return -1 # Sensor did not return valid data
# Convert the received bytes to a 16-bit integer (big-endian)
distance = (data[0] << 8) | data[1]
return distance/10 # Distance in cm
except:
return -1 # Return -1 if reading fails
# Example Usage:
if __name__ == "__main__":
sensor = QwiicRangefinder()
if sensor.begin():
print("Qwiic Rangefinder Connected!")
while True:
print("Distance: {} mm".format(sensor.get_distance()))
time.sleep(0.5)
else:
print("Sensor not detected.")
2 Likes