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.
| Setting | What it does |
|---|---|
| Pin | one pin carrying both angles |
| Split mode | two 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.
#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
| Problem | Check |
|---|---|
| Nothing arrives | the switch on the widget is off, or the pin does not match PLYNX_WRITE() |
| Robot creeps when the phone is still | no dead zone in your code |
| Only one axis responds | split mode is on but the sketch reads param[0..1] |
| Values arrive as whole numbers | the handler uses asInt() instead of asFloat() |