Building a Multi-Device RC Controller with ESP-NOW

Prerequisites: This is part of our IoT Firmware series. If you’re new to ESP32 development, make sure to check out our first blog post in the series where we cover the basics of ESP32 programming and MicroPython setup. Basic soldering skills will be helpful for this project, especially when connecting the joysticks and buttons to the ESP32-C6 board.

⚡ Check out the project repository for the complete source code, detailed setup instructions, and to contribute to the project! Feel free to star the repo if you find it helpful. 🌟

Ever wanted to control multiple devices wirelessly with a single controller? In this project, we’ll explore how to build a powerful RC controller using the ESP32-C6 microcontroller and ESP-NOW protocol. This isn’t just another RC project - it’s a versatile system that can control up to three different devices simultaneously, perfect for robotics, drones, or any IoT project that needs wireless control.

Why ESP-NOW?

ESP-NOW is a powerful wireless communication protocol developed by Espressif Systems. It offers several advantages over traditional wireless protocols:

  • Low Latency: Perfect for real-time control applications
  • Long Range: Up to 200 meters in open space
  • Simple Implementation: No need for complex network setup
  • Low Power Consumption: Ideal for battery-powered projects
  • Peer-to-Peer Communication: Direct device-to-device communication without a router

Hardware Components

Here’s what you’ll need to build this project:

ComponentQuantityPurposeNotes
ESP32-C61Main microcontrollerLatest ESP32 variant with improved wireless capabilities
Analog Joysticks2Dual-axis control10K potentiometer type recommended
Push Buttons4Additional controlsTactile switches with pull-up/down resistors
NeoPixel LED1Visual feedbackWS2812B compatible
Power Supply1Battery or USB power3.3V regulated power supply

I recommend using a board with integrated WS2812B LEDs, such as the ESP boards from Waveshare.

Pin Configuration

Here’s the detailed pin mapping for connecting all components:

ComponentPinFunctionConfiguration
Joystick 1 X-AxisGPIO 2Left/Right controlADC, 11DB attenuation
Joystick 1 Y-AxisGPIO 3Up/Down controlADC, 11DB attenuation
Joystick 2 X-AxisGPIO 0Secondary X controlADC, 11DB attenuation
Joystick 2 Y-AxisGPIO 1Secondary Y controlADC, 11DB attenuation
Joystick 1 ButtonGPIO 4Joystick 1 pressPull-up input
Joystick 2 ButtonGPIO 5Joystick 2 pressPull-up input
Device SwitchGPIO 15Device selectionPull-down input
Button 2GPIO 21Additional controlPull-down input
Button 3GPIO 22Additional controlPull-down input
Button 4GPIO 19Additional controlPull-down input
NeoPixel LEDGPIO 8Status indicatorDigital output

Software Architecture

The controller uses a simple but effective architecture:

  1. Initialization

    • ESP-NOW setup
    • ADC configuration
    • GPIO pin setup
    • NeoPixel initialization
  2. Main Loop

    • Device selection handling
    • Input reading
    • Data packaging
    • Wireless transmission

Data Communication

The controller sends data in a structured JSON format every 70ms (configurable):

{
    "Joystick1-X": value,    // 0-4095 (12-bit ADC)
    "Joystick1-Y": value,    // 0-4095 (12-bit ADC)
    "Joystick2-X": value,    // 0-4095 (12-bit ADC)
    "Joystick2-Y": value,    // 0-4095 (12-bit ADC)
    "Joystick1-Button": value,  // 0 or 1
    "Joystick2-Button": value,  // 0 or 1
    "Button1": value,        // 0 or 1
    "Button2": value,        // 0 or 1
    "Button3": value,        // 0 or 1
    "Button4": value,        // 0 or 1
    "Device": active_device_index  // 0, 1, or 2
}

Visual Feedback System

The NeoPixel LED provides intuitive feedback for device selection:

  • 🟢 Green (10,0,0): Device 1 selected
  • 🔴 Red (0,10,0): Device 2 selected
  • 🔵 Blue (0,0,10): Device 3 selected

Common Challenges and Solutions

1. Connection Issues

If you’re experiencing connection problems:

  • Verify MAC addresses are correctly configured in device_macs list
  • Ensure devices are within range (up to 200m in open space)
  • Check power supply stability (3.3V required)
  • Verify ESP-NOW initialization sequence

2. Joystick Calibration

For optimal joystick performance:

  • Use proper ADC attenuation settings (11DB for full 3.3V range)
  • Implement deadzone handling (center point ±5%)
  • Calibrate center points on startup
  • Use 12-bit ADC resolution (0-4095 range)

3. Power Management

To ensure stable operation:

  • Use a stable 3.3V power supply
  • Add 100μF decoupling capacitors near power pins
  • Consider separate power for NeoPixels (5V)
  • Monitor power consumption (ESP32-C6 can draw up to 500mA)

Getting Started

  1. Hardware Setup

    • Connect components according to the pin configuration
    • Ensure proper power supply
    • Add decoupling capacitors
    • Test continuity of all connections
  2. Software Setup

    • Flash MicroPython to ESP32-C6
    • Upload the controller code
    • Configure target device MAC addresses
    • Test basic functionality
  3. Testing

    • Power on the controller
    • Test each input
    • Verify LED feedback
    • Check wireless communication
    • Monitor serial output for debugging

Future Enhancements

The project can be extended in several ways:

  • Add more control channels
  • Implement battery monitoring
  • Create a custom enclosure
  • Add OLED display for status
  • Implement failsafe mechanisms
  • Add OTA updates
  • Implement power saving modes

Conclusion

This ESP-NOW RC controller project demonstrates the power and flexibility of ESP32 microcontrollers in wireless control applications. Whether you’re building a robot, drone, or any other IoT project, this controller provides a solid foundation for wireless control systems.

The combination of ESP-NOW protocol, MicroPython, and the ESP32-C6’s capabilities makes this project both powerful and accessible to makers of all skill levels.

Check Out the Project

Want to build this project yourself? Head over to our GitHub repository where you’ll find:

  • Complete source code
  • Detailed wiring diagrams
  • Troubleshooting guide
  • Example receiver code
  • Community support

Happy building! 🚀