Maker.io main logo

Wirelessly Controlling the Pico ARP with the Mini Controller for Pico

2023-12-14 | By Kitronik Maker

License: See Original Project

Courtesy of Kitronik

Guide by Kitronik Maker

Overview

In this blog we are going to look at how to wirelessly control the Kitronik ‎Autonomous Robotics Platform for Pico with the Kitronik Mini Controller for Pico. ‎We will use two Raspberry Pi Pico W's, one in the ARP buggy and the other in the ‎Mini Controller.‎

The library and example code which we look through, can be found on our GitHub ‎repo.‎

How It Works

As we are using two Pico Ws, we can communicate wirelessly between the two. ‎One of the Pico Ws will set itself up as the server which can be connected to. The ‎other Pico W will be the client and connect to the server. Once connected, the two ‎Pico Ws will be able to send and receive messages between them.‎

works_1‎ ‎

This allows us to setup one Pico W with the Mini Controller as the client, which ‎sends commands to the other when we press the buttons. The other Pico W we'll ‎setup with the ARP buggy as the server, which will receive commands from the ‎other and move the buggy.‎

Mini Controller for Pico Code

mini_2

‎Import Libraries

Before we start using the Mini Controller, we first need to import some libraries that ‎we are going to need. We'll use the KitronikPicoWClient class from ‎the PicoWNetworking library to handle our wireless connection with the ARP buggy. ‎We'll use the secrets dictionary from the secrets library to store the SSID and ‎password for our wireless connection. We'll use ‎the KitronikMiniControllerPico class from the KitronikMiniControllerPico library to ‎help us access the components on our Mini Controller.‎

Copy Code
from PicoWNetworking import KitronikPicoWClient
from secrets import secrets
from KitronikMiniControllerPico import *

Setup the Mini Controller for Pico

With the libraries imported, we can setup our Mini Controller. We'll initialise our ‎Mini Controller using the KitronikMiniControllerPico class and store this object in ‎the controller variable.‎

Copy Code
# Setup Mini Controller for Pico
controller = KitronikMiniControllerPico()‎

Let's also create some flag variables that will help us keep track of when our ‎buttons are being held down. We will call these flags upClicked, for example, to ‎store when the Up button is being pressed. We can set them all to be False to start ‎off with as our buttons aren't being pressed yet.‎

Copy Code
# Create flags for button presses
# Want to send the command once, when the button is initially pressed
upClicked = False

Setup the Wireless Connection

We'll setup our wireless connection using the PicoWNetworking library to help us. ‎We are going to set the Mini Controller as the client meaning it will connect to the ‎ARP buggy. To do this we want to initialise an object called client using ‎the KitronikPicoWClient class. We'll pass the server's SSID and password from ‎the secrets dictionary as the two inputs for the client constructor. This will tell ‎the client class which device we want to connect to.‎

Copy Code
# Setup network connection with Pico ARP
# Client - Connect to soft AP setup by the server
client = KitronikPicoWClient(secrets["ssid"], secrets["password"])

Next, we need to wait until we have connected to the server. We can wait for the ‎connection to be made using a while loop which checks the status of our wireless ‎connection. The loop will continue to repeat while the client has not established a ‎connection with the server.‎

Copy Code
# While not connected, waiting for connection
while not client.isWifiConnected():
pass

Now we have the client wirelessly connected to the server we need to setup a way ‎to communicate with the server. We want to surround the next section of code in a ‎try catch block. Inside the try block the Pico W will try and run the code. If any ‎errors occur when running this code, then we will catch those errors and handle ‎them in a suitable way. For our code, we could have an error while communicating ‎with the server. If this happens, we want to close the connection with the server.‎

Inside of the try block, let's start by opening a communication channel with the ‎server using the connectToServer function on the client. After our client has ‎connected let's turn the onboard LED on to show we have full wireless ‎communication available. At the end of the try block, we'll want to disconnect from ‎the server to close the wireless communication.‎

Copy Code
try:
# Connect to the server to open a communication channel
client.connectToServer()
# Turn LED on to show its connected
led.on()

# The rest of our code will go here

# Close connection
client.disconnect()
except Exception as e:
# Error occurred, close connection
client.disconnect()

Communicate with the ARP Buggy

For our communication with the ARP buggy, we are going to put this inside of an ‎infinite loop. This means our loop will continue repeating forever. We can use ‎a while loop with the condition set to True to make an infinite loop. At the start of ‎our loop, we want to create the message variable and set it to be an empty string.‎

Copy Code
   # Loop forever
while True:
# Clear message
message = ""

Next, we are going to detect button presses on our Mini Controller. We'll add these ‎inside of the infinite loop to continuously check when a button is being pressed. An ‎example of this is our Up button. We'll check when the Up button is being pressed ‎using an if statement and using the Up.pressed() function as the condition. Then ‎when the Up button on our Mini Controller is being pressed down, the code inside ‎of the if statement will execute.‎

Inside our if statement we are going to check that the upClicked flag has not been ‎set or is False. When the upClicked flag is True we know that we have already ‎detected the current button press. This allows us to only send the command to the ‎ARP buggy a single time each button is pressed and stops us from overloading the ‎wireless connection with commands.‎

When we know this button press has not been detected yet, we want to set ‎the up flag to True and set the message variable to have the Forward command to ‎move the ARP buggy forward.‎

Copy Code
       if controller.Up.pressed():
# When Up pressed and up flag isn't set
if not upClicked:
# Set the up flag and send Forward command
upClicked = True
message = "Forward"

At the end of the button detection if statements, we want to have an else statement. ‎This will allow us to reset our button flags and send the Stop command to stop the ‎ARP buggy moving around. Inside of the else statement we need to check when ‎the upClicked flag is True. When it is, we are going to set the upClicked flag ‎to False and set the message variable to have the Stop command.‎‎

Copy Code
        else:
# Clear any button flags and send Stop command
if upClicked:
upClicked = False
message = "Stop"‎

So far, we haven't sent any commands to our ARP buggy. We'll add this to the end ‎of our infinite loop and start by checking whether the message variable is empty. ‎This if statement checks when the message variable is not empty and means that ‎we have a command stored inside of message.‎

When we have a command to send, we can use the client function ‎called sendToServer which takes a single input for the message we want to send ‎to the server. As we want to send our command, we'll use the message variable as ‎the input for the function to tell the ARP buggy what to do.‎

Copy Code
       # When we have a command in message
if message != "":
# Send command to server
client.sendToServer(message)

Pico Autonomous Robotics Platform Code

platform_3 ‎ ‎

Import Libraries

Before we start using the ARP buggy, we first need to import some libraries that ‎we are going to need. We'll use the KitronikPicoRobotBuggy class from ‎the PicoAutonomousRobotics library to help us access the components on our ARP ‎buggy. We'll use the KitronikPicoWServer class from the PicoWNetworking library ‎to handle our wireless connection with the Mini Controller. We'll use ‎the secrets dictionary from the secrets library to store the SSID and password for ‎our wireless connection.‎

Copy Code
from PicoAutonomousRobotics import KitronikPicoRobotBuggy
from PicoWNetworking import KitronikPicoWServer
from secrets import secrets

Setup the Autonomous Robotics Platform Buggy

With the libraries imported, we can setup our ARP buggy. We'll initialise our ARP ‎buggy using the KitronikPicoRobotBuggy class and store this object in ‎the buggy variable.‎

Copy Code
# Setup Pico Autonomous Robotics Platform Buggy
buggy = KitronikPicoRobotBuggy()

Let's also create a speed variable to store current speed of our buggy. We'll set ‎this to 50% to start off with.‎

Copy Code
# Set the buggy speed to 50%
speed = 50

Setup the Wireless Connection

We'll setup our wireless connection using the PicoWNetworking library to help us. ‎We are going to set the ARP buggy as the server meaning it will receive the ‎connection from the Mini Controller. To do this we want to initialise an object ‎called server using the KitronikPicoWServer class. We'll pass the SSID and ‎password from the secrets dictionary as the two inputs for the server constructor. ‎This will start the server using the SSID and password provided, allows devices to ‎connect to it using those values.‎

Copy Code
# Setup network connection with Mini Controller for Pico
# Server - Start soft AP for client to connect to
server = KitronikPicoWServer(secrets["ssid"], secrets["password"])

Next, we need to wait until the server has set itself up, and is available for devices ‎to connect to. We can wait for it to turn on using a while loop which checks the ‎status of our wireless connection. The loop will continue to repeat while ‎the server is not fully setup.‎

Copy Code
# While not turned on, waiting for access point
while server.isAPConnected() == False:
pass

Now the server is available for wireless connections we want to listen for the client ‎to open a communication channel. This will allow the client and server to send ‎messages to each other. We want to surround the next section of code in a try ‎catch block. Inside the try block the Pico W will try and run the code. If any errors ‎occur when running this code, then we will catch those errors and handle them in a ‎suitable way. For our code, we could have an error while communicating with the ‎client. If this happens, we want to close the connection with the client.‎

Inside of the try block, let's start by listening for the client to open a communication ‎channel using the listenForClient function on the server. After our server has ‎opened a communication channel let's turn the onboard LED on to show we have ‎full wireless communication available. At the end of the try block, we'll want to ‎disconnect from the client to close the wireless communication.‎

Copy Code
try:
# Listen for the client to open a communication channel
server.listenForClient()
# Turn LED on to show its connected
led.on()

# The rest of our code will go here

# Close connection
server.disconnect()
except Exception as e:
# Error occurred, close connection
server.disconnect()

Communicate with the Mini Controller

For our communication with the Mini Controller, we are going to put this inside of ‎an infinite loop. This means our loop will continue repeating forever. We can use ‎a while loop with the condition set to True to make an infinite loop. At the start of ‎our loop, we want to create the message variable and set it to be an empty string.‎

After this we want to receive the command from our Mini Controller. We will ‎receive a message from the client by using the server function ‎called receiveFromClient. This function returns the string message that has been ‎received by the server and we'll store this in the message variable. ‎The message variable will store the command we have been sent by the Mini ‎Controller.‎

Copy Code
    # Loop forever
while True:
# Clear message
message = ""
# Receive command from client
message = server.receiveFromClient()

Next, we are going to check which command we have received in ‎the message variable. To do this we'll use if statements to test the contents ‎of message against our known commands. The first one will be ‎the Forward command and checking when message is equal to it.‎

When we have received the Forward command in message, we simply want to turn ‎both motors on going forward at our current speed.‎

Copy Code
       if message == "Forward":
# When Forward command received, move buggy forward
buggy.motorOn("l","f",speed)
buggy.motorOn("r","f",speed)

At the end of checking for known commands we want to use an else statement ‎which essentially acts as our Stop command. Inside the else statement we are ‎going to turn off both motors on the buggy, to stop any movement.‎

Copy Code
        else:
# When we don't receive an above command
# Assume Stop command and turn off motors
buggy.motorOff("l")
buggy.motorOff("r")

Conclusion

In this blog we have learnt how to use the wireless networking on the Pico Ws to ‎control the ARP buggy using the Mini Controller. Now that we have seen how we ‎can add the basic functionality, you can now customise this code to make your own ‎fun projects using the ARP buggy and Mini Controller.‎

You can also check out the GitHub repo to see the full example code project.‎

‎©Kitronik Ltd – You may print this page & link to it but must not copy the page or part thereof ‎without Kitronik's prior written consent.‎

制造商零件编号 5338
KITRONIK AUTONOMOUS ROBOTICS PLA
Kitronik Ltd.
制造商零件编号 5353
MINI CONTROLLER FOR RPI PICO
Kitronik Ltd.
制造商零件编号 SC0918
RASPBERRY PI PICO W RP2040
Raspberry Pi
Add all DigiKey Parts to Cart
TechForum

Have questions or comments? Continue the conversation on TechForum, DigiKey's online community and technical resource.

Visit TechForum