UC2-ESP32 Getting Started Tutorial
The UC2-ESP32 firmware is the low-level software that runs on ESP32 microcontrollers to control UC2 hardware components. This tutorial guides you through setting up, flashing, and using UC2-ESP32 firmware.
Overview
UC2-ESP32 firmware features:
- Modular Architecture: Only compile modules you need
- Multi-Protocol Communication: Serial, WiFi, I2C support
- Real-time Control: Loop-based hardware management
- Resource Optimization: Minimal RAM and CPU usage
- Extensible Design: Easy to add new hardware modules
Supported Hardware Modules
- Motors: Stepper motors for XYZ stages and focus control
- LEDs: Individual LEDs and LED arrays/matrices
- Lasers: Laser diode control with safety features
- Sensors: Temperature, humidity, and other environmental sensors
- Communication: WiFi, Bluetooth, Serial interfaces
- Input Controllers: Joysticks, PS4 controllers, buttons
Firmware Resources and Tools
Official Firmware Repository
- Main Repository: UC2-ESP32 Firmware - Complete firmware source code and documentation
- Rework Branch: uc2-esp32/reworkBD - Latest development version with enhanced features
Firmware Flashing Tools
- Web-based Flashing: youseetoo.github.io - Browser-based firmware flashing tool
- Firmware Testing Interface: WebSerial Test Tool - Browser-based testing and configuration
Supported Images and Documentation
The UC2-ESP32 firmware supports various hardware configurations with corresponding images and setup guides available in the repository.
Firmware Architecture
Module Structure
Each hardware module implements four standard functions:
class HardwareModule {
public:
void setup(); // Initialize hardware
void loop(); // Continuous background tasks
void act(); // Execute commands
void get(); // Return status/data
};
Communication Protocol
Commands use JSON format:
{
"task": "/motor_act",
"motor": 0,
"direction": 1,
"steps": 1000
}
Responses follow the same structure:
{
"return": 1,
"task": "/motor_act",
"motor": 0,
"position": 1000
}
Installation and Setup
Method 1: Web-Based Flashing (Recommended)
The easiest way to flash UC2-ESP32 firmware:
Visit the UC2 Firmware Page:
- Go to youseetoo.github.io
- This provides a web-based ESP32 flashing interface
Select Your Board:
- Choose your specific ESP32 board type
- Common options: ESP32-WROOM, ESP32-CAM, Custom UC2 boards
- If unsure, check your hardware documentation
Connect ESP32:
- Connect ESP32 to computer via USB
- Ensure proper USB drivers are installed
- Press and hold BOOT button (if required)
Flash Firmware:
- Click "Connect" and select the correct COM port
- Click "Flash Firmware"
- Wait for completion (usually 1-2 minutes)
Test Installation:
- Visit UC2 Web Serial Test Page
- Connect to your ESP32
- Send test commands to verify functionality
Method 2: PlatformIO (Development)
For development and customization:
Install PlatformIO:
# Install PlatformIO Core
pip install platformio
# Or use PlatformIO IDE extension in VS CodeClone Firmware Repository:
git clone https://github.com/youseetoo/uc2-esp32
cd uc2-esp32
# Switch to development branch for latest features
git checkout mainConfigure Build:
# Edit platformio.ini for your board and modules
nano platformio.iniBuild and Flash:
# Build firmware
pio run
# Flash to ESP32
pio run --target upload
# Monitor serial output
pio device monitor
Basic Configuration
Serial Communication Setup
Default serial parameters:
- Baud Rate: 115200
- Data Bits: 8
- Stop Bits: 1
- Parity: None
- Flow Control: None
WiFi Configuration
Configure WiFi for network communication (right now this is untested and barely documented ):
// WiFi credentials (set in firmware or via serial)
const char* ssid = "your_wifi_network";
const char* password = "your_wifi_password";
// Static IP configuration (optional)
IPAddress local_IP(192, 168, 1, 100);
IPAddress gateway(192, 168, 1, 1);
IPAddress subnet(255, 255, 255, 0);
Set WiFi via serial commands:
{
"task": "/wifi_act",
"ssid": "your_network",
"password": "your_password"
}
Module Configuration
Hardware Control Examples
Motor Control
Based on the JSON API specification, here are the correct motor control commands:
Move Stepper Motor:
{
"task": "/motor_act",
"motor": {
"steppers": [
{
"stepperid": 1,
"position": 1000,
"speed": 15000,
"isabs": true,
"isblocking": false
}
]
}
}
Home Stepper Motor:
{
"task": "/home_act",
"home": {
"steppers": [
{
"stepperid": 1,
"timeout": 20000,
"speed": 15000,
"direction": 1,
"endposrelease": 3000
}
]
}
}
Get Motor Position:
{
"task": "/motor_get",
"motor": {
"steppers": [
{
"stepperid": 1
}
]
}
}
Set Motor Position (Calibration):
{
"task": "/motor_set",
"motor": {
"steppers": [
{
"stepperid": 1,
"position": 0
}
]
}
}
LED Control
Set Individual LED:
{
"task": "/led_act",
"led": {
"LEDArrMode": 1,
"led_array": [
{
"id": 1,
"r": 255,
"g": 0,
"b": 0
}
]
}
}
Set LED Array Pattern:
{
"task": "/led_act",
"led": {
"LEDArrMode": 1,
"led_array": [
{"id": 1, "r": 255, "g": 0, "b": 0},
{"id": 2, "r": 0, "g": 255, "b": 0},
{"id": 3, "r": 0, "g": 0, "b": 255},
{"id": 4, "r": 255, "g": 255, "b": 255}
]
}
}
Get LED Status:
{
"task": "/led_get"
}
Laser Control
Turn on Laser:
{
"task": "/laser_act",
"laser": {
"LASERid": 1,
"LASERval": 100
}
}
Turn off Laser (Safety):
{
"task": "/laser_act",
"laser": {
"LASERid": 1,
"LASERval": 0
}
}
Get Laser Status:
{
"task": "/laser_get"
}
Web Interface Test
Access Web Test Page:
- Open youseetoo.github.io/indexWebSerialTest.html
- Connect to your ESP32
Test Basic Commands:
{"task": "/state_get"}
{"task": "/led_act", "led": 0, "intensity": 100}
{"task": "/led_act", "led": 0, "intensity": 0}Verify Responses:
- Check that commands return proper JSON responses
- Observe physical hardware changes (LEDs, motor movement)
Python Test Script
import serial
import json
import time
def test_uc2_esp32(port="/dev/ttyUSB0", baudrate=115200):
"""Test basic UC2-ESP32 communication"""
try:
# Open serial connection
ser = serial.Serial(port, baudrate, timeout=1)
time.sleep(2) # Wait for connection
# Test state command
command = {"task": "/state_get"}
ser.write((json.dumps(command) + '\n').encode())
response = ser.readline().decode().strip()
if response:
result = json.loads(response)
print(f"State response: {result}")
if result.get("return") == 1:
print("✓ ESP32 communication successful")
return True
else:
print("✗ ESP32 returned error")
return False
else:
print("✗ No response from ESP32")
return False
except Exception as e:
print(f"✗ Communication error: {e}")
return False
finally:
if 'ser' in locals():
ser.close()
# Run test
if __name__ == "__main__":
test_uc2_esp32()
Advanced Configuration
Custom Module Development
Create a custom hardware module:
// custom_module.h
#ifndef CUSTOM_MODULE_H
#define CUSTOM_MODULE_H
class CustomModule {
public:
void setup();
void loop();
void act(JsonObject& json_in, JsonObject& json_out);
void get(JsonObject& json_in, JsonObject& json_out);
private:
int custom_value;
bool enabled;
};
extern CustomModule customModule;
#endif
// custom_module.cpp
#include "custom_module.h"
CustomModule customModule;
void CustomModule::setup() {
// Initialize custom hardware
custom_value = 0;
enabled = true;
Serial.println("Custom module initialized");
}
void CustomModule::loop() {
// Background tasks (if needed)
if (enabled) {
// Continuous operations
}
}
void CustomModule::act(JsonObject& json_in, JsonObject& json_out) {
// Handle action commands
if (json_in.containsKey("value")) {
custom_value = json_in["value"];
json_out["return"] = 1;
json_out["value"] = custom_value;
}
}
void CustomModule::get(JsonObject& json_in, JsonObject& json_out) {
// Return status
json_out["return"] = 1;
json_out["custom_value"] = custom_value;
json_out["enabled"] = enabled;
}
Network Configuration
Configure advanced networking (This is right now largely untested/undocumented):
// Static IP configuration
void setupStaticIP() {
if (!WiFi.config(local_IP, gateway, subnet, primaryDNS, secondaryDNS)) {
Serial.println("Static IP configuration failed");
}
}
// Access Point mode
void setupAccessPoint() {
WiFi.softAP("UC2-ESP32", "password123");
IPAddress IP = WiFi.softAPIP();
Serial.print("AP IP address: ");
Serial.println(IP);
}
// Web server for HTTP API
void setupWebServer() {
server.on("/api/motor", HTTP_POST, handleMotorAPI);
server.on("/api/led", HTTP_POST, handleLEDAPI);
server.on("/api/status", HTTP_GET, handleStatusAPI);
server.begin();
}
Performance Optimization
Optimize for specific applications:
// Reduce motor loop frequency for power saving
#define MOTOR_LOOP_INTERVAL 10 // ms
// Buffer size optimization
#define JSON_BUFFER_SIZE 512
// Task priorities for multi-core ESP32
void setupTaskPriorities() {
// High priority for motor control
xTaskCreatePinnedToCore(
motorTask, "MotorTask", 2048, NULL, 2, NULL, 1);
// Low priority for WiFi communication
xTaskCreatePinnedToCore(
wifiTask, "WiFiTask", 4096, NULL, 1, NULL, 0);
}
Troubleshooting
Common Issues
ESP32 not responding:
- Check USB cable and connection
- Verify correct COM port
- Press RESET button
- Try different baud rates (used to be higher, now it's 115200 BAUD)
Firmware upload fails:
- Hold BOOT button during upload
- Check board selection in IDE
- Verify USB drivers installed
- Try different upload speed
Motor not moving:
- Check power supply voltage
- Verify motor driver connections
- Test with manual commands
- Check current limits
Debug Output
Enable debug output for troubleshooting:
#define DEBUG_SERIAL 1
#define DEBUG_WIFI 1
#define DEBUG_MOTOR 1
void debugPrint(String message) {
#if DEBUG_SERIAL
Serial.println("[DEBUG] " + message);
#endif
}
Integration with ImSwitch
UC2-REST Communication Layer
UC2-ESP32 communicates with ImSwitch through UC2-REST:
from UC2REST import UC2Client
# Connect to ESP32
client = UC2Client(serialport="/dev/ttyUSB0")
# Test communication
if client.is_connected:
print("Connected to UC2-ESP32")
# Send commands through UC2-REST
client.stage.move_x(1000)
client.led.set_led(channel=1, intensity=100)
Configuration in ImSwitch
Configure ESP32 device in ImSwitch:
{
"rs232devices": {
"ESP32": {
"managerName": "ESP32Manager",
"managerProperties": {
"serialport": "/dev/ttyUSB0",
"baudrate": 115200
}
}
}
}
Next Steps
- UC2-REST Integration - Python interface setup
- ImSwitch Configuration - Configure ImSwitch for ESP32
- Hardware Assembly - Physical hardware setup