bmellink / IBusBM

Arduino library for RC IBUS protocol - servo (receive) and sensors/telemetry (send) using hardware UART
GNU General Public License v3.0
205 stars 52 forks source link

Servo jitter #22

Open Ivzo opened 3 years ago

Ivzo commented 3 years ago

Hi. I have WeAct 3.0 STM32F411 and when use only IBusServo connected the servo and run an example everything works perfect. But when i added IBusSens the servo started to jitter (( Can you give some advice how to solve?

bmellink commented 3 years ago

Hi Ivzo,

I have seen this behavior before and it was related to the servo library used and the way the library uses interrupts. Let me explain: A servo will position itself based on a pulse width generated by the servo library. The library starts a timer within the STM32 with a start value based on the required pulse width (=position of the servo) which will generate an interrupt when the pulse time is expired. Because IbusBM also uses interrupts (for communication) there may be multiple interrupts at the same exact moment. As interrupts typically can not happen at the same time, one needs to wait for the other. This may result in a pulse width that is not exactly the same.

The IbusBM interrupt control routine relinquishes control back as soon as possible (allowing another interrupt to go ahead anyway, even if the interrupt of IbusBM is still busy). This is by design to reduce jitter as much as possible and IbusBM does not need to be as real time as a Servo pulse, but just needs to be able run at least once per millisecond. In most cases this works well, except maybe in your case. Other reasons this may happen is, when you are reading of writing to Flash memory.

Some chips allow you to define interrupt priority: which means you can tell the processor to give priority to an interrupt that is more time critical (such as the pulse width for the servo).

I think there are 4 options for you to address this issue: 1.- Use a servo library that ensures the highest interrupt priority is used (if your CPU supports that - I am not sure such a library exists for the STM32) 2.- Turn off the use of interrupts in IbusBM, so your servos are the only ones that use interrupts. Look at the readme for the IBUSBM_NOTIMER argument of the IBus.begin() constructor. You then need to call the iBus.loop(); routine in your main program as often as possible to ensure communication stays online. 3.- Try to avoid using Flash read/write functions in combination with servos on the STM32. Reading or writing Flash seems to be a high priority operation that messes up any servo. 4.- Connect your servo's directly to your receiver (the TGY-IA6B has multiple servo ports) and use the IbusBM library only for non-servo things, such as switching lights, relays, reading sensor values and servos where jitter is not an issue

There was another discussion on this topic here: https://github.com/bmellink/IBusBM/issues/20 This user was trying something else and was eventually able to solve this.

Hope this helps

regards

Bart

Ivzo commented 3 years ago

Thank you. I've changed the board and find another thing... When I run this library on ESP32 there is a conflict between ibusbm lib and eeprom lib (and Preferences lib). But with NOTIMER works fine.