vibration motor/Driving it/07. Strength is a duty cycle
Driving it · 07 of 10

Strength is a duty cycle

analogWrite switches SIGNAL on and off hundreds of times a second, and the motor settles at the average: 128 of 255 is about 1.66 V from the 3.3 V rail. Speed, and so shake, fall with it. Below about 178 of 255, about 2.3 V, a stopped motor is not guaranteed to start at all.

On and off, very quickly

A digital pin is only ever HIGH or LOW. analogWrite(pin, 128) does not put half a voltage on SIGNAL. It switches the pin fully on and fully off, over and over, with the on part half of each cycle. That fraction is the duty cycle, 0 for always off to 255 for always on, and the technique is PWM, pulse-width modulation.

On an Uno's pin 9 the cycle repeats 490 times a second. The ESP32, ESP32-S3 and Pico cores use 1000 by default. The MOSFET follows every edge; the motor cannot. Its winding and the diode smooth the pulses into an average, and the motor turns as if it were given that average.

Strength is a duty cycle
analogWrite(MOTOR_PIN, …)128
Duty
50 %
Motor, average
1.66 V
From rest
may not start
Shake vs full
below the curve
128 of 255 averages about 1.66 V. That is under the 2.3 V the datasheet guarantees a start from, so a stopped motor may just sit and hum. Already spinning, it may keep going. Start it at 255 and then drop to 128: the next article.

Drag the level. The bar is the average on the motor: the duty times the rail, 3.3 V from 5V or 3V3 on VCC alike. The red line is 2.3 V, the voltage the motor's datasheet guarantees a start from, and the shaded band is its working range, 2.7 to 3.3 V. The figure's numbers are calculated from that simple model.

Where it stops starting

With the motor's 3.3 V, from 5V or 3V3 on VCC, 2.3 V is about 178 of 255, 70 % duty. Above that, any motor of this type starts from rest. Below it the datasheet promises nothing: some units start at lower levels, some hum and sit still. A motor that is already turning keeps going below its starting level, because it no longer has to overcome the friction of standing still. How far below is not published.

Strength is not a straight line

The datasheet's typical curve puts the speed at about 12,700 rpm at 2.6 V and about 15,800 at 3.3 V. The shake from an off-centre weight grows with the square of its speed. So from full power down to 2.6 V the shake falls by about a third, and below that the curve stops and the motor soon may too. In practice a vibration motor has three useful settings: off, full, and a lower level that you have tried on the unit in your hand.

The code

Steps through four levels from rest, a second each with a second off between, and prints each. Change MOTOR_PIN to the PWM pin you wired SIGNAL to.

motor_strength.ino
/*
  Vibration Motor - strength with analogWrite           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. ESP32S3 Dev Module
    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;

// 0 is off, 255 is full. From full to below the start line.
const int LEVELS[] = {255, 200, 150, 100};

void setup() {
  Serial.begin(115200);
  pinMode(MOTOR_PIN, OUTPUT);
}

void loop() {
  for (int level : LEVELS) {
    Serial.print("level ");
    Serial.println(level);
    analogWrite(MOTOR_PIN, level);   // from rest, every time
    delay(1000);
    analogWrite(MOTOR_PIN, 0);       // off, and let it stop
    delay(1000);
  }
}

255 and 200 always start; 150 and 100 are below the 178 the datasheet's start voltage asks for, so they may or may not, depending on the unit. Whatever yours does at 100 from rest, it is not a fault. The LED dims with the level.

When it does not work

analogWrite(MOTOR_PIN, 128) does nothing.

128 averages about 1.66 V, well under the 2.3 V the motor's datasheet guarantees a start from. A motor already turning may keep going at that level; one at rest may just hum. Start it at 255 and then drop, which is the next article.

The motor whines at low levels.

That can be the PWM itself: the motor's winding moves a little at the switching rate, 490 times a second on an Uno's pin 9 and 1000 on the others. It does no harm. Use full on and off for silence, or change the PWM frequency if your core allows.

analogWrite does nothing on my pin.

The pin may not be PWM-capable. On an Uno only pins 3, 5, 6, 9, 10 and 11 are. On the ESP32 boards and the Pico nearly every output pin is. On an ESP32, analogWrite needs board package 2.0 or later.

Half of 255 does not feel half as strong.

It would not. The shake from a spinning off-centre weight grows with the square of its speed, the speed falls with the voltage, and below about 2.3 V the motor may not turn at all. Choose levels by feel, from 255 down to wherever it stops starting.

Where this goes next

Full power for a moment, then the level you wanted: low levels that always start.

A kick to start

Edit this page — content/books/vibration-motor/strength-is-a-duty-cycle.mdx

Community

Questions about this product

See what other owners have asked, and read their solutions.

Ask a question ↗

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.

Browse Modules and blocks on the forum