In Thonny, click on the Run->Configure Interpreter buttons at the top of the window.
Choose "MicroPython (Raspberry Pi Pico) from the first dropdown menu.
-
Click the "Install or update MicroPython" button down the bottom-right of the window.
-
You need to put your device in FLASH mode, hold down the BOOT button, press and release the RESET button.
+
Click the "Install or update MicroPython" button down the bottom-right of the window.
+
+
You need to put your device in FLASH mode, hold down the BOOT button, press and release the
+ RESET button.
You should now find a drive called "RPI-RP2". in the Target volume dropdown, shoose it.
Choose the variant "Raspberry Pi Pico - Pico / Pico H"
Press Install button to install the firmware.
Reset the device again with the RESET button.
-
Press the cancel button to close the firmware update panel, then press OK to officially begin coding.
+
Press the cancel button to close the firmware update panel, then press OK to officially
+ begin coding.
@@ -100,8 +107,10 @@
Step 1: Open/Create the main.py file
-
When your device is plugged into your computer, you should be able to press the File->Load button, and choose "Raspberry Pi Pico" to load from.
-
If no such file exists we need to make it, press File->New, and then save it to the Raspberry Pi Pico as "main.py"
+
When your device is plugged into your computer, you should be able to press the File->Load
+ button, and choose "Raspberry Pi Pico" to load from.
+
If no such file exists we need to make it, press File->New, and then save it to the Raspberry Pi
+ Pico as "main.py"
@@ -110,7 +119,8 @@
Step 2: Open the Serial Monitor
-
To get messages back from your device, and to read errors, press the view->shellbutton and make sure
+
To get messages back from your device, and to read errors, press the view->shellbutton and make
+ sure
you have the shell window open at the bottom.
@@ -119,7 +129,8 @@
print("Hello World") and then save, yuou should see the message appear in the
Serial monitor.
-
Note that the code won't persist on the robot after a reset unless you also SAVE it to the device, RUN just runs it once
+
Note that the code won't persist on the robot after a reset unless you also SAVE it to the
+ device, RUN just runs it once
Step 4: Code all the things!
@@ -132,7 +143,7 @@
-
+
@@ -908,10 +919,13 @@ while True:
Step 2: Coding
-
We'll use a library to handle sending and listening for the pulses. Put this module on your device.
+
We'll use a library to handle sending and listening for the pulses. Put this module on your
+ device.
-
When the "distance()" function is called, it sends a short pulse on the trigger pin, then waits for a response on the echo pin. The time it takes for the echo to return is used to calculate the distance.
-
+
When the "distance()" function is called, it sends a short pulse on the trigger pin, then waits
+ for a response on the echo pin. The time it takes for the echo to return is used to calculate
+ the distance.
+
@@ -955,7 +969,8 @@ class Sonar:
Step 3: Call it in the main.py
-
Now all we need to do is create the object and call the distance function in the main.py file.
+
Now all we need to do is create the object and call the distance function in the main.py file.
+
Like most inputs, the sonar data is noisy, and there are different types of noise.
+
On the right you can see a fairly fixed output, but with sudden spikes of irregular data.
+
+
So we need code that will filter our spikes like that, the easiest is to just throw them away. To
+ do this we'll use a simple moving average filter.
+
+
+
+
+
+
+
+
+
+
+
Step 2: Coding a moving average filter
+
Instead of just taking single data points and making decisions, we'll keep an array of the last 8
+ readings.
+
+
First we need to start keeping a rolling buffer of the last 8 readings.
+
We'll use a list to store the readings, and we'll use the append() method to add new
+ readings to the end of the list.
+
We'll use the pop(0) method to remove the oldest reading from the start of the list.
+
+
We'll use the len() method to check the size of the list.
+
We'll use the print() method to print the list.
+
+
NOTE: We can get smoother results by using a larger buffer size, but this can also start
+ to introduce lag.
+
+
+
+
+
+
+BUFFER_SIZE = 8 # The size of the buffer
+buffer = [] # Create an empty array to hold
+ # the readings (this is the rolling buffer)
+
+while True:
+ dist = sonar.distance() # Get a new reading
+ buffer.append(dist) # Add it to the buffer
+
+ # If the buffer is too big, remove the oldest reading
+ if len(buffer) > BUFFER_SIZE:
+ buffer.pop(0)
+
+ print(buffer) # Print the buffer
+
+
+
+
+
+
+
Step 3: Take the average
+
Now all we need to do is create the object and call the distance function in the main.py file.
+
+
+def average_filter(values):
+ total = 0
+ for i in range(len(values)):
+ total = total + values[i]
+
+ return total / len(values)
+
+
+# Call in the main loop
+filtered = average_filter(values)
+print(filtered)
+
+
+
+
+
+
+
+
+
+
Step 4: Take the median
+
That's better, but those large peaks are still throwing our average off quite a bit. We can improve this by taking the MEDIAN of the buffer rather than the average.
+
+
+def median_filter(values):
+ sorted_vals = sorted(values) # sort the values from low->high
+ mid = int(len(sorted_vals) / 2) # get the middle index
+ return sorted_vals[mid] # return the value of the median
+
+
+# Call in the main loop
+filtered = median_filter(values)
+print(filtered)
+
+
+
+
+
+
+
+
+
+
Step 5: Fine tuning
+
Before moving on, play with the buffer size to see how it effects the results AND the responsiveness to changes.
+
Try and find a good balance with the time.sleep() value as well
+
+
+
+
+
+
+
+
+
+
Receiver
+
+
+
+
+
+
+
+
Step 1: Coding
+
Create a new file called remote.py and add the code to the right.
Initialize the receiver with receiver = ThumbInput()
+
+
Create a new loop as this won't work nicely with any i2c, this loop should be placed after the
+ motors are created, and before the i2c is initialized.