VANT151/2026/Capstone/APSC/Team1/Coding
Coding
Overview of the Arduino Code
The Coding sub-team was responsible for the remote-control software and the software interface between the transmitter, vehicle receiver, and dashboard. The system uses three Arduino Nano boards. The first Nano is inside the handheld transmitter. The second Nano is mounted on the vehicle as the receiver. The third Nano is connected to a laptop by USB and works as a radio bridge for the dashboard.
The transmitter reads the joystick and button inputs, then sends a command packet through an nRF24L01 radio module. The receiver reads this command packet and controls the steering servo, drive motor PWM, Peltier module, fan, lights, and buzzer. The receiver also reads the cabin temperature and humidity sensor. The third Nano listens for dashboard telemetry from the receiver and sends the data to a browser dashboard on the laptop.
| File | Board | Purpose |
|---|---|---|
| TXCODE.ino | Transmitter Arduino Nano | Reads the joystick, Peltier button, buzzer button, and light button, then transmits the RC command packet. |
| RXCODE.ino | Vehicle receiver Arduino Nano | Receives RC commands, applies vehicle outputs, reads temperature and humidity, sends dashboard telemetry, and enters failsafe when signal is lost. |
| DASHBOARD_BRIDGE.ino | Third Arduino Nano connected to laptop | Receives telemetry packets and prints them as JSON through USB Serial. It also forwards safe buzzer-tone settings from the dashboard to the receiver. |
| dashboard.html | Laptop browser | Displays the live dashboard with cabin temperature, humidity, Peltier mode, fan state, lights, motor PWM, steering, failsafe, packet count, and buzzer tone. |
Requirements
Functions
The Coding sub-team design must:
- Read user inputs from the RC transmitter, including joystick movement, Peltier mode selection, buzzer input, and the extra light button.
- Send wireless command packets from the transmitter to the vehicle receiver using nRF24L01 radio modules.
- Convert valid receiver packets into vehicle outputs, including steering servo position, drive motor PWM, Peltier mode, fan state, lights, buzzer sound, dashboard telemetry, and failsafe shutdown.
Objectives
The main design objectives are:
- Make the RC control responsive and predictable so the vehicle can be tested and driven reliably.
- Make the code easy to debug and demonstrate by including Serial output, live dashboard telemetry, temperature and humidity readings, adjustable buzzer tone, and signal-loss failsafe behavior.
Constraints
The Coding design must work within these constraints:
- The transmitter and receiver must use the available Arduino Nano pins, nRF24L01 modules, joystick, buttons, switches, sensor, and output hardware.
- The software must match the Electrical, Mechanical, Structural, and Thermal sub-team designs because the code depends on the actual motor driver, steering actuator, Peltier circuit, fan wiring, light wiring, and dashboard sensor placement.
- The receiver must return to a safe state if radio communication is lost, so the motor does not continue running without a valid command signal.
The Design
System Architecture
The final coding system has three wireless roles. The transmitter sends driver commands to the receiver. The receiver controls the vehicle and sends telemetry data to the third Nano. The third Nano connects to the laptop by USB and allows the dashboard to show live data.


-
| Device | Radio role | Main data sent or received |
|---|---|---|
| Transmitter Nano | Command sender | Sends joystick X/Y, Peltier mode, buzzer command, fan command, and light command. |
| Vehicle receiver Nano | Command receiver and telemetry sender | Receives RC commands, controls outputs, reads sensors, and sends telemetry to the dashboard bridge. |
| Dashboard bridge Nano | Telemetry receiver and safe config sender | Receives vehicle telemetry and sends buzzer-tone settings from the laptop dashboard. |
Transmitter Hardware
The transmitter is a rectangular controller box with one joystick, three buttons, one power switch, and one LED to show whether the controller is on. The physical box and mounting layout are part of the controller hardware design, while the Coding sub-team is responsible for reading the inputs and sending the correct command packet.
Transmitter Layout Alternatives and Selection
The transmitter layout was selected by comparing three physical layout alternatives. The goal was to make the controller comfortable to hold, easy to understand, and safe to operate while still leaving enough space for extra features.

| Alternative | A. Compact layout | B. Mixed layout | C. Separated layout |
|---|---|---|---|
| Description | The joystick, switch, LED, and buttons are all placed on the top surface in a compact arrangement. | The joystick and switch are placed on the top surface, while the feature buttons are placed on the right side of the transmitter. | The joystick is placed in the main driving area, while the switch and feature buttons are placed in a separate control area on the top surface. |
| Advantages | Small overall layout; simple to understand; all controls are visible from the top. | The top surface is less crowded, and the feature buttons are separated from the joystick area. | Clear separation between driving control and extra features; more space around the joystick; more comfortable two-thumb operation; easier to label and understand. |
| Disadvantages | The buttons are close to the joystick, which gives less thumb clearance and increases the chance of accidental button presses during driving. It also leaves less space for future features. | Side buttons are less visible during operation and may be harder to press consistently while holding the transmitter. They may also be pressed accidentally by the user's grip. | Requires slightly more planning for the transmitter box layout. |
| Decision | Not selected. | Not selected. | Selected. |
The separated layout was chosen because it provides the best balance of comfort, clarity, and expandability. The joystick is used for the main driving control, while the extra feature buttons are placed in a separate area. This allows the user to keep one thumb on the joystick and use the other thumb for the feature buttons. As a result, the transmitter is more comfortable to hold, easier to understand, and less likely to cause accidental button presses during driving.
This layout also makes testing and demonstration easier because each control area has a clear purpose. The joystick area is used for vehicle movement, while the feature button area is used for extra functions such as the Peltier system, buzzer, and lights.
Final Transmitter Part Drawing
After comparing the layout alternatives, the separated transmitter layout was selected as the final design. The final transmitter uses a joystick for the main driving control and separates the extra feature buttons into a different control area. The part drawings below show the final physical layout of the transmitter.




Table 4 shows a summary of the transmitter inputs.
| Input | Arduino pin | Coding function |
|---|---|---|
| Joystick X-axis | A0 | Controls steering. The receiver maps this value to the steering servo pulse. |
| Joystick Y-axis | A1 | Controls drive motor speed. The receiver calibrates the center value, applies a deadzone, and maps joystick travel to PWM. |
| Button 1 | D2 | Cycles the Peltier module through OFF, COLD, HEAT, then back to OFF. |
| Button 2 | D3 | Activates the buzzer while the button is held. |
| Button 3 | D4 | Toggles the vehicle lights on and off. This was chosen as the extra button feature because it is simple, visible, and useful during the conference demonstration. |
| Power switch | Hardware power path | Turns the transmitter on and off. |
| Power LED | Power indicator circuit | Shows when the controller is powered. |
Vehicle Receiver Hardware
The receiver Arduino Nano is mounted on the vehicle and converts wireless commands into physical outputs. It controls the steering servo, motor driver, Peltier module, fan driver, lights, and buzzer. It also reads the temperature and humidity sensor inside the vehicle cabin.
| Part | Arduino pin | Purpose |
|---|---|---|
| Steering servo signal | D3 | Controls steering position using joystick X. |
| Motor PWM | D5 | Controls drive motor speed using joystick Y. |
| Peltier enable | D4 | Turns the Peltier circuit on or off. |
| Peltier mode control | D2 | Selects cold or heat mode through the Peltier relay/control circuit. |
| Fan driver | D6 | Turns the fan on when the Peltier mode is active. |
| Lights | D7 | Turns the vehicle lights on or off using transmitter Button 3. |
| Buzzer | D8 | Plays a tone while the buzzer button is held. The tone frequency can be adjusted from the dashboard. |
| DHT temperature/humidity sensor | A0 | Measures cabin temperature and humidity for the dashboard. |
Dashboard Bridge and Landing Page
The dashboard feature uses a third Arduino Nano connected to the laptop by USB. This avoids needing an ESP32 or Bluetooth module. The third Nano has its own nRF24L01 radio and receives telemetry packets from the vehicle receiver. It then prints the data to the laptop as JSON through USB Serial. A browser dashboard reads this serial data and displays it as a live landing page.
The dashboard is not a public internet website. It is a local landing page opened on the laptop during testing or the conference. It can show live data in a browser while still keeping the RC transmitter responsible for vehicle movement.


| Dashboard value | Source | Reason for including it |
|---|---|---|
| Cabin temperature | DHT sensor on receiver | Shows whether the Peltier/fan system changes the rider area temperature. |
| Cabin humidity | DHT sensor on receiver | Adds more environmental data for the cabin. |
| Peltier mode | Receiver telemetry | Shows if the system is OFF, COLD, or HEAT. |
| Fan state | Receiver telemetry | Shows if fan output is active with the Peltier system. |
| Lights state | Transmitter Button 3 and receiver telemetry | Shows the extra button feature. |
| Motor PWM | Receiver telemetry | Shows the current motor command. |
| Steering pulse | Receiver telemetry | Shows the current steering servo command. |
| Failsafe status | Receiver timeout logic | Shows whether the vehicle has entered safe-stop mode. |
| Signal age and packet count | Receiver telemetry | Helps debug radio communication. |
| Buzzer tone | Dashboard setting and receiver telemetry | Allows the buzzer sound to be adjusted safely without affecting steering or motor control. |
Command and Telemetry Packets
The transmitter and receiver use the same command packet structure so both Arduinos interpret the radio message correctly.
| Field | Meaning |
|---|---|
| x | Joystick X value for steering. |
| y | Joystick Y value for motor speed. |
| peltierMode | 0 = OFF, 1 = COLD, 2 = HEAT. |
| buzzerActive | 1 when the buzzer button is held, otherwise 0. |
| fanActive | 1 when the Peltier mode is active, otherwise 0. |
| lightsActive | 1 when the lights are on, otherwise 0. |
The receiver sends a second packet type to the dashboard bridge. This packet includes the sensor values and the current output state of the vehicle.
| Field | Meaning |
|---|---|
| temperatureC | Cabin temperature in degrees Celsius. |
| humidity | Cabin relative humidity. |
| peltierMode | Current Peltier mode applied by the receiver. |
| fanActive | Current fan command. |
| lightsActive | Current light command. |
| motorPWM | Motor PWM value from 0 to 255. |
| servoPulse | Steering servo pulse in microseconds. |
| failsafe | Shows whether signal-loss failsafe is active. |
| signalAgeMs | Time since the receiver last received a valid command packet. |
| packetCount | Number of command packets received by the receiver. |
| buzzerToneHz | Current buzzer tone frequency. |
Operating Sequence
- The user turns on the transmitter using the power switch. The power LED turns on.
- The transmitter initializes the joystick, buttons, Serial output, and nRF24L01 radio module.
- The transmitter repeatedly reads the joystick and buttons.
- If Button 1 is pressed, the transmitter cycles the Peltier mode through OFF, COLD, HEAT, and OFF again.
- If Button 2 is held, the transmitter sends the buzzer-active command.
- If Button 3 is pressed, the transmitter toggles the light command.
- The transmitter sends a command packet to the receiver about every 50 ms.
- The receiver reads valid command packets and updates the last-received time.
- The receiver maps joystick X to the steering servo and joystick Y to motor PWM after joystick center calibration.
- The receiver applies Peltier, fan, light, and buzzer outputs.
- The receiver reads the DHT temperature/humidity sensor approximately every 2 seconds.
- The receiver sends a telemetry packet to the third Nano about every 250 ms.
- The third Nano sends the telemetry data to the laptop dashboard as JSON over USB.
- The dashboard displays live values and can send a safe buzzer-tone setting back to the receiver.
- If the receiver does not receive a command packet for more than 1000 ms, it enters failsafe by centering steering, stopping the motor, turning off the Peltier, turning off the fan, turning off the buzzer, and turning off the lights.
Program Flowchart
The program flowchart should be uploaded as an image in this section. Mermaid is useful for generating the diagram, but UBC Wiki may not render Mermaid directly. The recommended method is to render the Mermaid flowchart as a PNG or SVG, upload it to UBC Wiki, and place it below as Figure 7.

Extra Features
The extra feature selected for the third transmitter button is vehicle lights. This was chosen because lights are easy to test, easy to show visually, and listed as a common extra feature for the project. The light output is controlled from transmitter Button 3 and displayed on the dashboard.
The second extra feature is the laptop dashboard. Instead of adding an ESP32 or Bluetooth module, the design uses a third Arduino Nano as a USB radio bridge. This allows the team to show live vehicle data on a browser page while using the same nRF24L01 radio system already used for RC communication.
| Extra feature | Description | Status |
|---|---|---|
| Vehicle lights | Button 3 on the transmitter toggles a light output on the vehicle receiver. | Implemented in code; needs final light wiring. |
| Live dashboard | A browser dashboard displays temperature, humidity, Peltier mode, fan, lights, motor PWM, steering, failsafe, packet count, and buzzer tone. | Implemented as local laptop dashboard using a third Arduino Nano bridge. |
| Adjustable buzzer tone | The dashboard can send a safe buzzer-tone frequency to the receiver. | Implemented in code; works best with a passive buzzer. |
| Temperature and humidity sensing | A DHT sensor measures cabin environment data near the rider/mannequin. | Implemented in code; sensor must be mounted and wired. |
Other possible uses for the extra transmitter button were considered, such as a horn toggle, dashboard marker, manual fan override, or joystick recalibration button. Lights were selected because they have the best balance of simplicity, safety, and demonstration value.
Current Testing Status
At the current stage, the code supports radio command packets, joystick control, Peltier mode cycling, fan command, light toggle, buzzer command, DHT temperature and humidity readings, dashboard telemetry, adjustable buzzer tone, and signal-loss failsafe. Final testing should confirm that the radio modules remain stable when all three Nanos are powered, that the receiver enters failsafe correctly, and that the dashboard updates reliably while the vehicle is running.
| Test | Expected result |
|---|---|
| Transmitter joystick test | Dashboard and receiver Serial output show changing X/Y values. |
| Peltier button test | Mode cycles through OFF, COLD, HEAT, and OFF. |
| Buzzer button test | Buzzer plays only while the button is held. |
| Light button test | Vehicle lights toggle on and off. |
| DHT sensor test | Dashboard displays cabin temperature and humidity. |
| Dashboard bridge test | Browser dashboard receives live telemetry from the third Nano. |
| Failsafe test | Turning off the transmitter causes the receiver to stop the motor and turn off unsafe outputs. |
Recommendations
- Use a 10 uF to 47 uF capacitor across the VCC and GND pins of each nRF24L01 module to reduce radio power problems.
- Keep the nRF24L01 wires short and power the module from 3.3 V only.
- Test the DHT sensor before final mounting because incorrect sensor type selection can cause blank temperature and humidity readings.
- Use a passive buzzer if adjustable tones are needed, because active buzzers may ignore frequency changes.
- Keep the dashboard control limited to safe accessory settings, such as buzzer tone. Driving and steering should remain controlled by the transmitter.