I’ve been having some issues getting the PiicoDev VL53L1X laser distance sensor to connect to a Pi Pico and was wondering if I could get any input on something I might have overlooked or am obviously getting wrong:
The VL53L1X is connected to I2C0 on the Pico, GP20 for SDA and GP21 for SCL, 3.3v for 3.3v and ground for ground.
I have the latest PiicoDev python files and no upload/issues with other scripts running on the Pico itself
Using the following code, I can see the device at address 0x41 and the device power LED is lit:
from PiicoDev_VL53L1X import PiicoDev_VL53L1X
from time import sleep
from machine import I2C
i2c = machine.I2C(0, scl=21, sda=20, freq=400000)
output = i2c.scan()
print("I2C Scan addresses:")
print(output)
Returns:
I2C Scan addresses:
[41]
But when passing this config into the constructor for the VL53L1X (either with the specified address or just leaving the constructor blank), I receive the following:
from PiicoDev_VL53L1X import PiicoDev_VL53L1X
from time import sleep
from machine import I2C
i2c = machine.I2C(0, scl=21, sda=20, freq=400000)
output = i2c.scan()
print("I2C Scan addresses:")
print(output)
print("Starting Distance Sensor:")
distSensor = PiicoDev_VL53L1X(0, 400000, 20, 21, 0x41)
while True:
dist = distSensor.read() # read the distance in millimetres
print(str(dist) + " mm") # convert the number to a string and print
sleep(0.1)
Starting Distance Sensor:
Traceback (most recent call last):
File "<stdin>", line 10, in <module>
File "PiicoDev_VL53L1X.py", line 112, in __init__
File "PiicoDev_VL53L1X.py", line 136, in reset
File "PiicoDev_VL53L1X.py", line 125, in writeReg
OSError: [Errno 5] EIO
I’ve checked for any connectivity issues with a basic multimeter and everything seems to be fine, even though the error showing seems to point at that. I’m using a 4pin cable to connect the VL53L1X back to the pico with a cable distance of <76cm but am unsure if this is an issue.
Thanks for the reply Liam! Yep - I’m a moron. Changing those values to Pin(x) after importing Pin instead of straight ints and I’m now getting data from the sensor successfully. I must’ve missed this - since I switched the numbers between SDA and SCL as part of debugging and it returned a “Invalid SCL pin” error instead, so assumed the int numbers worked. Whoops.
For those playing along at home, the solution was to update the initialisation to be:
from PiicoDev_VL53L1X import PiicoDev_VL53L1X
from time import sleep
from machine import I2C, Pin # Import Pin
i2c = machine.I2C(0, scl=Pin(21), sda=Pin(20), freq=400000) # Use Pin objects to initialise
Thankyou… this is the best post I’ve found on this subject, but I (a newbie) am still getting errors.
My wiring is exactly the same as shown in JamesD pic above.
What is NOT clear, is how the rest of the code (after the initialisation) should look… specificllly, is this line:
distSensor = PiicoDev_VL53L1X(0, 400000, 20, 21, 0x41)
still good… or do the 20, 21 args also need to be Pin(20), Pin(21) ?
I’ve tried both… and am still getting Errno5 EIO.
My entire code & output is:
from PiicoDev_VL53L1X import PiicoDev_VL53L1X
from time import sleep
from machine import I2C, Pin # Import Pin
i2c = machine.I2C(0, scl=Pin(21), sda=Pin(20), freq=400000)
output = i2c.scan()
print("I2C Scan addresses:")
print(output)
print("Starting Distance Sensor:")
distSensor = PiicoDev_VL53L1X(0, 400000, 20, 21, 0x41)
while True:
dist = distSensor.read() # read the distance in millimetres
print(str(dist) + " mm") # convert the number to a string and print
sleep(0.2)
I2C Scan addresses:
[41]
Starting Distance Sensor:
Using supplied bus, sda, and scl to create machine.I2C() with freq: 400000 Hz
Traceback (most recent call last):
File “”, line 10, in
File “PiicoDev_VL53L1X.py”, line 112, in init
File “PiicoDev_VL53L1X.py”, line 136, in reset
File “PiicoDev_VL53L1X.py”, line 125, in writeReg
OSError: [Errno 5] EIO
Looking back at my code, the distance sensor is part of the PiicoDev library which is what requires the pins to be defined as Pins, so my line of code that you’re referring to is:
Which should hopefully then let you call distSensor.read(). I no longer make use of i2c.scan() and removed those lines, leaving just the distSensor definition.
Still getting EIO error.
To be precise, my earlier post implied I had wired axactly as shown… not sure if it matters, but I have my Pico soldered onto an expansion board, with wires connecting to the sensor board (soldered). Also, my board is actually a Pico W… but I don’t believe that matters… same pinout - right?
I note you also dropped the 0x41 arg… which I believe was wrong anyway… 0x29 is decimal 41. I’v tried both with and without this arg… makes no difference.
Could it be my wires need to be soldered directly to the Pico? I read lots of posts suggesting the EIO error may be related to poor connections?
BTW… I resorted to these wires as the tiny I2C cables I bought were complete failures… could not even power the onboard LED, with the 3.3V dropping to 1.8V on the sensor. That was never going to work!. Whatever… I am still stuck with no data
Worked first time… then didn’t, unsure why, but I nuked the flash, reinstalled 20220831 uf2, and it’s been just fine.
So it seems that whatever broke after that 2022 build has stayed broke…
Some of the technical details in that other thread go over my head…but it does surprise me that this apparently has not been fixed in two years!
Anyway… I have something working, now need to test it, and maybe tweak FOV parameters. I saw a post somewhere that talked about that…
Sorry my response wasn’t helpful, but glad you figured it out and thank you for coming back to the thread to post what worked! I’ll have to also keep that build for the Pico firmware in mind, appreciate that.
I am quite new to all of this stuff… many years in IT, but not with microcontrollers etc. I am still finding my feet. Arduino, Rasberry… micropython… all new, so I really appreciate folk like you who responded so quickly. Many thanks.
I clearly have more to learn about the MicroPython ecosystem…
Code runs… great. But somehow, I sometimes get things messed up… by which I mean, even if I power off, restart Thonny, I get the old error msg again - until and unless I reload the August 2022 uf2 file, ie, basically wipe everything and start over.
Can you please point me to somewhere I can learn what the heck is happening?
I can try to replicate if it helps, it has happened few times now, it is not clear to me what sequence of things cause the fail mode. Grrr… Suffice to say, I know I have the “good” build of micropython on the SRAM, but hitting the Thonny red Stop button, and rerunning the known-to-working code… breaks But not always. Hrumph.
There is a definite problem here.
I loaded Micropython version 1.23.0 through Thonny, downloaded the library and test files from Core Electronics PiicoDev VL53L1X web page, and it all ran ok.
But …
When I tried to use the I2C alternate ports (pins 20 & 21) it failed. After trying a few things to try and find out why I did not come to any conclusive conclusion, after a couple of hours.
So I went back to using the standard pins 8 & 9, that now failed with the same error.
I then removed all files and loaded the library and test file again. Still failed.
Went back to square one and reloaded the Micropython version and it now all works again.
This would be very confusing to any one.
My investigation will continue …
OK … so an old ‘gotcha’ got me.
I restarted the test from scratch with a reload of micropython. I used the following code to change the I2C pins. A slight modification of main.py from the Core Electronics web site. Adds machine library imports and parameter definitions.
from PiicoDev_VL53L1X import PiicoDev_VL53L1X
from time import sleep
from machine import I2C, Pin
bus=0
freq=400000
sda=Pin(8)
scl=Pin(9)
#distSensor = PiicoDev_VL53L1X()
distSensor = PiicoDev_VL53L1X(bus=bus, scl=scl, sda=sda, freq=freq)
while True:
dist = distSensor.read() # read the distance in millimetres
print(str(dist) + " mm") # convert the number to a string and print
sleep(1)
If I changed the pin numbers and ran the code again, it did NOT work no matter what pins I swapped to. If an error occurred the Pico no longer worked even with the right pin numbers.
ie. right pins - works, change to wrong pins - fails, change back to right pins - fails
But … after a power cycle of the Pico it works. If you change the pin numbers in the code, power cycle the Pico.
Note: because the code is named, main.py it runs when the Pico powers up. This confuses the issue because once an error occurs it does not work anymore. My policy is to only change the name to main.py when the code has been adequately tested and works. If for any reason the sensor does not work and the code errors the Pico will need a power cycle to work again. it might only need a reset but the Raspberry Pi Pico boards do not come with a reset button Frustrating !!
Regards
Jim
PS I dont know if this will fix the problem @Trevor277988 is experiencing.
Thanks… my internet was out most of Thursday… and it’s now 12:30 AM Friday. I WILL send code and photos… tomorrow! I notice James46717 has added some useful info…I’ll digest this all after I have got some sleep…
PS Having a ball learning Python, PicoDev… while also building my hardware where this little gadget will be installed. Lots to learn…
Without going into the depths of Micropython my guess is when the program first sets any pin definitions it can only be changed with a reset or power cycle. It would be how the RP-2040 is programmed to determine the function of its pins.
Normally you would not swap pin definitions without a reset. Speaking of reset …
Taking pin 30 of the Pico low provides a hardware reset (labelled Run); using machine.reset() in software does the same thing.
I used the software reset in a project to reboot the processor at midnight, because sometimes the program crashed during the day. The project turned on a water valve for an hour in the morning so it was not a very active project spending most of the time asleep.
The problem seems to be solved… not sure if it is because I’ve renamed main.py to test.py… anyway, as the pics show, now working on both old and new versions of microPython, using pins 20&21. I have not tried changing pins (again) now… I have more pressing things to do!
Jim’s summary above seems to cover this. And yes… confusing. Specially for new players who have no clue what they are doing !!
I’m not the biggest fan of the wiring here. While the board is getting powered it doesn’t look like there is much solder on those pads. You could possibly be losing connection with the Pico while running the script.
That’s definitely concerning! Each of the PiicoDev boards are tested post-manufacture so hardware errors should be rarer, would it be possible to send through some photos?
Unfortunately, the style of connector doesn’t have a satisfying click like one with a latch to prove its engaged. The front of the connector and flange of the cable should be around 1mm apart.