Servo.h Can I change the frequency?

Hello everyone,

I am using an STM32 in the Arduino IDE to build a drone. It flies well but I would like to increase the update rate to the Servos and ESCs from 50Hz to 100Hz (maybe higher in the future). They are digital servos and multicopter ESCs so should be able to handle anywhere up to ~250Hz.

My thought at the moment is I go into the hardware folder, then to the STM32 folder, then the F103C series board folder and edit the Servo.cpp file contained within it.

#include "Servo.h"

#include <boards.h>
#include <io.h>
#include <pwm.h>
#include <wirish_math.h>

// 20 millisecond period config.  For a 1-based prescaler,
//
//    (prescaler * overflow / CYC_MSEC) msec = 1 timer cycle = 20 msec
// => prescaler * overflow = 20 * CYC_MSEC
//
// This picks the smallest prescaler that allows an overflow < 2^16.
#define MAX_OVERFLOW    ((1 << 16) - 1)
#define CYC_MSEC        (1000 * CYCLES_PER_MICROSECOND)
#define TAU_MSEC        20
#define TAU_USEC        (TAU_MSEC * 1000)
#define TAU_CYC         (TAU_MSEC * CYC_MSEC)
#define SERVO_PRESCALER (TAU_CYC / MAX_OVERFLOW + 1)
#define SERVO_OVERFLOW  ((uint16)round((double)TAU_CYC / SERVO_PRESCALER))

Would I be right in thinking that changing:

#define TAU_MSEC 20
to
#define TAU_MSEC 10

would yield the results I'm after? I'm not sure if there is anything else I need to be editing or secondary effects of changing this value.

Any thoughts would be appreciated. Thanks.

jaddion82052:
the update rate to the Servos and ESCs from 50Hz to 100Hz

That's the frequency, not the duty cycle.

The duty cycle is what changes to tell the servo what angle to adapt - using Servo.write() or Servo.writeMicroseconds()

...R

Can you update the sender and receiver in the same way?

20ms is the usual frame that can contain up to 8 (9?) channels. Shorter frames can not contain that many channels.

Robin2:
That's the frequency, not the duty cycle.

Thanks for that, my mistake I mean the frequency of the pulses.

DrDiettrich:
Can you update the sender and receiver in the same way?

20ms is the usual frame that can contain up to 8 (9?) channels. Shorter frames can not contain that many channels.

I have a RC Radio that is linked to a 2.4GHz Rx, this has a PPM output, so 7 channels multiplexed onto 1 wire. The STM32 uses ISRs to measure the time between all the pulses and outputs 7 channels and their corresponding pulse length in microseconds. The code then does some maths and outputs to 2 servos and 2 ESCs.
So I think I only need to update the STM32 code as the Tx and Rx won't be affected, and this potential change in frequency only affects the servos and ESCs.
I guess I could just try it and see, but I'm worried about bricking something or causing irreparable damage.

I don't understand what you want to do. Feel free to try whatever timing and math, servos do not normally break from irregular input.

I'm trying to increase the frequency of pulses from the servo library from 50Hz -> 100Hz

And how do you want to achieve that? Do you understand how the channels are multiplexed?
With 7 multiplexed channels you have to cut the slot and pulse width into halves.

The servo library doesn't deal with 'multiplexed' PPM signals, just the outputs to individual servos which are 1-2ms pulses repeated every 20ms. I believe the OP simply wants those same pulses to repeat every 10ms instead of 20ms.

Unfortunately I can't help because I'm only used to the AVR Servo library and the timing code is very different. I know nothing about STM32.

Steve

DrDiettrich:
And how do you want to achieve that? Do you understand how the channels are multiplexed?
With 7 multiplexed channels you have to cut the slot and pulse width into halves.

If you look at the code at the top of the thread you'll see my theory for doing so.

slipstick:
The servo library doesn't deal with 'multiplexed' PPM signals, just the outputs to individual servos which are 1-2ms pulses repeated every 20ms. I believe the OP simply wants those same pulses to repeat every 10ms instead of 20ms.

Unfortunately I can't help because I'm only used to the AVR Servo library and the timing code is very different. I know nothing about STM32.

My question has nothing to do with the PPM signal input, that was just for a more complete explanation of whats going on .That side of the code works independently of the servo library. It just uses timers to measure the time between pulses and pulse length itself.
What I'm talking about is the servo Output. Which is going to 2 servos and 2 ESCs via the Write.microseconds() function.
I want the update rate of the duty cycle to go from the standard 50Hz up to 100Hz or even higher. These are digital servos and multicopter ESCs so can handle much more than 50Hz.

You do not yet understand that your theory is incomplete. Proceed and find out the limits yourself.

DrDiettrich:
You do not yet understand that your theory is incomplete. Proceed and find out the limits yourself.

I'm not sure whether you're referring to PPM. That has nothing to do with what I'm doing. I am interested in changing the frequency of the PWM OUTPUT only using Write.microseconds(XXX).

My initial question was pretty simply, does changing this:

#define TAU_MSEC 20
to
#define TAU_MSEC 10

do what I want it to?

jaddion82052:
My initial question was pretty simply, does changing this:

#define TAU_MSEC 20
to
#define TAU_MSEC 10

do what I want it to?

I'd say it's pretty darn easy to find out - try it and see what happens.

Can't help but wonder what the purpose or expected result is, considering the physical reaction time of a typical servo or the motors attached to those ESCs is far greater than 20 ms.

Yea, I been wondering when will the OP just try it and see what happens.

On an ESP32 using the MCPWM or LED PWM the frequency can be changed. The max frequency of the MCPWM is 80Mhz. The issue comes is that the calculations change with frequency changes.

At 50Hz there is a range of 500uS to 2500uS to torque the servo. If the frequency is changed then uSec torque or degree torque values will be different.

Example the ESP32 formula to convert uS requested torque values to clock ticks, LED PWM API.

int usToTicks(int usec)
{
  return (int)((float)usec / ((float)REFRESH_USEC / (float)timer_width_ticks) * (((float)TIMER_FREQUENCY) / 50.0));
} // int usToTicks(int usec)

Notice that the Timer_Frequency

#define TIMER_FREQUENCY 50

is an integral part of the formula to determine the proper clock frequencies.

Also, the something that may be important to you is PWM frequency goes up and and duty cycle resolution goes down.

Servo control signals are not standard PWM. They do not rely on duty cycle percentages. The pulse is approx 500-2500us and there must conventionally be a 4ms guard gap before the next pulse. So the maximum practical frequency for normal servos is around 150Hz. Anything lower than that is fine. Some high speed servos can handle faster frequencies by reducing the 4ms.

Steve

I wonder how many more pulse width "standards" will show up in this thread. RC standard is 1000-2000µs, so that 10 channels fit into a 50Hz frame - with 1 or 2 empty frames for channel synchronization. There exist protocols for up to 24 channels, now it depends on what the actual devices support.

You keep describing a multichannel PPM signal. Even these have not been constrained to either 50Hz or 1-2ms since the whole world started using microcontrollers instead of shift registers/counters for decoding.

The rest of us are talking about a servo control signal. These are NOT THE SAME THING.

Steve

DrDiettrich:
I wonder how many more pulse width "standards" will show up in this thread. RC standard is 1000-2000µs, so that 10 channels fit into a 50Hz frame - with 1 or 2 empty frames for channel synchronization. There exist protocols for up to 24 channels, now it depends on what the actual devices support.

I'm not talking about PPM, I'm talking about pwm OUTPUT from the uC to a servo or ESC.

Have flown rc helis for many years and never found the need for high refresh rate servos.
That said, there are some such as Curtis Youngblood who do.

Below is an explanation of the higher frequency servos plotted against the standard 50hz analog units.

As I say, no idea why you would need the high rate units, perhaps it's a look at me thing.

In the offchance you are highly skilled flyer, I would be going for a commercial unit which I know would work correctly.

Anyhow...the link....... RC Servos: The Muscles of Our Hobby. How They Work, What to Get.

Thanks for the reading. The reason I'm wanting to go higher than 50Hz is its for the flight control software of a thrust vectored drone (think Falcon 9 1st stage with brushless motors). I'm just trying to eliminate any possible source of delay or granularity from the control system.