logo elektroda
logo elektroda
X
logo elektroda

[Solved] Servo movement range limited to 90 degrees with NodeMCU V2 - potentiometer control

Krismir102 3387 15
ADVERTISEMENT
Treść została przetłumaczona polish » english Zobacz oryginalną wersję tematu
  • #1 19599292
    Krismir102
    Level 5  
    Posts: 15
    Rate: 1
    Hello. I apologise in advance for my inexperience but this is my first attempt at servo control with the NodeMCU V2. Right at the start I hit a problem that I don't understand. With simple code I want to control the servo with a potentiometer, but the servo only moves around 90 degrees (roughly from 45 to 135). The same thing happens when I upload the "Swap" example from the Servo.h library.
    I don't understand what I've done wrong, the current is rather not missing, the grounds are common, I've connected the potentiometer to 5V as well as 3.3V, and I've also controlled the servo via a transistor and connected it to different pins, I've copied examples and schematics from the internet.... still the same. On the serial monitor the values from the potentiometer show me 13-1024, which is rather ok. The cat variable also operates between 2 and 180.

    I also connected the MG90 servo and it behaved identically.
    After plugging everything into an Arduino Uno and uploading the same code, everything works as expected so it's more of a NodeMCU thing.

    I was wondering if maybe it's the Servo.h library that works badly with the ESP8266 but in all the examples I've found people are using it successfully. I installed older versions of Servo.h but that didn't help either.

    I am using a NodeMCU V2, an MG995 servo and a 10k potentiometer.

    I have included a link to the video and a screen shot of the code below:

    https://www.youtube.com/watch?v=UPR1Ny_D6Fo

    Servo movement range limited to 90 degrees with NodeMCU V2 - potentiometer control .
  • ADVERTISEMENT
  • #2 19599308
    Anonymous
    Level 1  
  • ADVERTISEMENT
  • #3 19599322
    Krismir102
    Level 5  
    Posts: 15
    Rate: 1
    khoam wrote:
    Krismir102 wrote:
    I was wondering if maybe it's the Servo.h library that malfunctions with the ESP8266
    .
    Which specific library is this referring to? Link?
    .

    https://www.arduino.cc/reference/en/libraries/servo/

    I also noticed that ESP isn't there, but all the tutorials on connecting servo to Node that I found use it. At least it seems that way to me because in every code (on ESP too) it is included:
    #include <Servo.h>
    If this is the incorrect library then I have no idea what other library to use.
  • #4 19599327
    Anonymous
    Level 1  
  • ADVERTISEMENT
  • #5 19599352
    Krismir102
    Level 5  
    Posts: 15
    Rate: 1
    khoam wrote:
    Arduino Core for ESP8266 already has its own Servo library bundled and there is no need to install an additional one in the Arduino IDE (best to uninstall it).
    Link
    .

    There is indeed a library for ESP with servo. I removed the one there. Unfortunately after uploading the example from the library you are talking about the servo behavior did not change.
  • #6 19599358
    Anonymous
    Level 1  
  • #7 19599365
    Krismir102
    Level 5  
    Posts: 15
    Rate: 1
    khoam wrote:
    Try running the "Sweep" example from this library: Link .
    You need to match the GPIO number to your configuration.


    Unfortunately, it continues to do the same thing. It does not rotate more than within 90 degrees. It appears that I have the library correct.
  • #8 19599367
    Anonymous
    Level 1  
  • #9 19599376
    Krismir102
    Level 5  
    Posts: 15
    Rate: 1
    khoam wrote:
    How is the servo connection via this transistor? What kind of transistor is it? Maybe post a schematic, even a handwritten one.
    .

    The transistor was an act of desperation and I have already removed it. I now have the signal wire from the servo directly connected to a pin in the Node.

    But if you want to know it looked like this:
    Servo movement range limited to 90 degrees with NodeMCU V2 - potentiometer control .
  • #10 19599388
    Anonymous
    Level 1  
  • ADVERTISEMENT
  • #11 19599462
    Krismir102
    Level 5  
    Posts: 15
    Rate: 1
    khoam wrote:
    The MG995 requires a PWM signal with an amplitude of 5V at the control input, from the ESP8266 pin is 3V3.


    I checked with a logic state analyser the PWM signal that the Node provides. It is exemplary. I have now routed the control signal through the optocoupler and checked, it is 5V. On the power supply when the servo moves, the voltage drops from 5V to 4.8V.
    Unfortunately, the servo still moves in a limited range. Everything is working and it is not working.... Maybe some interference?
  • #12 19599605
    Anonymous
    Level 1  
  • #13 19600301
    Krismir102
    Level 5  
    Posts: 15
    Rate: 1
    Ha! Problem solved. Something amazing. It turns out that everything works as it should just that the servo library from the ESP environment is feeding the PWM signal TOO ACCURATE. I discovered this with a logic state analyser, with which I checked the PWM signal fed through the Node and the Arduino Uno. I recall that on the Node the servo moved in a limited range and on the Uno in a full range. The library from the Node generated a downright exemplary PWM signal, with the shortest fill time of 1 ms and the longest of 2 ms, and all to the nearest hundredth of a ms. The library from Uno generated a PWM signal with a shortest fill time of 0.5 ms and a longest of about 2.4 ms!!!! At least both agree on the 20 ms period. I installed the older ESP8266 environment library and suddenly everything started working! After reading the PWM waveform, it appeared to me that now my Node, on the older library, generates a signal with a fill range of 0.5 ms to 2.4 ms over a 20 ms period. In this fill range, 1 ms for my servo is about 75 degrees, and 2 ms is about 150 degrees. And indeed, that is about the extent to which it was moving for me. It is a pity that the documentation I came across gives the correct fills as 1 ms and 2 ms.... I don't know about other servo models, but the Tower Pro SG90 and MG995 servos require the ESP8266 environment library version 2.7.4 or older. Versions 3.0 and later generate an inappropriate PWM signal for these servos. Below is a graphic showing how my servo works. Probably in a 200 zł servo and some of the latest ones this problem will not occur, but mine for three grand from allegro has such requirements ;) . Servo movement range limited to 90 degrees with NodeMCU V2 - potentiometer control . Servo movement range limited to 90 degrees with NodeMCU V2 - potentiometer control .
  • #14 19600557
    Anonymous
    Level 1  
  • #15 19600652
    Krismir102
    Level 5  
    Posts: 15
    Rate: 1
    khoam wrote:
    There is a version of the attach () function in the Servo library with additional arguments that allow you to specify a minimum and maximum duty cycle. Actually, the default is 1000us and 2000us in Core 3.0, but this can be changed just with the attach() function:
    Code: C / C++
    Log in, to see the code
    A version of this function is available from Core 2.7.3.
    Link .

    Krismir102 wrote:
    It turns out that everything works as expected only that the library for the servo from the ESP environment is giving the PWM signal TOO ACCURATE.
    .
    This is the value specified by the author of the code, as " uncalibrated default ". The aforementioned attach() function is used for calibration.
    .

    O good to know about this function I will definitely test it. Thanks for your help and time, I close the topic ;) .
  • #16 19600656
    Krismir102
    Level 5  
    Posts: 15
    Rate: 1
    khoam wrote:
    There is a version of the attach () function in the Servo library with additional arguments that allow you to specify a minimum and maximum duty cycle. Actually the default is 1000us and 2000us in Core 3.0, but this can be changed just with the attach() function:
    Code: C / C++
    Log in, to see the code
    A version of this function is available from Core 2.7.3.
    Link .

    Krismir102 wrote:
    It turns out that everything works as expected only that the library for the servo from the ESP environment is giving the PWM signal TOO ACCURATE.
    .
    This is the value specified by the code author as " uncalibrated default ". The aforementioned attach() function is used for calibration.
    .

    O good to know about this function I will definitely test it. Thanks for your help and time, I close the topic ;) .

    Added after 2 [minutes]:

    Ha! Problem solved. Something amazing. It turns out that everything works as it should just that the library for the servo from the ESP environment is giving the PWM signal TOO much.
    I discovered this with a logic state analyser, with which I checked the PWM signal fed through the Node and the Arduino Uno. I recall that on the Node the servo moved in a limited range and on the Uno in a full range.
    The library from the Node generated a downright exemplary PWM signal, with the shortest fill time of 1 ms and the longest of 2 ms, and all to the nearest hundredth of a ms. The library from the Uno generated a PWM signal with a shortest fill time of 0.5 ms and a longest of about 2.4 ms!!!! At least both agree on the 20 ms period.
    I installed the older ESP8266 environment library and suddenly everything started working! After reading the PWM waveform, it appeared to me that now my Node, on the older library, generates a signal with a fill range of 0.5 ms to 2.4 ms over a 20 ms period. In this fill range, 1 ms for my servo is about 75 degrees, and 2 ms is about 150 degrees. And indeed, that is about the extent to which it was moving for me.

    It is a pity that the documentation I came across gives the correct fills as 1 ms and 2 ms....

    I don't know about other servo models, but the Tower Pro SG90 and MG995 servos require the ESP8266 environment library version 2.7.4 or older. Versions 3.0 and later generate an inappropriate PWM signal for these servos.

    Probably in a 200 PLN servo and some of the latest ones this problem will not exist, but my 3 grand servo from Allegro has such requirements

    EDIT
    On newer libraries, the problem is also solved by using the command that a colleague recommended above:
    servo.attach(pin, min, max);
    Where for min we enter 544 and for max 2400

    Servo movement range limited to 90 degrees with NodeMCU V2 - potentiometer control Servo movement range limited to 90 degrees with NodeMCU V2 - potentiometer control

Topic summary

✨ The discussion revolves around a user's challenge in controlling a servo motor with a NodeMCU V2 using a potentiometer, where the servo only moves within a limited range of approximately 90 degrees. The user initially attempted various connections and libraries, including the Servo.h library, but faced persistent issues. Responses highlighted that the ESP8266 has its own bundled Servo library, which the user confirmed was correctly installed. After troubleshooting, including checking PWM signals and power supply issues, the user discovered that the newer library generated a PWM signal that was too precise, limiting the servo's range. By reverting to an older version of the ESP8266 library, the user successfully resolved the issue, allowing the servo to operate correctly across its full range. Additionally, a suggestion was made to use the attach() function with custom duty cycle parameters for further calibration.
Generated by the language model.

FAQ

TL;DR: If your NodeMCU V2 servo only sweeps ~90°, calibrate pulses to 0.5–2.4 ms; fix with "min=544, max=2400". [Elektroda, Krismir102, post #19600656]

Why it matters: This FAQ helps ESP8266/NodeMCU users quickly fix limited servo travel (SG90/MG995) when controlling via a potentiometer.

Quick Facts

Why does my NodeMCU V2 servo only move about 90 degrees?

ESP8266 Core 3.x’s Servo library defaults to a 1000–2000 µs window. Many SG90/MG995 interpret this as mid‑range only. The author called it an "uncalibrated default". Set explicit min/max microseconds to match your servo’s needs. That expands travel beyond ~90°. [Elektroda, khoam, post #19600557]

How do I fix the 90° limit on ESP8266/NodeMCU?

Use the ESP8266 Servo library and set wider pulse widths.
  1. Include Servo.h from the ESP8266 core.
  2. Call servo.attach(GPIO, 544, 2400).
  3. Map your potentiometer to 544–2400 µs and write microseconds. This restored full sweep on SG90/MG995. [Elektroda, Krismir102, post #19600656]

Which Servo library should I use with ESP8266?

Use the Servo library bundled with the ESP8266 Arduino core. Uninstall any extra Arduino Servo.h to avoid conflicts. "Arduino Core for the ESP8266 already has its own Servo library." Set the correct GPIO number in your code. [Elektroda, khoam, post #19599327]

Do I need a 5 V logic signal to drive an MG995 from ESP8266?

A contributor noted the MG995 expects a 5 V PWM control signal, while ESP8266 outputs 3.3 V. If 3.3 V is unreliable, use a level shifter or an optocoupler. Then calibrate pulse widths for range. [Elektroda, khoam, post #19599388]

I shifted the signal to 5 V and it still only moves ~90°. Why?

Because the problem is the pulse window, not just logic level. The 5 V control via an optocoupler didn’t change the limited range. Full travel appeared only after widening pulses via attach(min,max). [Elektroda, Krismir102, post #19599462]

What PWM timings give full travel on SG90 or MG995?

Full sweep was achieved around 544–2400 µs within a 20 ms period. The author summarized the fix as "min=544, max=2400" using attach(). This aligns the ESP8266 output with what these servos expect. [Elektroda, Krismir102, post #19600656]

How do I map a potentiometer to servo microseconds on NodeMCU?

Read the pot (0–1024; observed 13–1024 is fine). Map your measured min and max to 544–2400 µs. Write the mapped value using writeMicroseconds(). This uses the full knob travel within your configured pulse window. [Elektroda, Krismir102, post #19599292]

Can downgrading the ESP8266 core fix the servo range?

Yes. Installing Core 2.7.4 made the Node output ~0.5–2.4 ms pulses by default. That restored full range similar to Arduino Uno behavior. You can also stay on 3.x and set attach(min,max). [Elektroda, Krismir102, post #19600301]

Why does Arduino Uno sweep fully but ESP8266 doesn’t?

Measured signals showed the Uno generating ~0.5–2.4 ms by default. ESP8266 Core 3.x produced 1.0–2.0 ms at the same 20 ms period. The wider Uno window yields full travel; the narrower ESP window limits motion. [Elektroda, Krismir102, post #19600301]

Which GPIO pin should I use for the servo on NodeMCU?

Pick a suitable GPIO and pass its number to attach(). The ESP8266 Servo "Sweep" example reminds you to match the GPIO to your wiring. Ensure your code uses the correct pin numbering. [Elektroda, khoam, post #19599358]

My serial monitor shows 13–1024 from the potentiometer. Is that normal?

Yes. Analog readings rarely hit exact 0. Use your measured endpoints, like 13 and 1024, for mapping. Then scale to your chosen microsecond range. This avoids dead zones and maximizes usable travel. [Elektroda, Krismir102, post #19599292]

What is the exact attach() signature for setting min/max on ESP8266?

Use the overload: "uint8_t attach(int pin, uint16_t min, uint16_t max);" Pass microseconds for min and max. This API is available starting with Core 2.7.3. It is the intended calibration method. [Elektroda, khoam, post #19600557]
Generated by the language model.
ADVERTISEMENT