Docs

Tilt

The Tilt widget sends how far your phone is tilted, as two angles in degrees: pitch (forward and back) and roll (left and right).

Use it for: steering a robot by tilting, aiming a pan and tilt head, levelling something, a control you use without looking at the screen.

SettingWhat it does
Pinone pin carrying both angles
Split modetwo pins, pitch on one and roll on the other

Open these from the canvas: tap Edit, then long press the widget and choose Configure.

The widget has a switch on its face. Nothing is sent until you turn it on, and it goes back off when you leave run mode, so a phone in your pocket cannot drive anything by accident.

What the numbers are

Both values are degrees with one decimal, and both can be negative: 0.0 is flat, and the sign tells you which way it leaned. A phone tilted right sends a positive roll.

The bubble drawn on the widget stops moving at 45 degrees, but the value keeps going past it.

Example

Tilt steering for a two motor robot, both angles on V34.

tilt.ino
#include <PlynxSimpleEsp32.h>

// Below this many degrees the phone counts as flat. Without it a robot
// creeps while the phone sits still in your hand.
#define DEAD_ZONE 4.0

// Tilt this far means full speed. Past it the value is clamped.
#define FULL_TILT 30.0

int axisToSpeed(float degrees)
{
  if (fabs(degrees) < DEAD_ZONE) return 0;
  float ratio = constrain(degrees / FULL_TILT, -1.0, 1.0);
  return (int)(ratio * 255);
}

// Merged mode sends both angles in one message.
PLYNX_WRITE(V34)
{
  float pitch = param[0].asFloat();   // forward and back
  float roll  = param[1].asFloat();   // left and right

  int speed = axisToSpeed(pitch);
  int turn  = axisToSpeed(roll);

  driveMotors(speed + turn, speed - turn);
}

void setup()
{
  Serial.begin(115200);

  // Auto setup: WiFi and the Plynx token are configured from the app.
  //
  // To provide them directly in the sketch instead, use:
  //   Plynx.begin(auth, ssid, pass);
  Plynx.begin();
}

void loop()
{
  Plynx.run();
}

param[0] is pitch and param[1] is roll. Read them with asFloat(), because asInt() throws away the decimal.

The dead zone matters more here than on a Slider. A hand is never perfectly still, so without one the robot drifts whenever you stop steering.

Split mode

Turn on Split mode and the widget asks for two pins instead of one. Each handler then reads a plain value:

PLYNX_WRITE(V34) { setSpeed(axisToSpeed(param.asFloat())); }   // pitch
PLYNX_WRITE(V35) { setTurn(axisToSpeed(param.asFloat())); }    // roll

In split mode you can leave one axis without a pin. A self levelling platform that only cares about side to side sets roll and leaves pitch empty, instead of burning a virtual pin on a value it ignores.

How often it sends

At most five times a second, and only when an angle has moved more than half a degree. Holding the phone steady sends nothing at all.

That is already gentle on the link, so the thing to keep short is your handler. Add a safety timeout as well: if nothing arrives for a second, stop the motors. A dropped connection otherwise leaves the last speed running.

Troubleshooting

ProblemCheck
Nothing arrivesthe switch on the widget is off, or the pin does not match PLYNX_WRITE()
Robot creeps when the phone is stillno dead zone in your code
Only one axis respondssplit mode is on but the sketch reads param[0..1]
Values arrive as whole numbersthe handler uses asInt() instead of asFloat()

Next