-
Notifications
You must be signed in to change notification settings - Fork 0
Examples
Complete, ready-to-flash sketches. Copy any one into your project's main.cpp (PlatformIO) or .ino (Arduino IDE) and upload -- each is a whole program, setup() and loop() included.
Note Two things about the movement calls below: walking, turning, and gestures are blocking -- the call returns only when the motion finishes -- and the walking sketches genuinely drive the robot across the floor, so give it space and be ready to catch it. See Bench Testing for the safe bring-up workflow.
The classic: Otto walks forward and turns away from anything in its path.
Needs: the standard biped kit (distance sensor + leg servos), and room to walk.
#include <OttoFlow.h>
const long AVOID_CM = 15; // react when something is closer than this
void setup() {
OttoFlow::start(); // classic Otto biped kit
Mouth::show(Icon::Happy);
Voice::play(Sound::Hello);
}
void loop() {
if (Eyes::closerThanCm(AVOID_CM)) {
// Something is in the way: stop, react, then turn until the path is clear.
Mouth::show(Icon::Surprised);
Voice::play(Sound::OhOoh);
Legs::walkBackward(1);
while (Eyes::closerThanCm(AVOID_CM)) {
Legs::turnRight(1);
}
Mouth::show(Icon::Happy);
} else {
// Clear ahead: take a step.
Legs::walkForward(1);
}
}How it works
-
Eyes::closerThanCm(15)is the whole obstacle test. The distance reading is median-filtered for you, so a single bad echo will not trigger a false turn. - Because moves block, the logic reads straight down the page: back off one step, keep turning right until the way ahead opens, then carry on walking.
- Turning until clear, rather than a fixed amount, means Otto handles corners and walls it turns into -- not just one obstacle at a time.
A safe-on-a-desk companion: it never walks, but reacts to a hand, a tap, and a clap with faces, sounds, and a wave.
Needs: distance sensor, touch sensor (pin A0), and microphone (pin A6). Arms are optional -- the wave is a no-op without them.
#include <OttoFlow.h>
void setup() {
OttoFlow::start(Preset::Humanoid); // arms if present; harmless on a biped
Mouth::show(Icon::Happy);
Voice::play(Sound::Hello);
Arms::waveRight(2); // silently skipped if this build has no arms
}
void loop() {
// A tap on the head -> affection
if (Touch::wasTapped()) {
Mouth::show(Icon::Heart);
Voice::play(Sound::Cuddly);
Arms::waveRight(1);
delay(800);
return;
}
// A clap or loud noise -> surprise
if (Ears::hearsSoundLouderThanPercent(65)) {
Mouth::show(Icon::SmallSurprise);
Voice::play(Sound::OhOoh);
delay(600);
return;
}
// Otherwise the resting face follows how close your hand is
Mouth::show(Eyes::closerThanCm(10) ? Icon::Surprised : Icon::Happy);
}How it works
-
Touch::wasTapped()fires once per tap because it detects the change, so a resting finger does not keep re-triggering. It works whether your sensor is momentary or toggle -- see Touch. - The
returnafter each reaction lets the heart or surprise face linger for itsdelay()before the resting face takes back over. -
Arms::waveRight()on a biped build is a silent no-op, so the one sketch runs on both kits with no#ifdef. - The loop issues no leg commands, so the feet stay put -- safe on a desk.
Clap to cue the next move in a playlist of gestures.
Needs: microphone (pin A6), and room to move -- gestures move the legs.
#include <OttoFlow.h>
// A little show; each clap advances to the next move.
const Gesture SHOW[] = {
Gesture::Happy, Gesture::Love, Gesture::Victory,
Gesture::Confused, Gesture::Magic, Gesture::SuperHappy
};
const uint8_t SHOW_COUNT = sizeof(SHOW) / sizeof(SHOW[0]);
uint8_t next = 0;
void setup() {
OttoFlow::start(); // classic biped
Mouth::show(Icon::Happy);
}
void loop() {
if (Ears::hearsSoundLouderThanPercent(70)) {
Gestures::play(SHOW[next]); // blocks until the move finishes
next = (next + 1) % SHOW_COUNT; // wrap back to the start
}
}How it works
- Each gesture is a whole performance -- movement, face, and sound -- and blocks until it ends, then leaves Otto back in a neutral standing pose.
- Stepping through a fixed playlist keeps the show predictable and needs no random-seed setup.
- Raise the
70threshold if a noisy room keeps setting Otto off; lower it if it ignores your claps.
Hold Otto in your hand and it reacts to being shaken, tilted, or turned upside down -- a good first check that the motion sensor works.
Needs: the MPU-6050 motion sensor wired to I2C (A4/A5) and enabled in the config.
#include <OttoFlow.h>
Icon mood = Icon::Happy;
void setup() {
OttoConfig cfg;
cfg.mpu6050.enabled = true; // GY-521 board on I2C (A4 = SDA, A5 = SCL)
OttoFlow::start(cfg);
Motion::disable(); // held in hand: keep the servos off and quiet
Mouth::show(mood);
}
void loop() {
Icon next;
if (Balance::isShakenHarderThanG(0.8)) next = Icon::Surprised;
else if (Balance::isUpsideDown()) next = Icon::Confused;
else if (!Balance::isLevelWithinDegrees(25)) next = Icon::SmallSurprise; // tilted
else next = Icon::Happy; // level and calm
if (next != mood) { // act only when the mood actually changes
mood = next;
Mouth::show(mood);
if (mood == Icon::Surprised) Voice::play(Sound::Surprise);
if (mood == Icon::Confused) Voice::play(Sound::OhOoh);
}
}How it works
- The four conditions are tested most-urgent first, so a hard shake wins over a mere tilt.
- The
next != moodguard is the key idea: it turns a continuously-true condition (you are still holding it tilted) into a single reaction, so the sound plays once on the change instead of machine-gunning every loop. -
Motion::disable()detaches the servos while you handle the robot -- no current draw, no buzzing, nothing to move by accident. The motion sensor is unaffected;Balancereads the MPU directly.
- Phone control -- drive Otto from the official Otto DIY app over Bluetooth: Bluetooth and the Otto App.
- Bench testing -- exercise each motor and sensor live from the Serial Monitor before wiring them into a sketch: Serial Console.
- The full vocabulary -- every dance move, gesture, icon, and sound: Movement and the Icon, Sound and Gesture Reference.
OttoFlow is licensed under GPL-3.0 and wraps OttoDIYLib. Buy the kits at ottodiy.com.
Prologue
Getting Started
The Basics
Digging Deeper
- Bench Testing
- Serial Console
- Calibration
- Bluetooth and the Otto App
- Modules
- The Driver
- Extending OttoFlow
Reference