A modular robot control system built with Arduino framework and PlatformIO for autonomous navigation and task execution across multiple stations.
This project provides a software control hub for a mobile robot platform designed to execute various station-based tasks. The architecture emphasizes clean separation of concerns, software-driven configuration, and deterministic behavior execution.
- Microcontroller: Arduino UNO R4 Minima
- Motor Driver: L298N dual H-bridge motor controller
- Sensors:
- Ultrasonic distance sensor (HC-SR04 or compatible)
- Color sensor (optional, library included)
- Actuators:
- Servo motor
- DC motors for drivetrain
- EN_A: Pin 9
- IN1_A: Pin 2
- IN2_A: Pin 3
- EN_B: Pin 10
- IN1_B: Pin 4
- IN2_B: Pin 5
- Ultrasonic TRIG: Pin 11
- Ultrasonic ECHO: Pin 12
UTRA-main/
├── src/
│ ├── main.cpp # Main program dispatcher
│ ├── movements.cpp/h # Robot movement control
│ ├── robot_mode.h # Mode enumeration
│ ├── ultrasonic.h # Ultrasonic sensor wrapper
│ ├── StationA/ # Station A task logic
│ ├── StationB/ # Station B task logic
│ ├── StationC/ # Station C task logic
│ └── StationTest/ # Testing routines
├── lib/ # Custom color sensor library
├── include/
│ └── constants.hpp # Hardware pin definitions
└── platformio.ini # Build configuration
The following libraries are automatically managed by PlatformIO:
L298N(v2.0.3) - Motor driver controlServo(v1.1.8) - Servo motor controlNewPing(v1.9.7) - Ultrasonic sensor interface
- PlatformIO installed (via VSCode extension or CLI)
pio runpio run --target uploadpio device monitorTo change which station the robot executes:
- Open
src/main.cpp - Modify the
START_MODEconstant:constexpr RobotMode START_MODE = RobotMode::STATION_A; - Available modes:
RobotMode::STATION_ARobotMode::STATION_BRobotMode::STATION_CRobotMode::TESTRobotMode::IDLE
- Re-upload the code to the robot
No other code changes are required.
Each station has its own subdirectory with implementation and header files:
// Example: StationA/Station_A.h
#pragma once
void runStationA();
// Example: StationA/station_A.cpp
#include "Station_A.h"
#include "movements.h"
void runStationA() {
moveForward(1000);
turnLeft(500);
// Add your station logic here
}void moveForward(int duration); // Drive forward (ms)
void turnLeft(int duration); // Rotate left (ms)
void turnRight(int duration); // Rotate right (ms)
void raiseArm(); // Raise servo arm
void lowerArm(); // Lower servo arm
int checkDistance(); // Get ultrasonic reading (cm)- Software-Driven Configuration: Change behavior by modifying a single constant
- Modular Architecture: Each station is self-contained and isolated
- Deterministic Execution: All logic runs once in
setup(), not inloop() - Clean Separation: Hardware pins centralized in
constants.hpp
- Create a new directory:
src/StationD/ - Add header file:
Station_D.hwith function declaration - Add implementation:
station_D.cppwith logic - Add enum value to
robot_mode.h:STATION_D - Update switch statement in
main.cpp
The robot waits 2 seconds after setup() begins, allowing time for:
- Serial connection establishment
- Physical placement and preparation
Monitor serial output at 115200 baud for debugging information.
This project is a winning submission of the UTRA (University of Toronto Robotics Association) 2026 hackathon.