Skip to content

Modules

Ahmed Dabak edited this page Jul 25, 2026 · 4 revisions

Modules

Introduction

Modules are the middle of the three layers: hardware-truth names, and the place where all the real logic lives. The facades are thin sugar on top of these; the driver is raw OttoDIYLib below.

Every module is a namespace, and every function name states its meaning and unit. You have been using modules all along whenever a page said "going lower" -- this page collects them.

When to drop to the module layer

Reach past a facade to its module when you need:

  • Raw or unfiltered access -- Ultrasonic::echoMicros(), SoundSensor::rawLevel().
  • A computed direction -- LegServos::turn(1, 2000, dir) where dir is a variable.
  • Something the facade does not expose -- Matrix::drawPixel(), Buzzer::bendTonesHz().
  • Generic code -- a routine that should not care about friendly names.

For everyday sketches, stay in the facades; they read better. Modules are the escape valve one level down, before you reach for the driver.

Facade to module map

Facade Module Hardware
Mouth Matrix 8x8 MAX7219 LED matrix
Eyes Ultrasonic HC-SR04 distance sensor
Voice Buzzer, Melody Piezo buzzer
Legs, Gestures LegServos Four leg and foot servos
Arms ArmServos Two arm servos
Touch TouchSensor TTP223 touch pad
Ears SoundSensor Analog microphone
-- LightSensor Photoresistor
Balance Mpu6050 MPU-6050 motion sensor
-- Bluetooth Serial Bluetooth module
-- AppLink Otto DIY app protocol

LightSensor, Bluetooth, and AppLink have no facade -- their module names already say plainly what they are.

Matrix

The LED matrix, with pixel-level control the Mouth facade does not offer. See also Mouth.

Matrix::drawIcon(Icon::Heart);
Matrix::drawDigit(7);                  // 0..9
Matrix::drawMouthId(17);               // raw OttoDIYLib mouth index, 0..30
Matrix::drawPixel(3, 4, true);         // one LED
Matrix::drawPattern(0b0011001001000010); // raw 6x5 pattern
Matrix::scrollText("HI", 50);          // ms per step
Matrix::setBrightness(8);              // 0..15
Matrix::clear();

drawMouthId() reaches the built-in shapes that have no Icon name; drawPattern() uses the driver's raw pattern encoding, the same the phone app sends.

Ultrasonic

The distance sensor, including raw access. See also Eyes.

long cm  = Ultrasonic::distanceCm();       // filtered (config controls how)
long one = Ultrasonic::readSingleCm();     // one unfiltered reading
unsigned long us = Ultrasonic::echoMicros(); // raw pulse width, 0 = timeout
constexpr long oor = Ultrasonic::OUT_OF_RANGE_CM;  // 999

The median filter and sample count are set in config.ultrasonic -- see Configuration.

Buzzer

The piezo buzzer, plus a frequency sweep. See also Voice.

Buzzer::play(Sound::Happy);
Buzzer::playToneHz(440, 200, 50);          // freq, duration, trailing silence
Buzzer::bendTonesHz(200, 800, 1.05, 10, 1); // start, end, step, step ms, gap ms
Buzzer::mute();
Buzzer::unmute();
bool m = Buzzer::isMuted();

For bendTonesHz, a step above 1.0 sweeps up and below 1.0 sweeps down; the start and end frequencies must match that direction.

Melody

Play tunes from note tables. See also Voice.

static const uint16_t NOTES[] PROGMEM = {392, 392, 440, 392};
static const uint8_t  BEATS[] PROGMEM = {1, 1, 2, 4};
Melody::playHz(NOTES, BEATS, 4, 150);      // tables, count, ms per beat
Melody::playHappyBirthday();

A note of 0 is a rest. Keep the tables in PROGMEM to save RAM.

LegServos

The four leg and foot servos: locomotion, dance, gestures, direct control, and calibration. See also Movement.

LegServos::enable();
LegServos::disable();
LegServos::center();

LegServos::walk(2, 1000, 1);               // steps, periodMs, dir (1 fwd, -1 back)
LegServos::turn(3, 2000, -1);
LegServos::moonwalk(3, 900, 25, 1);        // cycles, periodMs, amplitude, dir
// ... bend, shakeLeg, jump, upDown, swing, tiptoeSwing, jitter,
//     ascendingTurn, crusaito, flap

LegServos::positionLegLeftDegrees(90);     // and Right / Foot variants
LegServos::positionAllDegrees(90, 90, 90, 90, 200);

LegServos::playGesture(Gesture::Victory);

LegServos::setTrimsDegrees(-4, 3, 0, -2);
LegServos::saveTrimsToEeprom();

Directions are explicit here: 1 forward or left, -1 backward or right. Use the module when your direction is a variable; use the Legs facade otherwise.

ArmServos

The two arm servos, driven by the standard Servo library. See also Arms.

ArmServos::attach();
ArmServos::detach();
bool a = ArmServos::isAttached();
ArmServos::positionLeftDegrees(140);
ArmServos::positionRightDegrees(40);
ArmServos::positionBothDegrees(90);           // same angle to both
ArmServos::positionBothMirroredDegrees(140);  // left 140, right 40
ArmServos::center();                          // both to 90
ArmServos::up();                              // left 180, right 0
ArmServos::down();                            // left 0, right 180
ArmServos::waveRight(2);
ArmServos::waveLeft(2);

Nothing happens unless arms are enabled in the configuration.

TouchSensor

The touch pad or push button. See also Sensors.

bool held    = TouchSensor::isTouched();   // current state
bool tapped  = TouchSensor::wasTapped();   // changed since last call

wasTapped() works in both momentary and toggle wiring; call it every loop.

SoundSensor

The microphone. See also Sensors.

int raw       = SoundSensor::rawLevel();               // 0..1023
uint8_t loud  = SoundSensor::loudnessPercent(50);      // peak over a window
bool isLoud   = SoundSensor::isLouderThanPercent(60, 50);

LightSensor

The photoresistor. No facade -- the name is already plain. See also Sensors.

int raw       = LightSensor::raw();                    // 0..1023
uint8_t b     = LightSensor::brightnessPercent();      // 0 dark .. 100 bright
bool dark     = LightSensor::isDarkerThanPercent(20);
bool bright   = LightSensor::isBrighterThanPercent(80);

Bluetooth

The serial Bluetooth module. See also Bluetooth and the Otto App.

bool ok = Bluetooth::begin();      // called by start() when enabled
bool ready = Bluetooth::isReady();
Stream& s = Bluetooth::stream();   // hand to Console or AppLink, or read directly

Mpu6050

The motion sensor. See also Sensors.

bool ok = Mpu6050::begin();        // called by start() when enabled
bool c  = Mpu6050::isConnected();

float x, y, z;
Mpu6050::readAccelerationG(x, y, z);   // g
Mpu6050::readRotationDps(x, y, z);     // degrees/second
float t = Mpu6050::temperatureC();

float pitch = Mpu6050::pitchDegrees();
float roll  = Mpu6050::rollDegrees();
bool level  = Mpu6050::isLevelWithinDegrees(15);
bool flip   = Mpu6050::isUpsideDown();
bool shake  = Mpu6050::isShakenHarderThanG(0.6);

AppLink

The Otto DIY app protocol handler. See also Bluetooth and the Otto App.

AppLink::begin();               // listen on the Bluetooth stream
AppLink::begin(Serial);         // or any stream
AppLink::poll();                // every loop iteration

Clone this wiki locally