Support Forum

Share your projects and post your questions

Register   or   Sign In
The Forum

Sample/Tutorial for Ultrasonic Distance Sensor (3V or 5V) HC-SR04 / RCWL-1601

The IO Pi Plus is a 32 channel MCP23017 GPIO expander for the Raspberry Pi

1 Views - Created 21/12/2023

21/12/2023

Posted by:
sunilvb

sunilvb Avatar

I am trying to incorporate multiple distance sensors in my project. Wondering if there is a Sample/Tutorial for Ultrasonic Distance Sensor (3V or 5V) HC-SR04 / RCWL-1601, showing how to use it with IO Pi Plus. If not, I would really appreciate some guidance. Thanks in advance!

21/12/2023

Posted by:
andrew

andrew Avatar

Location:
United Kingdom

andrew Twitter  andrew Website  

Hi sunilvb

I don't think using the IO Pi Plus with the HC-SR04 or RCWL-1601 ultrasonic sensor would be possible.

The HC-SR04 needs precise timing for sending a pulse and measuring the time for the response. As the IO Pi Plus is I2C-based, it is impossible to make precise timing calculations for changes on the input pins. The length of time needed to send an I2C data packet and the different application processes running on the Raspberry Pi mean that each read from the IO Pi Plus will take a different amount of time.

The best option for using an HC-SR04 would be to connect it to a microcontroller like an Arduino or Raspberry Pi Pico where you will have more control for measuring time intervals. You could send the data from the microcontroller to the Raspberry Pi over the UART serial port or through the I2C or SPI bus.

The RCWL-1601 sensor uses I2C for communication. You can not use the input pins on the IO Pi Plus for I2C communication so connecting the RCWL-1601 to the IO Pi Plus would not be possible.

One solution that may work for connecting up to four RCWL-1601 sensors to the Raspberry Pi would be using our I2C Switch expansion board. The RCWL-1601 has a fixed I2C address so normally you could only connect one RCWL-1601 to the Raspberry Pi but our I2C Switch splits the I2C bus into four separate buses so this allows you to connect four I2C devices with the same address.

You can find more information on the I2C Switch on the I2C Switch product page.

I have ordered some RCWL-1601 sensors so I can test them with the I2C Switch. As it is close to Christmas it may take a week or two for them to arrive but as soon as they do I will run some tests and let you know if they are compatible.

29/12/2023

Posted by:
andrew

andrew Avatar

Location:
United Kingdom

andrew Twitter  andrew Website  

Hi sunilvb

The ultrasonic sensors arrived and as I suspected both models will not work with the IO Pi Plus.

I did have some success using the RCWL-1601 sensors with the I2C Switch. I connected two sensors to the switch, one on channel 1 and one on channel 2 and added 10K pull-up resistors to the SDA and SCL pins on each sensor.

I placed both ultrasonic sensors side by side on a breadboard and found that when the RCWL-1601 is being used in I2C mode it appears to be sending pulses continuously as there was some interference between the sensors that caused occasional inaccuracies in the readings. I suspect if the sensors were moved further apart or placed in different directions this would not be an issue.

This is the python script I used to test the sensors. It uses the I2CSwitch class from our GitHub repository. https://github.com/abelectronicsuk/ABElectronics_Python_Libraries/tree/master/I2CSwitch


import smbus
import time
import os
from I2CSwitch import I2CSwitch

# I2C address of the RCWL-1601 sensor
SENSOR_ADDRESS = 0x57

# Initialize the I2C bus
bus = smbus.SMBus(1) # Use bus 1 for Raspberry Pi

def start_ranging_session():
# Write '1' to start ranging session
bus.write_byte(SENSOR_ADDRESS, 1)

def read_distance():
# Wait a few milliseconds for the measurement to complete
time.sleep(0.01)

# Read the 3-byte response
data = bus.read_i2c_block_data(SENSOR_ADDRESS, 0, 3)

# Combine the 3 bytes to get the distance in um (divide by 1000 to get mm)
distance_um = (data[0] << 16) | (data[1] << 8) | data[2]
distance_mm = distance_um / 1000

return distance_mm

if __name__ == "__main__":
i2cswitch = I2CSwitch(0x70)
i2cswitch.reset()

while True:
# Set I2C Switch to channel 1 and read the distance
i2cswitch.switch_channel(1)
start_ranging_session()
distance1_mm = read_distance()

time.sleep(0.1)

# Set I2C Switch to channel 2 and read the distance
i2cswitch.switch_channel(2)
start_ranging_session()
distance2_mm = read_distance()

os.system("clear")

print(f"Channel 1 Distance: {distance1_mm} mm")
print(f"Channel 2 Distance: {distance2_mm} mm")

time.sleep(0.5) # Delay between readings

Sign in to post your reply


Note: documents in Portable Document Format (PDF) require Adobe Acrobat Reader 5.0 or higher to view.
Download Adobe Acrobat Reader or other PDF reading software for your computer or mobile device.