Arduino Integration
Connect Arduino controllers to OctoMY™
Arduino Integration
Learn how to integrate Arduino microcontrollers with OctoMY™ using the ArduMY firmware. This tutorial covers advanced configuration and custom actuator types.
Pro Tip
If you're building your first robot, start with the Basic Wheeled Robot tutorial. This advanced guide covers ArduMY configuration in depth for custom projects.
Overview
ArduMY is OctoMY™'s firmware for Arduino-compatible boards. It provides:
- Serial protocol for phone/computer communication
- Support for multiple actuator and sensor types
- Fail-safe modes for safety
- Real-time control with minimal latency
ArduMY Architecture
┌────────────────────────────────────────┐
│ OctoMY Agent │
│ (Phone/Computer) │
└───────────────┬────────────────────────┘
│ USB Serial
┌───────────────┴────────────────────────┐
│ Arduino + ArduMY │
│ ┌─────────────────────────────────┐ │
│ │ Protocol Parser │ │
│ │ Actuator Manager │ │
│ │ Sensor Reader │ │
│ │ Fail-safe Controller │ │
│ └─────────────────────────────────┘ │
└───────┬───────────┬───────────┬────────┘
│ │ │
[Servos] [Motors] [Sensors]
Supported boards
| Board | Pins | PWM | Analog | Notes |
|---|---|---|---|---|
| Arduino Mega 2560 | 54 | 15 | 16 | Recommended |
| Arduino Uno | 14 | 6 | 6 | Basic projects |
| Arduino Nano | 14 | 6 | 8 | Compact projects |
| ESP32 | 34 | 16 | 18 | WiFi capable |
| Teensy 4.0 | 40 | 31 | 14 | High performance |
Did You Know?
The Arduino Mega is recommended because it has 15 PWM pins - enough for complex robots with multiple servos and motors. The ESP32 adds WiFi, enabling wireless control without a phone connected.
Step 1: Install ArduMY firmware
Download
Get the ArduMY source from the OctoMY™ repository:
cd /path/to/OctoMY
ls src/libs/libardumy/arduino/
Open in Arduino IDE
- Open Arduino IDE
- File → Open → Navigate to:
src/libs/libardumy/arduino/ArduMYMain/ArduMYMain.ino
Configure board
- Tools → Board → Select your board
- Tools → Port → Select COM port
- Tools → Upload Speed → 115200
Step 2: Configure ArduMY
Main configuration
Edit ArduMYConfig.h:
#ifndef ARDUMY_CONFIG_H
#define ARDUMY_CONFIG_H
// Serial settings
#define SERIAL_BAUD 115200
// Number of actuators
#define NUM_ACTUATORS 8
// Number of sensors
#define NUM_SENSORS 4
// Fail-safe timeout (ms)
#define FAILSAFE_TIMEOUT 1000
// Update rate (Hz)
#define UPDATE_RATE 50
#endif
Actuator configuration
Define your actuators in ActuatorConfig.h:
#include "ArduMY.h"
ActuatorConfig actuators[NUM_ACTUATORS] = {
// Name Type Pin(s) Min Max Default
{"servo.pan", ACTUATOR_SERVO, {9}, 0, 180, 90},
{"servo.tilt", ACTUATOR_SERVO, {10}, 0, 180, 90},
{"motor.left", ACTUATOR_DC, {5, 6, 7}, -100, 100, 0},
{"motor.right", ACTUATOR_DC, {8, 11, 12}, -100, 100, 0},
// Add more actuators...
};
Sensor configuration
Define sensors in SensorConfig.h:
#include "ArduMY.h"
SensorConfig sensors[NUM_SENSORS] = {
// Name Type Pin(s)
{"distance.front", SENSOR_ULTRASONIC, {2, 3}}, // trig, echo
{"distance.left", SENSOR_ULTRASONIC, {4, 5}},
{"line.sensors", SENSOR_ANALOG, {A0, A1, A2}},
{"battery.voltage", SENSOR_ANALOG, {A7}},
};
Step 3: Actuator types
Servo motors
Standard hobby servos (PWM control).
// Single servo
{"arm.shoulder", ACTUATOR_SERVO, {9}, 0, 180, 90}
Wiring
Servo
┌─────────┐
│ ● ● ● │
│Signal │
│ 5V GND │
└─────────┘
│ │ │
│ │ └── GND
│ └───── 5V (or 6V external)
└──────── Arduino PWM pin
DC motors
Bidirectional DC motors with H-bridge driver.
// DC motor with L298N (EN, IN1, IN2)
{"motor.left", ACTUATOR_DC, {9, 8, 7}, -100, 100, 0}
The three pins are:
- EN - PWM speed control
- IN1 - Direction bit 1
- IN2 - Direction bit 2
Control logic
| Speed | EN | IN1 | IN2 | Result |
|---|---|---|---|---|
| 0 | 0 | X | X | Stop |
| 50 | 50% | 1 | 0 | Forward 50% |
| -50 | 50% | 0 | 1 | Reverse 50% |
| 100 | 100% | 1 | 0 | Full forward |
Stepper motors
Step/direction control for stepper drivers.
// Stepper with A4988 driver (step, dir)
{"stepper.z", ACTUATOR_STEPPER, {2, 3}, 0, 10000, 0}
Wiring with A4988
A4988 Driver
┌───────────────────┐
│ DIR STEP EN │
│ │ │ │ │
└──┼────┼────┼──────┘
│ │ │
│ │ └── Arduino D4 (optional)
│ └─────── Arduino D3
└──────────── Arduino D2
Relay outputs
On/off control for high-power loads.
// Relay (digital output)
{"lights.main", ACTUATOR_RELAY, {13}, 0, 1, 0}
Continuous rotation servos
Modified servos for continuous rotation.
// Continuous servo (-100 to 100 speed)
{"wheel.left", ACTUATOR_CONTINUOUS, {9}, -100, 100, 0}
Step 4: Sensor types
Ultrasonic distance
HC-SR04 or similar (trigger + echo pins).
{"distance.front", SENSOR_ULTRASONIC, {2, 3}} // trig=2, echo=3
Analog sensors
Generic analog input (potentiometers, IR sensors, etc.).
{"sensor.pot", SENSOR_ANALOG, {A0}}
Digital switches
Limit switches, buttons, etc.
{"limit.left", SENSOR_DIGITAL, {4}} // INPUT_PULLUP used
I2C devices
Sensors on I2C bus (MPU6050, etc.).
{"imu", SENSOR_I2C, {0x68}} // I2C address
Step 5: Upload and test
Upload firmware
- Connect Arduino via USB
- Click Upload in Arduino IDE
- Wait for "Done uploading"
Serial monitor test
Open Serial Monitor (115200 baud):
ArduMY v1.0.0
Board: Arduino Mega
Actuators: 4
Sensors: 3
Fail-safe timeout: 1000ms
Ready. Waiting for commands...
Test commands
Send commands manually:
# Query status
?
# Set actuator (servo.pan to 90)
A0=90
# Read sensor (distance.front)
S0?
# Enable/disable actuators
E1 # Enable
E0 # Disable
Pro Tip
Use the Arduino Serial Monitor's "No line ending" setting when testing. If commands don't work, try "Newline" or "Both NL & CR" instead.
Step 6: OctoMY™ integration
Connect to Agent
- Connect Arduino to phone via USB OTG
- Open OctoMY™ Agent
- Go to Settings → Hardware
- Controller should auto-detect
┌─────────────────────────────────────────────┐
│ Hardware Configuration │
├─────────────────────────────────────────────┤
│ │
│ Controller │
│ ● Arduino Mega at /dev/ttyUSB0 │
│ ArduMY v1.0.0 │
│ Status: Connected │
│ │
│ Actuators Sensors │
│ ├── servo.pan ├── distance │
│ ├── servo.tilt ├── imu │
│ ├── motor.left └── battery │
│ └── motor.right │
│ │
│ [Configure] [Test] [Disconnect] │
│ │
└─────────────────────────────────────────────┘
Map actuators
OctoMY™ auto-imports actuator names from ArduMY. Verify mapping:
┌─────────────────────────────────────────────┐
│ Actuator Mapping │
├─────────────────────────────────────────────┤
│ │
│ ArduMY Name │ OctoMY Name │ Type │
│ ───────────────────────────────────────── │
│ servo.pan │ head.pan │ Servo │
│ servo.tilt │ head.tilt │ Servo │
│ motor.left │ motors.left │ DC │
│ motor.right │ motors.right │ DC │
│ │
│ [Apply Mapping] [Reset to Defaults] │
│ │
└─────────────────────────────────────────────┘
Step 7: Fail-safe configuration
ArduMY includes fail-safe features for robot safety.
Security Consideration
Always configure fail-safe behavior for your robot. A robot that keeps moving when communication is lost can cause damage or injury. The default 1-second timeout is a good starting point.
Timeout behavior
If communication is lost for FAILSAFE_TIMEOUT milliseconds:
// In ArduMYConfig.h
#define FAILSAFE_TIMEOUT 1000 // 1 second
// Default fail-safe values (in ActuatorConfig)
{"motor.left", ACTUATOR_DC, {5, 6, 7}, -100, 100, 0}, // 0 = stopped
{"servo.pan", ACTUATOR_SERVO, {9}, 0, 180, 90}, // 90 = centered
Custom fail-safe
Override the fail-safe handler:
void onFailsafe() {
// Custom fail-safe behavior
for (int i = 0; i < NUM_ACTUATORS; i++) {
setActuator(i, actuators[i].defaultValue);
}
// Optional: signal failure
digitalWrite(LED_BUILTIN, HIGH);
}
Recovery
When communication resumes:
- Actuators remain at fail-safe values
- Agent must explicitly re-enable actuators
- Prevents sudden movements after reconnection
Advanced: Custom actuator types
Define custom type
// In ArduMY.h
enum ActuatorType {
ACTUATOR_SERVO,
ACTUATOR_DC,
ACTUATOR_STEPPER,
ACTUATOR_RELAY,
ACTUATOR_CONTINUOUS,
ACTUATOR_CUSTOM1, // Your custom type
ACTUATOR_CUSTOM2,
};
Implement handler
void handleCustomActuator(int id, float value) {
ActuatorConfig& cfg = actuators[id];
switch (cfg.type) {
case ACTUATOR_CUSTOM1:
// Your custom control logic
int pwm = map(value, cfg.minVal, cfg.maxVal, 0, 255);
analogWrite(cfg.pins[0], pwm);
// Additional logic...
break;
}
}
Troubleshooting
Arduino not detected
| Issue | Solution |
|---|---|
| No USB connection | Check cable (data, not charge-only) |
| Wrong port | Verify COM port in device manager |
| Permission denied | Linux: add user to dialout group |
| Driver missing | Install CH340/FTDI drivers |
Commands not working
| Issue | Solution |
|---|---|
| No response | Check baud rate (115200) |
| Garbled output | Verify serial settings |
| Actuators don't move | Check wiring and power |
| Wrong direction | Swap motor wires or pins |
Fail-safe triggers
| Issue | Solution |
|---|---|
| Frequent timeouts | Increase FAILSAFE_TIMEOUT |
| No fail-safe | Verify timeout is enabled |
| Slow recovery | Reduce agent poll interval |
Performance tips
Reduce latency
// Increase serial buffer
#define SERIAL_RX_BUFFER_SIZE 256
// Use direct port manipulation for time-critical actuators
PORTD = (PORTD & 0x0F) | (value & 0xF0);
Handle many actuators
// Stagger servo updates to reduce power spikes
void updateServos() {
for (int i = 0; i < numServos; i++) {
servos[i].write(values[i]);
delayMicroseconds(100); // Stagger
}
}
Battery monitoring
// Read battery voltage periodically
float readBattery() {
int raw = analogRead(A7);
float voltage = raw * (5.0 / 1023.0) * 3.0; // Voltage divider
return voltage;
}
void loop() {
if (readBattery() < 6.0) {
triggerFailsafe(); // Low battery protection
}
}
Next steps
- Add sensors - Sensor Setup
- Write behavior plans - Create a Plan
- Build a complete robot - Basic Wheeled Robot