Firmware

Firmware Getting Started

Get started programming your Moto32 with ESP32 firmware.

Firmware Getting Started

Learn how to program your Moto32 control unit with ESP32-S3 firmware using Arduino IDE or PlatformIO.

Overview

The Moto32 firmware runs on the ESP32-S3 microcontroller and controls all input/output functions. You can:

  • Upload test firmware to verify hardware
  • Customize GPIO pin assignments
  • Implement custom logic (turn signals, auto-cancel, etc.)
  • Add Bluetooth or Wi-Fi features
  • Integrate sensors and expansion modules

Prerequisites

Hardware Requirements

  • Assembled Moto32 PCB with all components
  • USB-C cable (data capable, not charge-only)
  • Computer (Windows, Mac, or Linux)

Software Requirements

Choose ONE development environment:

Arduino IDE

Beginner-friendly

  • Easy to learn
  • Large community
  • Extensive libraries
  • Good for simple projects

PlatformIO

Professional tool

  • VS Code integration
  • Better project management
  • Faster compile times
  • Advanced debugging

Setup: Arduino IDE

Step 1: Install Arduino IDE

  1. Download from arduino.cc/en/software
  2. Install version 2.0 or newer (recommended)
  3. Open Arduino IDE

Step 2: Add ESP32 Board Support

  1. Go to File → Preferences
  2. Find "Additional Board Manager URLs"
  3. Add this URL:
    https://espressif.github.io/arduino-esp32/package_esp32_index.json
    
  4. Click OK
  5. Go to Tools → Board → Boards Manager
  6. Search for "esp32"
  7. Install "ESP32 by Espressif Systems" (version 2.0.0 or newer)
  8. Wait for installation to complete
Version Note: ESP32-S3 requires ESP32 Arduino core version 2.0.0 or later. Older versions will not work.

Step 3: Select Board

  1. Connect Moto32 to computer via USB-C
  2. Go to Tools → Board → esp32
  3. Select "ESP32S3 Dev Module"
  4. Configure board settings:
SettingValueNotes
USB CDC On BootEnabledRequired for serial communication
USB ModeHardware CDC and JTAGDefault
Flash Size8MBMatch your module
PSRAMOPI PSRAMIf you have PSRAM (N8R2)
Partition SchemeDefault 4MB with spiffsOr choose based on needs
Upload Speed921600Faster uploads

Step 4: Select Port

  1. Go to Tools → Port
  2. Select the port showing your ESP32:
    • Windows: COM3, COM4, etc.
    • Mac: /dev/cu.usbserial-* or /dev/cu.wchusbserial*
    • Linux: /dev/ttyUSB0 or /dev/ttyACM0
Driver Issues? If the port doesn't appear, you may need to install CH340 drivers. Download from WCH website (Windows) or search for "CH340 driver" for your OS.

Step 5: Test Upload

Upload a simple test program:

  1. Go to File → Examples → Basics → Blink
  2. Modify the LED pin to GPIO2 (or any GPIO you can connect an LED to)
  3. Click Upload button (→)
  4. Wait for "Connecting..." message
  5. If it sticks on "Connecting...", hold the BOOT button on Moto32 (GPIO0 to GND)
  6. Upload should complete successfully
  7. Open Serial Monitor (Tools → Serial Monitor, set to 115200 baud)
  8. You should see ESP32 boot messages

Success! You can now program your Moto32.

Setup: PlatformIO

Step 1: Install VS Code

  1. Download Visual Studio Code
  2. Install for your operating system
  3. Launch VS Code

Step 2: Install PlatformIO Extension

  1. Click Extensions icon (sidebar)
  2. Search for "PlatformIO IDE"
  3. Click Install
  4. Wait for installation (may take several minutes)
  5. Reload VS Code when prompted

Step 3: Create New Project

  1. Click PlatformIO icon (sidebar)
  2. Click "New Project"
  3. Configure project:
    • Name: moto32-firmware
    • Board: Search "ESP32-S3-DevKitC-1" or "ESP32S3 Dev Module"
    • Framework: Arduino
  4. Click Finish
  5. Wait for project to initialize

Step 4: Configure platformio.ini

Edit platformio.ini file:

[env:esp32-s3-devkitc-1]
platform = espressif32
board = esp32-s3-devkitc-1
framework = arduino

; Serial Monitor Settings
monitor_speed = 115200
monitor_filters = esp32_exception_decoder

; Upload Settings
upload_speed = 921600
upload_port = /dev/cu.usbserial*  ; Change to your port

; Build flags for ESP32-S3-WROOM-1
board_build.flash_mode = dio
board_build.f_cpu = 240000000L
board_build.f_flash = 80000000L
board_build.partitions = default.csv

; Optional: Enable PSRAM
board_build.arduino.memory_type = qio_opi_psram
Port Configuration: Change upload_port to match your system. Remove this line to auto-detect.

Step 5: Test Upload

  1. Create src/main.cpp:
#include <Arduino.h>

void setup() {
  Serial.begin(115200);
  pinMode(2, OUTPUT);  // Built-in LED or test LED
  Serial.println("Moto32 Test");
}

void loop() {
  digitalWrite(2, HIGH);
  Serial.println("LED ON");
  delay(1000);
  
  digitalWrite(2, LOW);
  Serial.println("LED OFF");
  delay(1000);
}
  1. Click Upload button (→ arrow) in bottom toolbar
  2. Wait for compile and upload
  3. Click Serial Monitor button to view output

Success! PlatformIO is configured for Moto32 development.

Basic Firmware Structure

Minimal Moto32 Program

#include <Arduino.h>

// GPIO Pin Definitions
#define OUT1_PIN 1   // Output 1 - Headlight High
#define OUT2_PIN 2   // Output 2 - Headlight Low
#define OUT3_PIN 3   // Output 3 - Tail Light
#define OUT4_PIN 4   // Output 4 - Brake Light
#define OUT5_PIN 5   // Output 5 - Turn Signal Left
#define OUT6_PIN 6   // Output 6 - Turn Signal Right
#define OUT7_PIN 7   // Output 7 - Horn
#define OUT8_PIN 8   // Output 8 - Ignition

#define INPUT1_PIN 9  // Input 1 - Brake Switch
#define INPUT2_PIN 10 // Input 2 - Horn Button
// etc...

void setup() {
  // Initialize Serial
  Serial.begin(115200);
  Serial.println("Moto32 Initializing...");
  
  // Configure Outputs
  pinMode(OUT1_PIN, OUTPUT);
  pinMode(OUT2_PIN, OUTPUT);
  pinMode(OUT3_PIN, OUTPUT);
  pinMode(OUT4_PIN, OUTPUT);
  pinMode(OUT5_PIN, OUTPUT);
  pinMode(OUT6_PIN, OUTPUT);
  pinMode(OUT7_PIN, OUTPUT);
  pinMode(OUT8_PIN, OUTPUT);
  
  // Configure Inputs (with internal pull-ups)
  pinMode(INPUT1_PIN, INPUT_PULLUP);
  pinMode(INPUT2_PIN, INPUT_PULLUP);
  
  // All outputs OFF initially (MOSFET logic is inverted)
  digitalWrite(OUT1_PIN, HIGH);  // HIGH = OFF
  digitalWrite(OUT2_PIN, HIGH);
  digitalWrite(OUT3_PIN, HIGH);
  digitalWrite(OUT4_PIN, HIGH);
  digitalWrite(OUT5_PIN, HIGH);
  digitalWrite(OUT6_PIN, HIGH);
  digitalWrite(OUT7_PIN, HIGH);
  digitalWrite(OUT8_PIN, HIGH);
  
  Serial.println("Moto32 Ready!");
}

void loop() {
  // Read brake switch
  bool brakePressed = (digitalRead(INPUT1_PIN) == LOW);
  
  // Activate brake light if brake pressed
  digitalWrite(OUT4_PIN, brakePressed ? LOW : HIGH);
  
  // Read horn button
  bool hornPressed = (digitalRead(INPUT2_PIN) == LOW);
  
  // Activate horn if button pressed
  digitalWrite(OUT7_PIN, hornPressed ? LOW : HIGH);
  
  delay(10);  // Small delay for stability
}
MOSFET Logic: Remember that outputs are active LOW. Write LOW to turn ON, HIGH to turn OFF.

Testing Outputs

Bench Test Program

Upload this to test all outputs sequentially:

#include <Arduino.h>

// Define all 8 output pins
const int outputs[] = {1, 2, 3, 4, 5, 6, 7, 8};
const int numOutputs = 8;

void setup() {
  Serial.begin(115200);
  Serial.println("Moto32 Output Test");
  
  // Configure all outputs
  for(int i = 0; i < numOutputs; i++) {
    pinMode(outputs[i], OUTPUT);
    digitalWrite(outputs[i], HIGH);  // All OFF
  }
}

void loop() {
  // Test each output sequentially
  for(int i = 0; i < numOutputs; i++) {
    Serial.print("Testing Output ");
    Serial.println(i + 1);
    
    digitalWrite(outputs[i], LOW);   // Turn ON
    delay(500);
    digitalWrite(outputs[i], HIGH);  // Turn OFF
    delay(500);
  }
  
  Serial.println("Test cycle complete\n");
  delay(1000);
}

How to Use:

  1. Connect LED + resistor (or multimeter) to each output
  2. Upload program
  3. Watch LEDs light up sequentially
  4. Verify all 8 outputs work

Common Functions

Debouncing Inputs

bool readButtonDebounced(int pin) {
  static unsigned long lastDebounceTime = 0;
  static bool lastButtonState = HIGH;
  static bool buttonState = HIGH;
  
  bool reading = digitalRead(pin);
  
  if (reading != lastButtonState) {
    lastDebounceTime = millis();
  }
  
  if ((millis() - lastDebounceTime) > 50) {  // 50ms debounce
    if (reading != buttonState) {
      buttonState = reading;
    }
  }
  
  lastButtonState = reading;
  return (buttonState == LOW);  // Return true if pressed
}

Turn Signal Flasher

void updateTurnSignals() {
  static unsigned long lastFlash = 0;
  static bool flashState = false;
  const int flashRate = 500;  // ms
  
  if(millis() - lastFlash > flashRate) {
    flashState = !flashState;
    lastFlash = millis();
    
    if(leftTurnSignalActive) {
      digitalWrite(OUT5_PIN, flashState ? LOW : HIGH);
    }
    
    if(rightTurnSignalActive) {
      digitalWrite(OUT6_PIN, flashState ? LOW : HIGH);
    }
  }
}

Troubleshooting

Upload Fails

"Connecting..." stuck:

  • Hold BOOT button (GPIO0) during upload
  • Try lower upload speed (115200)
  • Check USB cable (must be data-capable)
  • Try different USB port

"Port not found":

  • Install CH340 drivers
  • Check device manager (Windows) or ls /dev/tty* (Mac/Linux)
  • Try different USB cable

Serial Monitor Issues

No output:

  • Check baud rate matches code (115200)
  • Verify "USB CDC On Boot" is enabled
  • Press ESP32 reset button

Garbage characters:

  • Wrong baud rate
  • Try 115200, 9600, or 74880 (boot ROM)

Compile Errors

"ESP32S3 not found":

  • Update ESP32 board support to 2.0.0+
  • Reinstall board package

"PSRAM error":

  • Check PSRAM settings in Tools menu
  • Use "OPI PSRAM" for -N8R2 module

Next Steps

Configuration

Customize pin mappings and features

Advanced Features

Implement advanced control logic

API Reference

Complete firmware documentation

Example Code

Download example firmware projects

Ready to Customize? Continue to the Configuration Guide to set up your Moto32 for your specific motorcycle.