This page details the design choices and implementation of all the electronics used in the completion of this project.
The schematic .pdf and the KiCad project can be found on published GitHub repository.
The system consists of two PIC32MX170F256B (PIC32) microcontrollers (for the boat and the controller). They communicate Zigbee RF using XBee radios, connected to them by UART.
The wireless controller system has its fun-to-watch "charging" procedure.
Wireless Communication was enabled by XBee radio modules in API mode at 9600 baud, 5Hz message rate.
A class-wide communications protocol handled pairing, driving, refueling, and error handling between any Mallard Module and any Quackraft
Refueling starts when a controller operator starts pumping the air pump, which is detected by a limit switch, hit by the upper side of the pump.
Fuel refills proportionally to time pumping the air pump, as a servo gauge on the controller displays remaining fuel continuously.
The system is powered by a small powerbank (Portable Charger (external 5V battery, 5mAH). We have a small power distribution board to match it that regulates our voltages down to 5V for the servo and 3.3V for logic.
The MPLAB SNAP programmer and debugger was used.
We made sure to manage wires well and solder into permanence when possible, especially on the levels of modules.
We kept signal lines away from switching drivers. We used twisted pairs for signals' related return paths.
We designed the electronics to be modular. All other lines extended out of the perfboard, and each signal is labeled clearly for debugging and organization.
This also removed the need to check whether wires are still connected and significantly reduced the time in debugging, especially while integrating.
handling all user inputs
We selected the pins based on what's available for ADC, PWM (OC, Output Capture) and UART capability. PWM was needed to control the servo (OC4). ADC channels on RA0, RA1, and RB2 were used for two joystick analog inputs and the selection of the boat to pair the controller to, respectively. UART (specifically UART2, as UART1 was used for debugging) was used to handle communication signals to/from the XBee to communicate wirelessly with the controller.
There are various inputs:
1 potentiometer
2 buttons
1 limit switch for the "charging" pump
Joystick X
Joystick Y
XBee Data Out to PIC32 Data In
And a few outputs:
Power LED
Connection LED
Recharge LED
Servo Motor (charge, steam pressure)
PIC32 Data out to XBee Data In
Two 2D joysticks, made by Adafruit, are used in our remote controller. With the left joystick, we control the thrust and direction of the boat. The right joystick's analog input is reserved for future functionality.
The left joystick's button (internally-pulled-up) was used for pairing.
The right joystick's button (internally-pulled-up) was used for spraying with our water gun when held down.
The joystick was powered by 3.3V to match the 3.3V logic of the PIC32. The VRx and VRy outputs were treated as analog inputs and read as 10-bit values (0–1023). These values were then converted to 8-bit (0–255), with 127 representing the centered (neutral) position. This conversion was necessary because the values were sent to the boat over XBee, which required 8-bit data.
This analog input allowed us to quickly and easily choose which boat to pair with. With the ability to turn 300 degrees and there being 5 boats, boat 1 was between 0-60deg, boat 2 between 60-120, Boat 3 between 120-180, boat 4 between 180-240, and boat 5 between 240-300. An analog compatible input pin was used.
We have an internally-pulled-up single-pole double-throw limit switch with for detecting when an operator is pumping the pump to "recharge" our system in a fun-to-watch way!
A small servo motor is used to indicate the charge/fuel level of the boat. Because the servo is not going to work against any load, a small servo like SG90 suffices.
The servo motor was the only component that required a +5 V supply. It was connected with three wires: +5 V power, ground, and a PWM control signal from the PIC32. The servo was then controlled using the our PWM library.
The microcontroller, based on the charge level it receives from the boat through the radio, calculates an angle for the servo to turn to (to continuously indicate the charge level), and generates a corresponding PWM signal to drive the servo motor. The PWM signal determines the angular position of the servo motor by controlling the duty cycle of the PWM.
We had three red LEDs to minimalistically indicate to the operator the state of the controller, from left to right:
Power: The LED is on when the microcontroller receives power.
Connection: The LED is blinking at 2Hz when pairing is in progress. It is solidly on when paired with a boat. It is off otherwise.
Charging: The LED is on when a charging action has taken place, indicating that no driving/spraying/gate action will be transmitted to the boat while in this charging state.
Our LED current limiting circuits use 220Ω resistors. This circuit limits the current through the LED to a safe level when driven by the PIC32 output pin.
With the PIC32 output voltage at 3.3V and a forward voltage of about V_f = 2.0V for the red LEDS and a desired current of about I_f = 10mA, this gave us:
I_f < 10 mA
I_f = (V_OH - V_f) / R
so
R > (V_OH - V_f) / 10 mA
> (3.3 V - 2.0 V) / 10 mA
> 1.3 V / 10 mA
> 130 Ω
We chose R = 200 Ω. Confirming with resistor choice:
I_f = (V_OH - V_f) / R
= (3.3 V - 2.0 V) / 220 Ω
= 1.3 V / 220 Ω
= 5.9 mA
The microcontroller used for the project was the PIC32MX170F256B (PIC32). The microcontroller connected to the MPLAB Snap to enable the programming of the microcontroller using MPLAB X IDE, and the microcontroller was also connected to a USB to Serial device in order to monitor the serial output of the PIC for debugging purposes.
The XBee RF module is responsible for receiving wireless communication signals between the remote controller and the boat using ZigBee. The XBee transmits data to the PIC32 over UART. Using a framework defined by the communications committee, the PIC32 decodes the received packets sent to the boat.
At each IC, we included a 0.1 uF capacitor as local charge storage, providing stability at local transitions and current draws. We used monolithic ceramic capacitors because they are:
+ physically small
+ inexpensive
+ maintain the capacitance value at higher frequencies, so able to support fast responses.
Additionally, we included larger bypass capacitors at high current loads and regulators.
We kept our PIC32s in removable mounts, keeping them modular and swappable.
We kept all our electronics isolated inside a modular 3D-printed PLA outer shell.
Signals are kept away from motors and switching drivers.
To reduce the effect of electrical noise, power lines and logic-level circuits were distanced.
Appropriate lines and their associated return paths were also twisted together whenever possible to minimize electromagnetic fields.
All power lines go directly back to the small power distribution board (explained below) to avoid undesirable ground loops.
We interfaced with and used the following the small power distribution board.
The power distribution board was assembled to allow a small powerbank (Portable Charger (external 5V battery, 5mAH) to supply power to all electronics in the system.
The servos and other such loads were placed on separate power rails to prevent high current draw from interfering with the robot’s sensing circuitry.