CircuitPython code on RP2350 for 4tronix M.A.R.S. Rover Robot remote control using the PiHut Wireless USB Game Controller
This folder contains the CircuitPython 9.2.4 code and interconnection diagram for controlling the 4tronix M.A.R.S. Rover Robot using a Challenger+ RP2350 WiFi6/BLE5 development board instead of the Raspberry Pi Zero computer board.
The Rover control requires the following signals from the RP2350-based board to be provided to the main rover board, via the the 2x20-pin connector normally used for connecting the Raspberry Pi Zero. The Table below summarizes the connections and the CircuitPython modules used to control the required I/O signals.
The corresponding interconnection diagram is available in ChallangerRP2350-MARS.
Controls | I/O | RasPi GPIO | RP2350 GPIO (JP1/2 pin) | CircuitPython module/driver |
---|---|---|---|---|
DC motors (via DRV8833) | 4x PWM | 12, 16, 13, 19 | 24(D6), 25(D9), 2(D10), 3(D11) | pwmio |
Servo motoros (via PCS9685) | I2C @ 0x40 | 2, 3 | 20 (SDA), 21 (SCL) | busio.I2C, PCA9685, motor-servo |
EEROM | I2C @ 0x50 | 2, 3 | 20 (SDA), 21 (SCL) | I2C Bus device |
LED control (direct) | 1x PWM | 18 | 7 (D13) | neopixel |
#23, #24, #25, #05 | 4x GPIO | 23, 24, 25, 5 | 26 (A3), 27(A2), 28(A1), 29(A0) | digitalio |
The code was built for and tested with:
- Challenger+ RP2350 WiFi6/BLE5 development board.
- CircuitPython version en_GB-9.2.4 from Adafruit.
- mpy-cross-*-9.2.4-236
- PiHut Wireless USB Game Controller
Steps:
-
Install CircuitPython on the device. The following libraries are required to be present in the
lib
folder in the root of the CircuitPython device, on the Challenger+ RP2350 WiFi6/BLE5 board:adafruit_motor
folder ,neopiel.mpy
,adafruit_pixelbuf.mpy
,adafruit_pca9685.mpy
andadafruit_hcsr04.mpy
. -
Copy the content of the root folder, including the lib folder, from the repo into the root of the CircuitPython device. The library files in lib can be compiled to mpy format to save space.
-
Copy the main.py and boot.py files into the root of the CircuitPython device. Note that this operation will overwrite the potentially existing main.py and boot.py files.
- There are four options: code.txt, code.py, main.txt and main.py, see Creating and Editing Code. CircuitPython looks for those files, in that order, and then runs the first one it finds. Hence, we use the
main.py
here to allow running the optional virtual OS shell from thecode.py
without overwriting themain.py
.
- There are four options: code.txt, code.py, main.txt and main.py, see Creating and Editing Code. CircuitPython looks for those files, in that order, and then runs the first one it finds. Hence, we use the
The main code will run automatically after (soft) reboot and does not require serial terminal access.
The settings.toml is used to configure the parameters for the custom M.A.R.S Rover drive modules. The variables in this file are read a environment variables in CircuitPython.
The main is the main CircuitPython implementation for the 4tronix M.A.R.S. Rover Robot remote control using the PiHut Wireless USB Game Controller. It uses the modules rover_cpy
, drivefunc
and pihutwugc
described below.
The rover_cpy implements the API to the rover hardware. For maximum backwards compatibility with the original rover.py
implementation provided by 4tronix, almost all the function definitions in this class are kept identical. This class also implements the original pca9685.py functionalities.
The pihutwugc implements the API for the PiHut Wireless USB Game Controller, loosely insipired by the Approximate Engineering implementation and adapted for CircuitPython. This class implements only the API for the PiHut Wireless USB Game Controller for now, see details in README-USBHost.
The drivefunc implements the custom functions to drive and control the rover. It uses the rover_cpy
API. This implementation is based on the Python code from rover_wugc.
The basic implementation is not performing well due to timing issues. One possible solution is to use cooperative multitasking with asyncio. The secction below describes the experiments using this approach.
Cooperative multitasking with asyncio
The main_async is the implementation using CircuitPython asyncio API. This script relies on the drivefunc in which all the LED effects/animations need to be disabled. This is achieved with the setting USE_ASYNC = True
. The LED effects/animations are restricted in the asyncio version to enable smoother driving experience. Further improvements are definetly possible.
The servoTest, motorTest and mastTest scripts provide manual tests for various rover_cpy functionalities. These scripts are based on their original counterparts provided by 4tronix. The ledTest and driveTest scripts provide manual tests for various drivefunc functionalities. The wugcTest script provides manual tests for various pihutwugc functionalities.
The calibrateServos can be used to calibrate the 0-degree position of the servo motors (1 to 6) and save the offsets in the EEPROM on the main rover board. This script is based on the original counterpart provided by 4tronix.
The usbhostTest and usbreportTest are standalone scripts, do not depend on the custom rover libraries above, and can be used for testing the USB host functionalities in general. More details on USB host related implementation can be found in README-USBHost. The usbhostTest uses the Adafruit USB Host Descriptors library (adafruit_usb_host_descriptors.mpy
).
All these test scripts require a serial terminal, while the RP2350-based board is connected to a PC, and can be run from the virtual OS shell or from the REPL.