Outils pour utilisateurs

Outils du site


issue194:micro-ci_micro-la

Ceci est une ancienne révision du document !


Before we get started on this month’s subject, I want to give you a little bit of an update on MicroPython 1.20.

As of the first of June 2023, the I2C issue still somewhat exists. You CAN use I2C, but, at this time, you can’t use the old defaults. I say old defaults because it looks like the people at RPi asked that the defaults be changed to what they are now. So, to be sure that your I2C projects will work under 1.20, use the table below to set your I2C pins.

As to the NeoPixel driver, you CAN use the one you used previously, but should rename it, just to avoid any confusion between you and MicroPython. I’ve tested this using the Pico-W and the Pico with three sets of 1-meter strings of 30 devices each. Everything works fine.

Also, as of June 2023, the BLE bluetooth drivers were still being worked on, but were showing great progress. When done, you should be able to use most code from ESP-32 boards.

I’ll give you a hint about the subject of the next MTMT, which should be controlling motors using the Pico-W. This is a great way to break into robotics.

Now onto the subject of the month, the HC-SR04 ultrasonic obstacle avoidance sensor.

As far as I know, this sensor comes only in a 5Vdc version. However, not all is lost. I was able to get a small 4-channel I2C-safe Bi-directional Logic Level Converter that costs about $4.00 USD. It works well.

You can see it in the wiring image above.

The pinout is pretty straightforward, even if you are using the logic level converter. I’ve created a small table here (below) to help you along.

I’ve tested the project with and without the logic level converter, and I haven’t noticed any major difference between the two setups, so if you don’t have a converter, you should be able to use it without any problems.

How it works

There is a lot of science behind this little sensor and I would be remiss if I didn’t address it here. So I’m going to put on my science geek hat before we get into the code.

Looking at the datasheet, whenever the Pico/MicroController wants to see if there is anything within its range, it sends out a pulse on the Trigger pin of the sensor. That causes the sensor to send out a burst of 8 pulses of ultrasonic sound at 40 kHz through the emitter and then it starts listening for an echo. The ultrasonic sound will bounce off most objects within the 4-meter maximum range and hopefully come back to the receiver. The amount of time between the sending and receiving is measured (in microseconds), and can be converted into a distance measurement using a formula EchoTime(us) / 58 = centimeters. This is then sent back to the driver which, in turn, sends the distance back to our program.

Our program can then take the information from the driver and simply display it, or use it to determine how much closer to the detected object the application wants to get.

The sensor has a range somewhere between about 2 cm and 4 meters, but the max distance could be anywhere between 2 and 4 meters.

All of that having been said, we have to remember to consider what kind of material we are going to be encountering as we try to use this project.

Because we are relying on an echo coming back to the sensor, we have to take into account what type of object the ultrasonic signal is bouncing off of. If it’s a hard surface like wood or drywall, there won’t be much absorption. However, if the object is like a curtain, a fair amount of the signal will be absorbed and might give you false data.

Another thing you want to take into consideration – if you are going to mount the sensor on, let’s say, a rover or small robot – make sure that the sensor is mounted as straight as possible at the front of the device. This is due to the signal’s reflection not returning. The law of physics says that the angle of incidence is equal to the angle of reflection. This gets into some pretty deep science, so I’ll avoid a discussion here. If you are curious, you can look at http://www.fast.u-psud.fr/~martin/acoustique/support/r%C3%A9flection-r%C3%A9fraction.pdf or https://en.wikipedia.org/wiki/Angle_of_incidence_(optics). You could also do an Internet search for “ultrasonic reflection” to find other sources of information.

The Code

There are a few drivers out there and you can certainly “roll your own”. However, I’m going to suggest you start with one that works pretty well for me. You can find it, as well as their code to run the driver on the RPi Pico/Pico-W, at https://microcontrollerslab.com/hc-sr04-ultrasonic-sensor-raspberry-pi-pico-micropython-tutorial/

They have a much deeper explanation of how the whole thing works, so you might want to take a look at their article as well as getting the code. I’ll also put it in a repository for your convenience.

First the driver. I’ll show only the important parts here.

import machine, time

from machine import Pin

First, we have the imports. The driver simply uses machine, machine.Pin, and time.

Next, we have the actual class. I’m going to omit most of the comments.

The init function (above) sets up the trigger and echo pins and the echo timeout value (in microseconds).

The _send_pulse_and_wait() function sends a pulse of 10 microseconds to the trigger pin, then starts looking for a return pulse on the echo pin, checking the elapsed time (bottom left).

The distance_mm() function is not actually called from the test program, but is there if you want to get return data that is more granular than the distance_cm() function (below).

The distance_cm() function (below) is the actual function that gets called from the test program. It first calls the _send_pulse_and_wait() function, and gets back the pulse time. Then that value is returned as the number of centimeters that represents the time between the trigger and the echo return.

If you want to see the reasoning behind the formulas, you can look at the comments in the actual driver file.

As for the test program, it’s really much simpler than the actual driver.

We import the driver class and time.sleep.

from hcsr04 import HCSR04

from time import sleep

Then, we instantiate the class from the driver, assigning the trigger and echo pins, and providing a timeout value in microseconds.

I added an optional line of code to assign a button on GPIO 20 as an input. This is so we can poll pin 20 for a low to let the program know that the button has been pressed. If the button has been pressed, it will allow the program to exit the forever loop that we will create. There is no issue if you don’t include a button in your setup. The code will still look for the falling signal, but it really won’t make any difference if it doesn’t see it. You can always just use the stop button in Thonny to end the program.

We then enter the ‘forever’ loop (right). We poll the sensor and get a distance value. Then I include a calculation to convert centimeters to inches, display them both on the REPL terminal, check to see if the button has been pressed (if there is one), break the loop if we get a 0 from the button pin, and finally sleep for 1 second before starting the loop all over again.

Testing the program

I’m going to assume that you are using a breadboard to hold your project. Place it on a table and place a ruler between the sensor and something fairly big like a box of tissues. This will give you a known reference. When you run the test program, you should see, about every second, something like this…

Distance 28.95189 cm - 11.39838 in

If it works, and the distance returned is somewhat reasonable, you can test the sensor by pointing at something else. If not, you will most likely be getting a return that looks something like this…

Distance 225.0 cm - 88.58268 in

This is the “default” return that means that the sensor didn’t receive a clear echo back before the timeout value. Given the sensor has a range between about 2 cm and 4 meters, as long as your target is within about 3 meters, this could mean that you have the trigger and echo pins swapped. The other possibility could be that the breadboard you are using has a bad spot or two. Try reseating the Pico, the sensor, and your jumper wires, and try again. I’ve seen it happen that even a brand new breadboard might have a bad spot, or 5, and the normal “tech support” answer is if you are using a breadboard, try different positions for your components and/or check your wires.

Well, that’s about it for this month. As I said, I’ve put the code for both the driver and the demo program in my repository at https://github.com/gregwa1953/FCM194_MTMT. Be sure to save your code for the project and the sensor, because we will be revisiting this in a future article when we get into the subject of robotics.

Until then, as always; stay safe, healthy, positive and creative!

issue194/micro-ci_micro-la.1688187178.txt.gz · Dernière modification : 2023/07/01 06:52 de d52fr