How to run servo on ESP32 with PlatformIO

I’m trying to learn to control my FS90R servo with ESP32-WROOM-32UE and PlatformIO. I’ve connected the servo to board ground, board 5v and signal to pin 14.

Here is my config:

[env:esp32]
platform = espressif32@6.5.0
board = esp32dev
framework = arduino
lib_deps =
    ESP32Servo
upload_port = /dev/ttyUSB0
monitor_speed = 115200

And here is the code:

#include <ESP32Servo.h>

static const int servoPin = 14;
Servo servo1;

int res = -99;

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

  delay(1000);
  ESP32PWM::allocateTimer(0);

  servo1.setPeriodHertz(50); // Standard 50Hz servo
  res = servo1.attach(servoPin, 1000, 2000);

  servo1.write(0);
}

void loop() {

  Serial.println("attach result");
  Serial.println(res);

  servo1.writeMicroseconds(1000);
  delay(3000);
  servo1.writeMicroseconds(2000);
  delay(3000);
}

After I upload it to the board run --target upload I can see next logs and serial output, but the servo doesn’t move at all.

================================== [SUCCESS] Took 6.96 seconds ==================================
[3/3] Starting serial monitor... (Press Ctrl+C to exit)
--- Terminal on /dev/ttyUSB0 | 115200 8-N-1
--- Available filters and text transformations: colorize, debug, default, direct, esp32_exception_decoder, hexlify, log2file, nocontrol, printable, send_on_enter, time
--- More details at https://bit.ly/pio-monitor-filters
--- Quit: Ctrl+C | Menu: Ctrl+T | Help: Ctrl+T followed by Ctrl+H
[  1016][W][ESP32Servo.cpp:84] attach(): [ESP32Servo] Attempting to Attach servo on pin=14 min=1000 max=2000
[  1027][W][ESP32PWM.cpp:339] attachPin(): [ESP32PWM] Pin Setup 14 with code 50
[  1034][W][ESP32Servo.cpp:134] attach(): [ESP32Servo] Success to Attach servo : 14 on PWM 0
attach result
0


On the other hand, the same code runs as expected after I uploaded it via Arduino IDE. On Arduino IDE side I picked ESP32-WROOM-DA as most similar board.

I see a nice square signal on oscilloscope for arduino based build and a total mess for PlatformIO on pin 14.

Any help appreciated.

This will use Espressif Arduino 2.0.14.

But the library states in it’s readme:

Specifically for the V3.0.0 of Arduino ESP32. All ADC’s have been updated to work correctly with the new release

See ESP32Servo/README.md at master · madhephaestus/ESP32Servo · GitHub

You have to use the Espressif Arduino 3.x core by using pioarduino’s espressif32-platform:

platform = https://github.com/pioarduino/platform-espressif32/releases/download/stable/platform-espressif32.zip

Note on the use of GPIO14:
GPIO14 outputs a PWM signal at boot. There might be some weird movements of the servo - See ESP32 Pinout Reference: Which GPIO pins should you use? | Random Nerd Tutorials

You are my savior! It was definitely a problem with incompatible versions. As soon as I pinned the versions, the servo started to work.

Additional thanks for pin14 note!

Here is my working config for arduino v3:

[env:esp32]
platform = https://github.com/pioarduino/platform-espressif32/releases/download/54.03.20/platform-espressif32.zip
board = esp32dev
framework = arduino
lib_deps =
    ESP32Servo@3.0.8
upload_port = /dev/ttyUSB0
monitor_speed = 115200
build_flags = -DCORE_DEBUG_LEVEL=3

and for v2:

[env:esp32]
platform = espressif32@6.5.0
board = esp32dev
framework = arduino
lib_deps =
    ESP32Servo@1.1.0
upload_port = /dev/ttyUSB0
monitor_speed = 115200
build_flags = -DCORE_DEBUG_LEVEL=3

For those who may face the same problem. To make arduino v3 work, I had to fix my local python env - remove ghosted libtorrent package, as pio run internals called some generic python python3 -m pip list --format=json --disable-pip-version-check under the hood, that failed in my case.