Arduino Uno R4 Servo PWM changing in 100µs increments

I have tried running at 8V, 12V, and 16V, and I am reporting the PWM signal out to serial and monitoring it, so I know that my code is sending out the PWM signal increasing by 2 every 200ms.

It starts at 1600 since that is where my motor deadband stops (much more than advertised?) and ramps to 1800, then after a pause ramps back down to 1600 pause, and repeat.

However, the pitch of the motor and its rpm (read thrust) remains constant from 1600 to 1699 microseconds, and then jumps up at 1700, then constant to 1799, and jumps up at 1800. Same behavior on the way down.

Can someone help me figure out why I am not ramping, I am stepping in 100 microsecond increments? I am no arduino wiz, but it seems like if the “motorSpeed” PWM value is changing and being sent to the ESC, the motor RPM should change at the same rate?

Thanks in advance!

Simple arduino code included below for reference:

#include <Servo.h>

byte servoPin1 = 9;
int motorSpeed;
Servo servo;

void setup() {
  Serial.begin(38400);
  servo.attach(servoPin1);
  servo.writeMicroseconds(1500);
  delay(7000); // Initializing Thruster
}

void loop() {
  //ramp up: initial power level 1600uS FWD
  for(motorSpeed = 1600; motorSpeed <= 1800; motorSpeed = motorSpeed + 2){
    servo.writeMicroseconds(motorSpeed);
    Serial.println("Speeding Up - ");
    Serial.println("Current PWM value:");
    Serial.println(motorSpeed);
    delay(225);
  }

  //sit there for a sec
  Serial.println("Pause High Speed");
  delay(5000);

  //ramp down: initial power level 1800uS FWD
  for (motorSpeed = 1800; motorSpeed >=1600; motorSpeed = motorSpeed - 2){
    servo.writeMicroseconds(motorSpeed);
    Serial.println("Slowing Down - ");
    Serial.println("Current PWM value:");
    Serial.println(motorSpeed);
    delay(225);
  } 

 //sit there for a sec
 Serial.println("Pause Low Speed");
 delay(5000);
}

Hi @Reef_Engineer -
It seems like you have an issue in your code. Have you tried our example to verify that your hardware functions as expected? You could manually send the speeds you’re interested in and see if the behavior is the same… The 1600 center point is alarming!

As for your code - the Servo-Style PWM signal is sent as a pulse every 20ms. Using the delay() function in your for loops may be related to your issue - perhaps you could accomplish the timing with a non-blocking function?

Hi @tony-white ! thanks for the response!

I did try your example code, with minor mods (pasted below):

of note, the motor dead band is still roughly 1400-1600. Then I can watch the potVal and the pwmVal and they change as one would expect. However, the motor RPM only changes at 1600, 1700, 1800, 1900 (and same behavior in reverse with 1400, 1300, 1200, 1100).

so the correct pwmVal is being sent, with no delays, and it is still not ramping smoothly, but jumping to 4 discrete forward RPMs and 4 discrete reverse RPMs.

Code here:

#include <Servo.h>

byte servoPin1 = 9;
byte potentiometerPin = A0;
Servo servo;

void setup() {
  Serial.begin(38400);
  servo.attach(servoPin1);
  servo.writeMicroseconds(1500);
  delay(7000);
}

void loop() {
  int potVal = analogRead(potentiometerPin);
  int pwmVal = map(potVal,0, 1023, 1100, 1900);
  servo.writeMicroseconds(pwmVal);
  Serial.println(pwmVal);
  Serial.println(potVal);
}

Hi @Reef_Engineer,

Given this is repeatable for you, it sounds like some kind of quantisation issue with the clock being used for the output timings, or the ESC has the wrong clock component or something.

I would guess that your board is only changing the pulse duration in 100µs increments, which you should be able to check by connecting some other peripheral that accepts servo-style inputs (e.g. a servo motor, or a different ESC), or an oscilloscope.

Which board type are you running the code on? It might help to try

  1. running on a different pin, and/or
  2. seeing if you can run a more direct PWM sweep without using the servo library (or at least seeing whether it’s possible to change which timer is being used for the library), and/or
  3. removing the serial communications, in case there’s some kind of timer interference
    • this seems unlikely to me

If you have an alternative board type you can test with, or a servo tester, then you should be able to independently check whether it’s the ESC that’s the problem. If it does turn out to be the ESC then please fill out the “report a problem with a product” form on our contact page, and we should be able to send you a replacement :slight_smile:


By the way, I’ve edited your posts to have the code in code blocks, so it’s easier for others to read, and to copy for testing. You can read about how to do that (and more) in the How to Use the Blue Robotics Forums post :slight_smile:

1 Like

Hi Eliot! thank you for your response.

I tried #1 without change (different pin on the Arduino Uno R4 wifi).
I tried using servo position 95-180 instead of sending uS, but no change, still 4 discreet speed steps. (here i monitored the position being sent at first and it is a smooth transition from 95-180 and back)
I tried removing all serial coms but no change in behavior.
I tried removing all delays and the steps just happen faster.

I am just getting into this so unfortunately have no other ESCs or boards to test with but I guess that is the next step. I would not be opposed to trying a different ESC so maybe ill reach out on the contact page.

Thank you for the info on how to correctly post code!

I will tinker more today and let you know if I get anywhere

1 Like

@EliotBR @tony-white Ok, discovery made. I have a Thruster Commander. when I hook it all up through the thruster commander, I have all RPMs available to me (smooth ramping as I adjust the potentiometer. So the question is, why in the world is my Arduino not sending the same control signals to the ESC as the Thruster Commander is?? It is displaying that it is sending uS signals with every value from 1600-1900. The plot thickens…

Good news is that the ESC and motor are good to go. Bad news is I need to work out why the Arduino is being wack. Problem is I need automated and variable programmability, so that means I cant just use the thruster commander long term.

Any ideas? I’ll keep tinkering…

one thought, could it somehow be only reading the first two significant digits of the pwm signal somehow? That would explain changing at those multiples of 100?

Hi @Ben -
That’s not actually how the PWM signal works! It could be related to the variable type you’re using to hold the throttle value, in terms of rounding / significant digits. But the signal itself is a pulse, 1 to 2 milliseconds in length, send every 20 milliseconds.
I would recommend using an oscilloscope to look at the signal from the Arduino, the problem is almost certainly in your code. The weird part to me is that our default code apparently exhibits the same behavior for you? This may suggest the issue is with the Arduino hardware itself?

@tony-white agreed. I was thinking it might be the variable i was setting as the pwm length, but i tried several with no improvement.

Also it showed the same behavior with your arduino code, so i think its something with my arduino. Ill dig into it some tonight.

Thanks again for your time!

Arduino uno R4 wifi problem

Well, there you go. Its a known issue on this new arduino, and not fixed yet i dont think.

So for all others out there using arduino uno r4 wifi, its not you, its not your code, its your arduino.

1 Like

From the thread you linked to, there’s apparently a pull request to the Servo library that fixes it, which is already merged in to the master (development) branch of the library, but has not yet been released in a version[1], so it’s not available via the Arduino Library Manager’s online listings.

If you install the library manually from the code in GitHub then it should work.
I believe the simplest way of doing that is to download the code from the GitHub repository (click the green “Code” button, then “Download ZIP”), then import that into your Arduino IDE.


  1. The last release was in June last year, whereas the pull request was only merged this January. ↩︎

1 Like

@EliotBR thank you for the guidance, i did it and the test code worked! Problem fixed. Epic.

Let the project continue!

Thanks for the help to all that chimed in. Hopefully it assists someone else with that arduino model!

2 Likes