A kick to start
A stopped motor needs more to start than to keep turning. So give it 255 for 50 ms, then drop to the level you want: it is already spinning, and a level too low to start it can still keep it going. The kick is usually too short to notice. How low your motor will keep turning is found by trying it.
Starting takes more than turning
A motor at rest has to overcome the friction of standing still, which is larger than the friction of turning. The motor's datasheet guarantees a start only from 2.3 V. Once it is turning, momentum helps, and it needs less.
Play it both ways. Written straight at 100 of 255 from rest, about 1.3 V on the motor, it may sit still: current flows through the winding, and nothing moves. Given 255 for 50 ms first, it spins up, and then 100 only has to keep it going. Whether your unit keeps going at 100 is not something the datasheet says. The traces are illustrative.
The kick in a sketch
setLevel(level) remembers whether the motor is running. From rest, and only
from rest, it writes 255, waits KICK_MS, then writes the level asked for.
From running it writes the level straight away. setLevel(0) stops it.
50 ms is a starting point. The datasheet gives no spin-up time for this motor, so the number is a guess, and it is a named constant so that you can change it.
Finding the floor
Run the sketch and watch the LED and your fingertip. The LED shows every level, dimmer as it goes down, because it follows the MOSFET. The motor shows whether it kept turning. The lowest level that keeps it going after the kick is this unit's floor; another unit may differ, so leave a margin above it.
The code
setLevel(level) sets any strength from 0 to 255 and, if the motor was stopped, runs it at 255 for KICK_MS first. The loop tries three levels, each from rest.
/*
Vibration Motor - kick-start for low levels TK30 / /p/tk30
Wiring. Count from the square pad on the TinkerBlock board, parts
up, header at the bottom:
GND -> GND
VCC -> 5V: an Uno's 5V, the 5V pin of an ESP32 or ESP32-S3
board on USB, a Pico's VBUS (3V3 works as well)
NC -> nothing (unconnected on the board)
SIGNAL -> a PWM pin: D9 on an Uno, GPIO 4 on an ESP32 or
ESP32-S3, GP15 on a Raspberry Pi Pico
Arduino IDE
Tools > Board your board, e.g. Arduino Uno
Tools > Port the one that appears when you plug in
Tools > USB CDC On Boot Enabled (ESP32-S3 only)
No library needed. ESP32 boards need board package 2.0 or later.
*/
// A PWM pin.
// Uno: 9. ESP32: 4. ESP32-S3: 4. Pico: 15.
const int MOTOR_PIN = 9;
const int KICK_MS = 50; // full power first: a guess, tune it
bool running = false;
// Any strength, 0 to 255. From rest, kick it first.
void setLevel(int level) {
if (level > 0 && !running) {
analogWrite(MOTOR_PIN, 255);
delay(KICK_MS);
}
analogWrite(MOTOR_PIN, level);
running = level > 0;
}
void setup() {
Serial.begin(115200);
pinMode(MOTOR_PIN, OUTPUT);
}
void loop() {
const int tries[] = {150, 100, 70};
for (int level : tries) {
Serial.print("level ");
Serial.println(level);
setLevel(level);
delay(1500);
setLevel(0);
delay(1000);
}
}If the motor keeps turning at 150 and 100 but not at 70, your unit's floor is somewhere between 70 and 100. Any level above that works from rest with the kick, where without it you would need about 178.
The same kick in MicroPython. set_level takes the same 0 to 255 as the Arduino sketch and converts it for duty_u16.
"""
Vibration Motor - kick-start, MicroPython TK30 / /p/tk30
Wiring. Count from the square pad on the TinkerBlock board, parts
up, header at the bottom:
GND -> GND
VCC -> 5V: the 5V pin of an ESP32 or ESP32-S3 board on USB,
a Pico's VBUS (3V3 works as well)
NC -> nothing (unconnected on the board)
SIGNAL -> GPIO 4 on an ESP32 or ESP32-S3, GP15 on a Raspberry
Pi Pico
Thonny
Run > Configure interpreter MicroPython (ESP32) or
MicroPython (Raspberry Pi Pico)
Save it to the board as main.py to run it on every power-up.
Nothing to install: machine and time are built in.
"""
import time
from machine import Pin, PWM
# A PWM pin. ESP32: 4. ESP32-S3: 4. Pico: 15.
MOTOR_PIN = 4
KICK_MS = 50 # full power first: a guess, tune it
motor = PWM(Pin(MOTOR_PIN), freq=1000)
motor.duty_u16(0)
running = False
def set_level(level):
"""Any strength, 0 to 255. From rest, kick it first."""
global running
if level > 0 and not running:
motor.duty_u16(65535)
time.sleep_ms(KICK_MS)
motor.duty_u16(level * 257)
running = level > 0
while True:
for level in (150, 100, 70):
print("level", level)
set_level(level)
time.sleep_ms(1500)
set_level(0)
time.sleep_ms(1000)time.sleep_ms blocks for the kick, 50 ms, which is short enough not to matter in most sketches. The global running flag remembers whether the motor is turning, so a change of level while it runs is not kicked again.
When it does not work
The level is below what this unit needs to keep turning. Raise it until it keeps going; the datasheet does not publish that floor, so it is found by trying. Below it, use full power and switch it on and off instead.
50 ms is a starting point, not a datasheet number: the motor's specification gives no spin-up time. If a low level stops after the kick, try 80 or 100 ms. If the start feels like a separate thump, shorten it.
It only kicks when the motor was stopped. A running motor does not need one, and kicking it on every change would make each change in strength start with a burst at full power.
Tap, double, long and alarm, played on a button press without stopping the sketch.
Patterns you can feel →Edit this page — content/books/vibration-motor/a-kick-to-start.mdx
Questions about this product
See what other owners have asked, and read their solutions.
Vibration Motor
Loading discussions…
Discuss this article
Ask about this page. The answer stays here, on the page it belongs to, for whoever hits the same wall next.