Category: Uncategorized

  • First PCB Update: Firmware

    Bringing the Robotics Controller to Life, Firmware and Software

    In a previous post, I focused on the hardware side of my custom ESP32 S3 robotics controller PCB, including the board layout, grounding strategy, power distribution, and the decisions that went into turning a prototype wiring setup into a real four layer design. That hardware was a huge milestone for me, but a robotics controller is only half finished until the firmware gives it behavior, structure, and a usable interface. The software side is what turns the board from a collection of connected parts into an actual development platform.

    For this stage of the project, I focused on building firmware that was modular, scalable, and practical to work with during development. I did not want a single giant source file with everything packed into one place. Instead, I organized the project into separate modules for motors, servos, ultrasonic sensors, hall sensors, the IMU, buttons, the display, the user interface, robot modes, games, and wireless communication. That structure makes the code easier to understand, easier to test, and much easier to expand later as the board evolves. The firmware is coordinated from a main entry point, while pin assignments and tunable settings are centralized in a config file so the system can be adapted to future hardware revisions without rewriting the whole project.

    One of the biggest goals of this firmware was to make the board useful as both a robotics controller and a self contained demo platform. On the motion control side, the ESP32 S3 uses hardware timed PWM through the LEDC peripheral to drive two DRV8871 motor channels at 20 kHz with 8 bit resolution. That keeps motor control responsive while also pushing the PWM frequency above the normal audible range. The board also supports a standard servo output on GPIO 8, while GPIO 9 is currently repurposed as the potentiometer input for menu navigation and analog controls inside the user interface.

    Sensor support was another major part of the firmware. The board reads four ultrasonic sensors for distance sensing, two hall effect inputs for pulse counting and speed feedback, and an I2C IMU for motion data. In other words, the software is built to support both movement and awareness. That makes the board useful not just for driving motors, but for experimenting with autonomous behavior, closed loop feedback, and navigation concepts.

    I also wanted the board to be easy to interact with without always needing to reflash code or hook up a separate interface. To solve that, I added several layers of user interaction. The first is an onboard TFT display driven over SPI using TFT_eSPI. The current firmware uses a tabbed menu system that runs directly on the display and is controlled with two buttons plus a potentiometer. Through that interface I can view live sensor data, open demos, launch robot modes, scan WiFi networks, look for nearby BLE devices, and navigate through test features without needing an external computer.

    The software also includes a built in wireless dashboard. On boot, the controller creates its own WiFi access point called RoboController and hosts a browser based dashboard at 192.168.4.1. That dashboard includes live sensor data, a WiFi scanner, a BLE radar view, and a control tab for remote operation. Instead of relying on constant polling, the interface pushes live data over WebSocket, which makes it feel much more responsive and interactive. On the control side, the dashboard can send JSON commands for motor drive, servo position, and emergency stop functions. That means the board is not limited to local buttons and a small screen, it can also act like a wireless robotics control node that is easy to test from a phone or laptop.

    BLE support was another area I wanted to build in early. The firmware advertises a custom BLE GATT service that exposes sensor data and accepts motor and servo control writes. That opens the door for mobile apps, sensor streaming, and remote control through BLE tools like nRF Connect. Having both WiFi and BLE built into the same board gives the platform a lot of flexibility, especially for future robotics projects where different communication methods may make sense in different situations.

    One of the most fun parts of this project is that I did not stop at just utility features. I also added a more polished on device experience with multiple demos and even simple games running on the TFT. The firmware includes menu driven screens for live system information, sensor displays, tilt visualization, ultrasonic radar, servo control, and robot mode selection. On top of that, there are games like Snake, Pong, and Asteroids, all rendered through an off screen framebuffer for smooth updates. Those features are obviously not the core purpose of a robotics controller, but they turned out to be a great way to test the display, inputs, UI state machine, timing, and overall firmware structure while making the board much more interesting to interact with.

    From a development standpoint, I built the project around PlatformIO, which makes library management and builds much easier to handle. The firmware pulls in libraries like ESP32Servo, TFT_eSPI, AsyncTCP, ESPAsyncWebServer, and NimBLE Arduino. Using a structured toolchain like this makes the project more portable and easier to maintain than an ad hoc sketch with manual dependency management.

    What I like most about this phase of the project is that it shows the board is more than just a PCB layout exercise. The hardware and software were designed to work together as a reusable robotics platform. The board can drive motors, read sensors, host a display UI, create its own wireless dashboard, expose BLE services, and support future expansion through broken out GPIO. That combination is what really makes it feel like a complete system rather than just another microcontroller board. The hardware post was about building the foundation. This firmware phase is about giving that foundation behavior.

    There is still plenty I want to improve. I want to keep refining the robot modes, continue testing the wireless control features, and push the platform further as both a practical robotics controller and a polished demonstration board. Even so, getting this firmware architecture working has already been a huge step forward. It taught me a lot about structuring embedded software, building usable interfaces on constrained hardware, and designing systems that are easier to grow over time.

    This project started as a custom board to clean up wiring and consolidate hardware. Now it is becoming a full robotics platform, with hardware, firmware, wireless control, and a user interface all designed to work together.

  • First Custom PCB Project

    ESP32-S3 Robotics Controller Hub

    One of the biggest milestones in my recent work has been designing my first fully custom PCB: a 4-layer, ESP32-S3 based robotics controller hub. This board was built to consolidate the many separate modules, wiring harnesses, and prototype systems I had been using into a single, clean, and scalable platform for robotics development.

    Design Overview

    At the core of the system is the ESP32-S3, chosen for its processing capability, flexible GPIO matrix, integrated WiFi and Bluetooth, and strong support for real-time control tasks. Around it, I designed a complete control and sensing ecosystem intended for mobile robotics applications.

    The board integrates:

    • Dual DRV8871 motor drivers for bidirectional DC motor control
    • Support for two servo outputs with PWM control
    • Four ultrasonic sensor interfaces for environmental awareness
    • Two hall effect sensor inputs for feedback such as wheel speed or position tracking
    • A SPI-connected display for onboard telemetry, debugging, and UI
    • Onboard linear regulation and power distribution
    • Expansion headers for unused GPIO to support future features

    The goal was not just to “make it work,” but to build something robust, reusable, and electrically sound.


    Moving from Wiring to PCB Design

    Prior to this board, most of my systems were built using breadboards or modular components. While flexible, those setups quickly became unreliable and difficult to maintain, especially when dealing with motors and multiple sensors. This project was my transition into designing a dedicated hardware platform.

    The schematic design phase was relatively straightforward. The real learning curve came during PCB layout.


    4-Layer Stackup and Grounding Strategy

    This board uses a 4-layer stackup, which allowed for a much more controlled and professional layout compared to a 2-layer design. The layers were organized as:

    • Top Layer: signal routing and high-current paths
    • Inner Layer 1: solid ground plane
    • Inner Layer 2: power distribution (VM and regulated rails)
    • Bottom Layer: additional signal routing and localized pours

    A continuous ground plane was one of the most important design decisions. Instead of routing ground as traces, I used large copper pours and stitching vias to create a low-impedance return path across the entire board. This significantly improves noise performance and reduces the likelihood of instability, especially with switching motor loads.

    PCB Front View

    High-Current Design Considerations

    Driving motors introduces large and rapidly changing currents, which can easily create voltage drops, EMI, and system instability if not handled properly.

    To address this:

    • High-current paths were routed using wide copper traces and local pours
    • Motor driver ground connections were reinforced with multiple stitching vias into the ground plane
    • VM (motor supply voltage) was kept as a controlled, localized copper region rather than a full-plane pour
    • Return paths were kept as short and direct as possible to minimize loop area

    One key concept I learned was that current does not just follow the forward path, it follows a loop. Designing tight, low-impedance loops between VM and GND was critical for stable operation.


    Decoupling and Noise Reduction

    Decoupling capacitors were placed strategically throughout the board, particularly:

    • Close to the ESP32-S3 power pins
    • Adjacent to each motor driver
    • Between VM and ground near high-current switching areas

    Both bulk capacitors and small ceramic capacitors were used to handle different frequency ranges of noise. Placement was just as important as value. Keeping these components physically close to the devices they support dramatically improves effectiveness.


    Signal Integrity and Peripheral Integration

    With a mix of analog-like signals (ultrasonic sensors), digital inputs (hall sensors, buttons), PWM outputs (servos), and high-speed communication (SPI display, I2C IMU), careful routing was required.

    Key considerations included:

    • Keeping noisy motor and power traces away from sensitive sensor lines
    • Using short, direct routes for SPI signals to the display
    • Maintaining clean pull-up configurations for I2C communication
    • Ensuring proper voltage compatibility, particularly for ultrasonic sensor echo lines

    Expandability and Practical Design

    A portion of the design was dedicated to future-proofing. Unused GPIO pins were broken out into a dedicated header along with power and ground, allowing additional modules or features to be added without redesigning the board.

    This was a deliberate choice to make the board not just a one-off project, but a reusable platform.


    What I Learned

    This project reinforced that PCB design is not just about making electrical connections, it is about managing current flow, noise, and physical layout in a way that supports reliable operation.

    Some of the biggest takeaways:

    • Grounding strategy is critical and should be planned early
    • High-current paths must be treated differently than signal traces
    • Component placement often matters more than routing
    • Decoupling and return paths directly affect system stability
    • Planning for expansion saves time in future iterations

    Looking Forward

    This board represents a major step forward in both my electronics design and system integration skills. It replaces a complex, error-prone wiring setup with a compact, reliable controller that can serve as the foundation for future robotics projects.

    The next phase will involve assembling, testing, and iterating on the design. I expect there will be improvements to make, but that is part of the process.

    Designing this board has been one of the most rewarding technical challenges I’ve taken on so far, and it sets the stage for more advanced and refined hardware in the future!

    How to Use the Robotics Controller

    This controller is designed to act as a central hub for motor control, sensing, and user interaction. The system is built around the ESP32-S3 and uses a mix of PWM, digital I/O, I2C, and SPI peripherals.

    GPIO Pin Reference

    GPIO | Function
    1 | Hall Sensor 1
    2 | Hall Sensor 2
    4 | Motor 1 PWM A
    5 | Motor 1 PWM B
    6 | Motor 2 PWM A
    7 | Motor 2 PWM B
    8 | Servo 1
    9 | Servo 2
    10 | Ultrasonic 1 TRIG
    11 | Ultrasonic 1 ECHO
    12 | Ultrasonic 2 TRIG
    13 | Ultrasonic 2 ECHO
    14 | Ultrasonic 3 TRIG
    15 | Ultrasonic 3 ECHO
    16 | Ultrasonic 4 TRIG
    17 | Ultrasonic 4 ECHO
    18 | I2C SDA (IMU)
    21 | I2C SCL (IMU)
    33 | SPI MOSI (Display SDA)
    34 | SPI SCLK (Display SCL)
    35 | SPI CS
    36 | SPI DC
    39 | SPI RES
    41 | Button 1
    42 | Button 2
    47 | Button 3

    Additional GPIO (37, 38, 40, 43, 44, 48) are exposed via header for expansion.

    Motor Control (DRV8871)

    Motor 1: GPIO 4 (PWM A), GPIO 5 (PWM B)
    Motor 2: GPIO 6 (PWM A), GPIO 7 (PWM B)

    Control:

    • PWM A high, PWM B low → forward
    • PWM A low, PWM B high → reverse
    • Both low → coast
    • Both high → brake

    Servo Outputs

    Servo 1 → GPIO 8
    Servo 2 → GPIO 9

    Standard 50 Hz PWM:

    • ~1.0 ms pulse → 0°
    • ~1.5 ms → center
    • ~2.0 ms → 180°

    Ultrasonic Sensors

    TRIG pins: GPIO 10, 12, 14, 16
    ECHO pins: GPIO 11, 13, 15, 17

    Operation:

    1. Send 10 µs pulse on TRIG
    2. Measure pulse width on ECHO
    3. Convert to distance

    Hall Effect Sensors

    Hall 1 → GPIO 1
    Hall 2 → GPIO 2

    Used for:

    • Speed measurement
    • Rotation counting
    • Position feedback

    IMU (I2C)

    SDA → GPIO 18
    SCL → GPIO 21

    SPI Display

    MOSI (SDA) → GPIO 33
    SCLK (SCL) → GPIO 34
    CS → GPIO 35
    DC → GPIO 36
    RES → GPIO 39

    Push Buttons

    Button 1 → GPIO 41
    Button 2 → GPIO 42
    Button 3 → GPIO 47

    Use:
    pinMode(pin, INPUT_PULLUP);

    Expansion Header

    Available GPIO:
    37, 38, 40, 43, 44, 48

    Firmware Template

    https://github.com/averyizatt/ESP32BasedRobiticsPCB

  • Project Update: Building, Leading, and Getting Things Running

    The past few months have been a mix of technical work, leadership, and finally getting some long-term projects across the finish line. A lot of what I’ve been doing has shifted from just building individual components to managing systems, teams, and real-world constraints.

    IEEE Club & COSGC Rover

    Alongside technical work, I’ve been managing the IEEE club, organizing meetings, planning workshops, and coordinating trips and outreach events. Balancing that with engineering work has been a challenge, but it’s also been a great way to build experience beyond just the technical side.

    At the same time, I’ve continued working on the COSGC rover project. After simplifying the drivetrain to a skid-steer design, I’ve been focusing on making the system more reliable and practical. A big part of that has been designing a self-righting mechanism, which turned into a deeper dive into torque, leverage, and mechanical advantage than I initially expected.

    What started as a simple idea quickly became an exercise in real engineering tradeoffs. Longer arms gave more reach but not enough force, while shorter arms had the opposite problem. That pushed me toward rethinking the geometry and exploring better ways to apply force rather than just increasing power.

    Electronics, Power, and Control

    On the electronics side, I’ve been refining control systems using Arduino-based setups and working through proper power distribution. Running a 24V system with buck converters for logic and peripherals has been a big part of this, along with learning how important things like decoupling and bulk capacitance are when motors and servos are involved.

    I’ve also been experimenting with using current sensing to estimate load on actuators. It’s a simple concept, but it adds a layer of awareness to the system that opens up better control and protection strategies.

    Sensors & Real-World Testing

    Another focus has been testing sensors in less-than-ideal environments. Comparing ultrasonic and optical distance sensing highlighted how much conditions like sunlight and uneven terrain can affect performance.

    It’s been a good reminder that designs need to work outside of controlled environments, especially for a rover that’s expected to operate on varied surfaces.

    Mustang Project

    Outside of robotics, I’ve been putting in a lot of work on my 1989 Mustang. After a long process of rebuilding and tuning, the car is now fully running and driving under a self-tuned ECU setup.

    Getting it to this point involved dialing in fuel, ignition, and overall system behavior, and it’s been one of the most rewarding parts of the past few months to see it finally come together and operate the way it should.

    What I’ve Been Learning

    Across all of these projects, the biggest takeaway has been that good engineering isn’t about forcing things to work, it’s about designing them so they work naturally.

    Whether it’s managing torque through better geometry stabilizing electronics with proper power design or balancing technical work with leadership responsibilities, the focus has been on building systems that are reliable, not just functional.