2023-04-27 12:32 PM
I want to connect four SATEL-53L7CX ToF sensors to a Jetson Orin Nx with an AVerMedia D131 carrier board. The board has a 40-pin expansion header with two i2c buses.
I have created a wiring diagram to connect every two sensors to each i2c bus.
Each sensor shares SDA and SCL with another sensor connected to the same bus, AVDD and IOVDD are connected to the Jetson with 5V and 3.3V pins respectively, the other pins of the two sensors (LPn, PWR_EN, I2C_RST) are connected to different GPIOs.
Steps:
I connect one sensor, then change the i2c address using set_i2c_address() and get the measurements.
But when I connect the second sensor to the same bus, the line immediately stops seeing any connected sensors, even though the two sensors already have different addresses — modified 0x38 and default 0x52).
Please, could you share thoughts on how to connect four ToF sensors to two i2c buses on Jetson?
Thanks in advance.
I will be very grateful to you!
Solved! Go to Solution.
2023-05-16 07:23 AM
You are exactly right. It's the cable length. And you are not the only one. 20 years ago, I had an unstable I2C desgin, and the trace length was about a foot. Six or seven years ago, I was debugging an ST cable of about 50cm. Worked fine as soon as I shortened the cable.
So you are not the first, and certainly will not be the last.
The I2C bus was invented to send one or two byte commands to chips during startup. And over the years it has changed to a full blown bus. Although not a very robust one.
NXP bought Phillips and they have a lot of documentation on tuning a bus. You need to evaluated the capacatance and size the pull-ups. It takes work and depends on the number of deviced on the bus, the bus length and even the size of the wire gets into it.
Shorting the wire is the best solution. Using two different busses will work too.
And if you want to prove that it's the bus length, get a scope and look at the lines. You will find that either the clock or the data line will be stuck low. And when not transmitting both these lines should be high.
2023-04-27 01:43 PM
I don't think hot swapping like that is going to work. The I2C is a pretty flakey bus to start with.
If you have some of those GPIOs under software control, drop the LPn pins on both, bring one up and prove the I2C works. Change it's address, Prove that works, then lift the LPn pin on the second sensor.
You will then have two working sensors.
If you don't have software control, attach both sensors and remove only the LPn pin of the second sensor. After changing the address of the first, re-connect the LPn pin and give it a try.
Should work.
2023-04-29 12:24 PM
Thank you for the quick response!
Yes, I'm going to use the gpiod library for C++.
To start off, I tried to test the connections using GPIO control through the sysfs interface provided by the Linux kernel. However, I was unsuccessful in swiftly establishing a connection with two sensors. As a result, I opted to test the connection using the "Hot Start" method mentioned above.
Could you please help with the necessary information for the initial states of each connected GPIO? Specifically, I need to know both sensors' assigned output/input direction and High/Low signal for the PWR_EN, I2C_RST, and LPN pins.
And how to change the GPIO states to change the address of one sensor and stream data continuously from two sensors?
You started to describe LPn toggling, but could you please write the step-by-step method for all the pins? I'm very grateful to you.
Thanks,
Daniil.
2023-05-01 07:14 AM
first - Google "SATEL-53L7CX Schematic". It will pop up on the ST web site.
Note that pin 5 is the LPn pin. When you drop this pin to 0, it will disable the sensor from communicating.
Next, hook up both sensors, and unhook pin 5 from one of the devices.
Boot your linux.
Prove that one of the sensors works - it will be the one with the connected pin 5.
Then change the address, and prove that worked.
Then re-connect pin 5.
You should now have both sensors working.
PWR_EN - high.
I2C_RST I think needs to be low.
LPn - high enables the I2C interface.
2023-05-15 02:24 AM - edited 2023-11-20 06:56 AM
@john E KVAM Thank you for the help!
I wrote a small script to handle sensor connections and establish a connection with each sensor:
#!/bin/bash -e
# GPIO control, Avermedia D131 & Jetson Orin NX
# Access
sudo chmod 777 /dev/i2c-1
sudo chmod a+rw /dev/gpiochip0
sudo chmod a+rw /dev/gpiochip1
# Sensor 1
# LPn
gpioId_p2_lp=492
gpioIndex_p2_lp=PAC.06
# PWR_EN
gpioId_p2_pwr=433
gpioIndex_p2_pwr=PN.01
# I2C_RST
gpioId_p2_i2c_rst=471
gpioIndex_p2_i2c_rst=PY.01
# Sensor 2
# LPn
gpioId_p3_lp=389
gpioIndex_p3_lp=PG.06
# PWR_EN
gpioId_p3_pwr=481
gpioIndex_p3_pwr=PZ.03
# I2C_RST
gpioId_p3_i2c_rst=461
gpioIndex_p3_i2c_rst=PR.05
# Sensor 3
# LPn
gpioId_p4_lp=453
gpioIndex_p4_lp=PQ.05
# PWR_EN
gpioId_p4_pwr=454
gpioIndex_p4_pwr=PQ.06
# I2C_RST
gpioId_p4_i2c_rst=482
gpioIndex_p4_i2c_rst=PZ.04
# Sensor 4
# LPn
gpioId_p5_lp=391
gpioIndex_p5_lp=PH.00
# PWR_EN
gpioId_p5_pwr=398
gpioIndex_p5_pwr=PH.07
# I2C_RST
gpioId_p5_i2c_rst=399
gpioIndex_p5_i2c_rst=PI.00
echo -e 'Initial GPIO state:\n'
echo 'The first sensor LP PWR_EN I2C_RST, P2 Connector:'
sudo cat /sys/kernel/debug/gpio | grep -e ${gpioId_p2_lp} -e ${gpioId_p2_pwr} -e ${gpioId_p2_i2c_rst}
echo
echo 'The second sensor LP PWR_EN I2C_RST, P3 Connector:'
sudo cat /sys/kernel/debug/gpio | grep -e ${gpioId_p3_lp} -e ${gpioId_p3_pwr} -e ${gpioId_p3_i2c_rst}
# Export GPIO
echo ${gpioId_p2_lp} > /sys/class/gpio/export
echo ${gpioId_p3_lp} > /sys/class/gpio/export
echo ${gpioId_p4_lp} > /sys/class/gpio/export
echo ${gpioId_p5_lp} > /sys/class/gpio/export
echo ${gpioId_p2_pwr} > /sys/class/gpio/export
echo ${gpioId_p3_pwr} > /sys/class/gpio/export
echo ${gpioId_p4_pwr} > /sys/class/gpio/export
echo ${gpioId_p5_pwr} > /sys/class/gpio/export
echo ${gpioId_p2_i2c_rst} > /sys/class/gpio/export
echo ${gpioId_p3_i2c_rst} > /sys/class/gpio/export
echo ${gpioId_p4_i2c_rst} > /sys/class/gpio/export
echo ${gpioId_p5_i2c_rst} > /sys/class/gpio/export
# Set output direction
echo out > /sys/class/gpio/${gpioIndex_p2_lp}/direction
echo out > /sys/class/gpio/${gpioIndex_p3_lp}/direction
echo out > /sys/class/gpio/${gpioIndex_p4_lp}/direction
echo out > /sys/class/gpio/${gpioIndex_p5_lp}/direction
echo out > /sys/class/gpio/${gpioIndex_p2_pwr}/direction
echo out > /sys/class/gpio/${gpioIndex_p3_pwr}/direction
echo out > /sys/class/gpio/${gpioIndex_p4_pwr}/direction
echo out > /sys/class/gpio/${gpioIndex_p5_pwr}/direction
echo out > /sys/class/gpio/${gpioIndex_p2_i2c_rst}/direction
echo out > /sys/class/gpio/${gpioIndex_p3_i2c_rst}/direction
echo out > /sys/class/gpio/${gpioIndex_p4_i2c_rst}/direction
echo out > /sys/class/gpio/${gpioIndex_p5_i2c_rst}/direction
# Power
echo 1 > /sys/class/gpio/${gpioIndex_p2_pwr}/value # HIGH
echo 1 > /sys/class/gpio/${gpioIndex_p3_pwr}/value # HIGH
echo 1 > /sys/class/gpio/${gpioIndex_p4_pwr}/value # HIGH
echo 1 > /sys/class/gpio/${gpioIndex_p5_pwr}/value # HIGH
# I2C_RST
echo 0 > /sys/class/gpio/${gpioIndex_p2_i2c_rst}/value # LOW
echo 0 > /sys/class/gpio/${gpioIndex_p3_i2c_rst}/value # LOW
echo 0 > /sys/class/gpio/${gpioIndex_p4_i2c_rst}/value # LOW
echo 0 > /sys/class/gpio/${gpioIndex_p5_i2c_rst}/value # LOW
# LPn, pull up the first sensor only
# P2
echo 1 > /sys/class/gpio/${gpioIndex_p2_lp}/value # HIGH
# P3
echo 0 > /sys/class/gpio/${gpioIndex_p3_lp}/value # LOW
# P4
echo 1 > /sys/class/gpio/${gpioIndex_p4_lp}/value # HIGH
# P5
echo 0 > /sys/class/gpio/${gpioIndex_p5_lp}/value # LOW
echo
echo -e 'GPIO state after powering the sensors:\n'
echo 'The first sensor LP PWR_EN I2C_RST, P2 Connector:'
sudo cat /sys/kernel/debug/gpio | grep -e ${gpioId_p2_lp} -e ${gpioId_p2_pwr} -e ${gpioId_p2_i2c_rst}
echo
echo 'The second sensor LP PWR_EN I2C_RST, P3 Connector:'
sudo cat /sys/kernel/debug/gpio | grep -e ${gpioId_p3_lp} -e ${gpioId_p3_pwr} -e ${gpioId_p3_i2c_rst}
echo
echo 'The third sensor LP PWR_EN I2C_RST, P4 Connector:'
sudo cat /sys/kernel/debug/gpio | grep -e ${gpioId_p4_lp} -e ${gpioId_p4_pwr} -e ${gpioId_p4_i2c_rst}
echo
echo 'The fourth sensor LP PWR_EN I2C_RST, P5 Connector:'
sudo cat /sys/kernel/debug/gpio | grep -e ${gpioId_p5_lp} -e ${gpioId_p5_pwr} -e ${gpioId_p5_i2c_rst}
For P2 and P3 connectors, this solution works:
But, the connection wasn't established with sensors on P4 and P5 connectors.
So, I decided to connect one sensor that works properly using jumpers, following the connector scheme for each P4, and P5 connection. And the connection was established only with jumpers according to the scheme, but the connection via cable connector didn't succeed (I checked all pins for continuity).
I guess the problem may be in the length of the cable.
Connectors P4 and P5 have a cable length of about 1.5 meters:
Please advise me on how to solve this issue and if there can be something else for a reason.
Thank you!
2023-05-16 07:23 AM
You are exactly right. It's the cable length. And you are not the only one. 20 years ago, I had an unstable I2C desgin, and the trace length was about a foot. Six or seven years ago, I was debugging an ST cable of about 50cm. Worked fine as soon as I shortened the cable.
So you are not the first, and certainly will not be the last.
The I2C bus was invented to send one or two byte commands to chips during startup. And over the years it has changed to a full blown bus. Although not a very robust one.
NXP bought Phillips and they have a lot of documentation on tuning a bus. You need to evaluated the capacatance and size the pull-ups. It takes work and depends on the number of deviced on the bus, the bus length and even the size of the wire gets into it.
Shorting the wire is the best solution. Using two different busses will work too.
And if you want to prove that it's the bus length, get a scope and look at the lines. You will find that either the clock or the data line will be stuck low. And when not transmitting both these lines should be high.
2023-05-17 04:13 AM
Hi!
Thanks for the detailed reply and the brief story about the "erratic" i2c bus)
I also observed that if the P3 and P4 wires are very close to each other, there is noise in the signals.
I'll do the appropriate tests and keep you updated.