Skip to content

Calibration

Ahmed Dabak edited this page Jul 24, 2026 · 2 revisions

Calibration

Introduction

No two servos rest at exactly the same angle, and no two Ottos are assembled identically. Calibration -- setting a small trim on each of the four leg servos -- is what makes your robot stand square and walk straight instead of curving off to one side.

Trims apply to the four leg and foot servos, which run through OttoDIYLib. Arm servos use the plain Servo library and are not trimmed; adjust arm angles in your own code if needed.

Why trims are needed

A trim is a permanent offset, in degrees, added to a servo before every move. If the left foot rests four degrees clockwise of true centre, a trim of -4 cancels it, and from then on "90 degrees" means the same physical pose on that servo as on the others.

Get this right once and every built-in move -- walking, turning, dancing -- inherits a straight, balanced starting point.

Calibrating with the console

The Serial Console is the intended tool: you adjust a number, the servo moves immediately, and you judge the result by eye.

> legs on
legs on
> center

center sends all four leg servos to 90 degrees -- the reference pose. Look at Otto from the front and the side. Feet flat, legs vertical, body square? If not, nudge the offending servo:

> trim -4 3 0 -2
trims set (not saved)

The four numbers are, in order: left leg, right leg, left foot, right foot. Otto moves to the new trim the instant you press Enter, so change one number, look, and repeat until the stance is clean.

When you are happy, store it:

> trim save
trims saved

That writes the trims to EEPROM, where they survive power-off and are loaded automatically on every start.

Note trim without save is temporary -- it is lost on the next reset. This is deliberate: experiment freely, and commit only the values you like.

An interactive calibration wizard -- one servo at a time with guided prompts -- is on the Roadmap.

Calibrating from a sketch

The same operations are available in code, through the Legs facade:

Legs::setTrimsDegrees(-4, 3, 0, -2);   // left leg, right leg, left foot, right foot
Legs::saveTrimsToEeprom();

You rarely need this -- the console is faster for the tuning loop -- but it is the way to bake known-good trims into a sketch, or to reset them programmatically.

How trims are stored and loaded

Saved trims live in the ATmega328's EEPROM, independent of your sketch. OttoFlow::start() loads them automatically, controlled by one setting:

OttoConfig cfg;
cfg.loadTrimsFromEeprom = true;   // the default
OttoFlow::start(cfg);

Set it to false to ignore stored trims -- useful when you want to test raw, uncalibrated behaviour, or when moving a sketch to a fresh board whose EEPROM holds someone else's numbers.

Note Trims are stored on the board, not in the sketch. Reflashing does not erase them, and moving your firmware to a different Otto does not carry them along. Recalibrate whenever you change the physical robot.

Reading the numbers

  • Positive turns the servo one way, negative the other; which way depends on how that servo is mounted. The direction does not matter as long as the stance ends up square.
  • Trims are usually small -- a few degrees. If you find yourself typing 20 or more, the horn is probably mounted a whole spline off. Pull it and reseat it, then trim the remainder.
  • The Otto DIY phone app can also send trims (its C command). They land in the same EEPROM and are honoured identically.

Clone this wiki locally