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
- Download from arduino.cc/en/software
- Install version 2.0 or newer (recommended)
- Open Arduino IDE
Step 2: Add ESP32 Board Support
- Go to File → Preferences
- Find "Additional Board Manager URLs"
- Add this URL:
https://espressif.github.io/arduino-esp32/package_esp32_index.json
- Click OK
- Go to Tools → Board → Boards Manager
- Search for "esp32"
- Install "ESP32 by Espressif Systems" (version 2.0.0 or newer)
- 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
- Connect Moto32 to computer via USB-C
- Go to Tools → Board → esp32
- Select "ESP32S3 Dev Module"
- Configure board settings:
Setting | Value | Notes |
---|---|---|
USB CDC On Boot | Enabled | Required for serial communication |
USB Mode | Hardware CDC and JTAG | Default |
Flash Size | 8MB | Match your module |
PSRAM | OPI PSRAM | If you have PSRAM (N8R2) |
Partition Scheme | Default 4MB with spiffs | Or choose based on needs |
Upload Speed | 921600 | Faster uploads |
Step 4: Select Port
- Go to Tools → Port
- Select the port showing your ESP32:
- Windows:
COM3
,COM4
, etc. - Mac:
/dev/cu.usbserial-*
or/dev/cu.wchusbserial*
- Linux:
/dev/ttyUSB0
or/dev/ttyACM0
- Windows:
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:
- Go to File → Examples → Basics → Blink
- Modify the LED pin to GPIO2 (or any GPIO you can connect an LED to)
- Click Upload button (→)
- Wait for "Connecting..." message
- If it sticks on "Connecting...", hold the BOOT button on Moto32 (GPIO0 to GND)
- Upload should complete successfully
- Open Serial Monitor (Tools → Serial Monitor, set to 115200 baud)
- You should see ESP32 boot messages
Success! You can now program your Moto32.
Setup: PlatformIO
Step 1: Install VS Code
- Download Visual Studio Code
- Install for your operating system
- Launch VS Code
Step 2: Install PlatformIO Extension
- Click Extensions icon (sidebar)
- Search for "PlatformIO IDE"
- Click Install
- Wait for installation (may take several minutes)
- Reload VS Code when prompted
Step 3: Create New Project
- Click PlatformIO icon (sidebar)
- Click "New Project"
- Configure project:
- Name:
moto32-firmware
- Board: Search "ESP32-S3-DevKitC-1" or "ESP32S3 Dev Module"
- Framework: Arduino
- Name:
- Click Finish
- 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
- 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);
}
- Click Upload button (→ arrow) in bottom toolbar
- Wait for compile and upload
- 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:
- Connect LED + resistor (or multimeter) to each output
- Upload program
- Watch LEDs light up sequentially
- 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
Ready to Customize? Continue to the Configuration Guide to set up your Moto32 for your specific motorcycle.