Add sensors to your robot for autonomous behavior. This tutorial covers common sensor types and how to integrate them with OctoMY™.
Pro Tip
Start with a single distance sensor for obstacle avoidance. Once that's working, add more sensors incrementally. Debugging multiple sensors at once can be frustrating!
Sensors allow your robot to perceive its environment:
| Sensor Type | Measures | Use Cases |
|---|---|---|
| Distance | Range to objects | Obstacle avoidance |
| IMU | Orientation, acceleration | Balance, heading |
| Line | Surface reflectivity | Line following |
| Touch | Physical contact | Bump detection |
| Light | Ambient brightness | Light seeking |
Before adding sensors, ensure you have:
Low-cost ultrasonic distance sensor (2-400cm range).
Did You Know?
The HC-SR04 works by sending a 40kHz ultrasonic pulse and measuring the time for the echo. At 343 m/s (speed of sound), each microsecond of delay equals about 0.017 cm distance.
HC-SR04
┌─────────────────┐
│ VCC TRIG ECHO GND
│ │ │ │ │
└───┼────┼────┼────┼───
│ │ │ │
│ │ │ └── Arduino GND
│ │ └─────── Arduino D12
│ └──────────── Arduino D11
└───────────────── Arduino 5V
| HC-SR04 Pin | Arduino Pin |
|---|---|
| VCC | 5V |
| TRIG | D11 |
| ECHO | D12 |
| GND | GND |
In the ArduMY firmware, add the sensor:
#define SENSOR_TRIG 11
#define SENSOR_ECHO 12
void setup() {
pinMode(SENSOR_TRIG, OUTPUT);
pinMode(SENSOR_ECHO, INPUT);
}
float readDistance() {
digitalWrite(SENSOR_TRIG, LOW);
delayMicroseconds(2);
digitalWrite(SENSOR_TRIG, HIGH);
delayMicroseconds(10);
digitalWrite(SENSOR_TRIG, LOW);
long duration = pulseIn(SENSOR_ECHO, HIGH);
return duration * 0.034 / 2; // cm
}
┌─────────────────────────────────────────────┐
│ Configure Sensor │
├─────────────────────────────────────────────┤
│ │
│ Name: distance.front │
│ Type: Ultrasonic (HC-SR04) │
│ │
│ Trigger Pin: 11 │
│ Echo Pin: 12 │
│ │
│ Update Rate: [20___] Hz │
│ Min Range: [2____] cm │
│ Max Range: [400__] cm │
│ │
│ [Test Sensor] [Save] │
│ │
└─────────────────────────────────────────────┘
Use Test Sensor to see live readings:
┌─────────────────────────────────────────────┐
│ Sensor: distance.front │
├─────────────────────────────────────────────┤
│ │
│ Current: 45.3 cm │
│ ████████████████░░░░░░░░ 45/400 cm │
│ │
│ Min: 23.1 cm Max: 187.4 cm │
│ Update Rate: 20 Hz │
│ │
│ [Stop] [Close] │
│ │
└─────────────────────────────────────────────┘
Infrared distance sensor (10-80cm or 20-150cm models).
Sharp IR
┌─────────────────┐
│ VCC GND OUT │
│ │ │ │ │
└───┼────┼────┼───┘
│ │ │
│ │ └─── Arduino A0 (analog)
│ └──────── Arduino GND
└───────────── Arduino 5V
┌─────────────────────────────────────────────┐
│ Configure Sensor │
├─────────────────────────────────────────────┤
│ │
│ Name: distance.front_ir │
│ Type: Sharp IR GP2Y0A21 │
│ │
│ Analog Pin: A0 │
│ │
│ [Test Sensor] [Save] │
│ │
└─────────────────────────────────────────────┘
Accelerometer + gyroscope for orientation sensing.
Security Consideration
IMU calibration is critical for accurate readings. An uncalibrated IMU will have drift and offset errors that accumulate over time, causing your robot to veer off course.
MPU6050
┌─────────────────┐
│ VCC GND SCL SDA │
│ │ │ │ │ │
└──┼───┼───┼───┼──┘
│ │ │ │
│ │ │ └── Arduino A4 (SDA)
│ │ └────── Arduino A5 (SCL)
│ └────────── Arduino GND
└────────────── Arduino 3.3V
| MPU6050 Pin | Arduino Pin |
|---|---|
| VCC | 3.3V |
| GND | GND |
| SCL | A5 |
| SDA | A4 |
The ArduMY firmware includes MPU6050 support:
#include <Wire.h>
#include <MPU6050.h>
MPU6050 imu;
void setup() {
Wire.begin();
imu.initialize();
}
void readIMU(float* ax, float* ay, float* az,
float* gx, float* gy, float* gz) {
int16_t raw[6];
imu.getMotion6(&raw[0], &raw[1], &raw[2],
&raw[3], &raw[4], &raw[5]);
// Convert to physical units...
}
┌─────────────────────────────────────────────┐
│ Configure Sensor │
├─────────────────────────────────────────────┤
│ │
│ Name: sensors.imu │
│ Type: MPU6050 (6-axis) │
│ │
│ I2C Address: 0x68 (default) │
│ │
│ [Calibrate] [Test Sensor] [Save] │
│ │
└─────────────────────────────────────────────┘
Before use, calibrate the IMU:
┌─────────────────────────────────────────────┐
│ IMU Calibration │
├─────────────────────────────────────────────┤
│ │
│ Status: Calibrating... │
│ │
│ Place robot on level surface │
│ Do not move during calibration │
│ │
│ Progress: ████████░░░░░░░░░ 45% │
│ │
│ Calculated Offsets: │
│ Accel X: -234 Gyro X: 12 │
│ Accel Y: 156 Gyro Y: -8 │
│ Accel Z: 892 Gyro Z: 3 │
│ │
│ [Cancel] │
│ │
└─────────────────────────────────────────────┘
Detects light vs dark surfaces for line following.
QRE1113 Array (Left, Center, Right)
┌─────────────────────────────────────┐
│ VCC GND L C R │
│ │ │ │ │ │ │
└────┼────┼───┼────┼────┼─────────────┘
│ │ │ │ │
│ │ │ │ └─── Arduino A2
│ │ │ └──────── Arduino A1
│ │ └───────────── Arduino A0
│ └───────────────── Arduino GND
└────────────────────── Arduino 5V
┌─────────────────────────────────────────────┐
│ Configure Sensor Array │
├─────────────────────────────────────────────┤
│ │
│ Name: line.sensors │
│ Type: Reflectance Array │
│ Count: 3 │
│ │
│ Pins: A0, A1, A2 │
│ │
│ Threshold: [500___] (0-1023) │
│ (Below = line detected) │
│ │
│ [Calibrate] [Test] [Save] │
│ │
└─────────────────────────────────────────────┘
Pro Tip
Use a high-contrast line (black tape on white surface works best). Ambient lighting can affect readings, so test in the environment where your robot will operate.
Simple contact detection.
Microswitch
┌───────────────┐
│ COM NO NC │
│ │ │ │ │
└───┼────┼───┼──┘
│ │ │
│ │ └── (not used)
│ └────── Arduino D2
└─────────── Arduino GND
Connect COM to GND, NO (normally open) to digital pin with INPUT_PULLUP.
┌─────────────────────────────────────────────┐
│ Configure Sensor │
├─────────────────────────────────────────────┤
│ │
│ Name: bump.front │
│ Type: Digital Switch │
│ │
│ Pin: 2 │
│ Active: LOW (pullup enabled) │
│ │
│ [Test Sensor] [Save] │
│ │
└─────────────────────────────────────────────┘
Once sensors are configured, access them in OPAL plans:
plan ObstacleAvoider {
var safe_distance = 30 // cm
loop {
var front = sensors.distance.front
if front < safe_distance {
// Too close - back up and turn
motors.left = -50
motors.right = -50
delay(300)
motors.left = 50
motors.right = -50
delay(400)
} else {
// Clear - go forward
motors.left = 60
motors.right = 60
}
delay(50)
}
}
plan LineFollower {
loop {
var left = sensors.line.left
var center = sensors.line.center
var right = sensors.line.right
if center {
// On line - go straight
drive(60, 60)
} else if left {
// Line on left - turn left
drive(30, 60)
} else if right {
// Line on right - turn right
drive(60, 30)
} else {
// Lost line - search
drive(40, -40)
}
delay(20)
}
}
plan HeadingHold {
var target_heading = sensors.imu.heading
loop {
var current = sensors.imu.heading
var error = target_heading - current
// Normalize error to -180 to 180
if error > 180 {
error = error - 360
} else if error < -180 {
error = error + 360
}
// Simple P control
var correction = error * 2
motors.left = 50 + correction
motors.right = 50 - correction
delay(20)
}
}
Use multiple sensors for robust behavior:
plan SmartNavigator {
loop {
var front = sensors.distance.front
var left = sensors.distance.left
var right = sensors.distance.right
var bump = sensors.bump.front
if bump {
// Emergency stop
stop()
delay(500)
backup()
} else if front < 20 {
// Very close - avoid
if left > right {
turn_left()
} else {
turn_right()
}
} else if front < 50 {
// Approaching - slow down
drive_slow()
} else {
drive_fast()
}
delay(50)
}
}
| Issue | Solution |
|---|---|
| Wiring error | Check connections, especially power/ground |
| Wrong pin | Verify pin numbers in configuration |
| I2C not working | Check SDA/SCL connections, try I2C scanner |
| Damaged sensor | Test with Arduino sketch directly |
| Issue | Solution |
|---|---|
| Noisy values | Add capacitors, check ground connections |
| Out of range | Verify sensor specifications |
| Slow updates | Increase update rate in configuration |
| Wrong units | Check sensor calibration |
| Issue | Solution |
|---|---|
| Heading drifts over time | Re-calibrate, use magnetometer fusion |
| Values jump | Check for vibration, motor interference |
| Wrong orientation | Verify sensor mounting orientation |