Controlling a Servo motor using interrupts without servo library

I have been trying to control a servo motor without the servo library due to a conflict in the library I am using.

A problem I have been running into is the Servo motor jitters unless I send it a certain frequency.

I figured I could use an interrupt to control the servo that way it always is sent the same frequency and therefore does not jitter.

I have never worked with timer interrupts before so I was working on some dummy code to make sure I understand it.
Here is what I have:

#include <TimerOne.h>

void setup() 
{
  //Initialize the digital pin as an output.
  pinMode(22, OUTPUT);
  Timer1.initialize(10000); //set a timer of length in microseconds
  Timer1.attachInterrupt(timerIsr); //attach the service routine here

}

void loop() {
  // put your main code here, to run repeatedly:

}

void timerIsr()
{
  //Toggle PWM
  digitalWrite(22, !digitalRead(22));
}

The only problem with this approach is that the pin is HIGH and LOW for an equal amount of time thus changing the frequency and not the position.

Is it possible to have it be HIGH for 30% or 90% of the time thus corresponding to a certain position but staying at the same frequency?

Thanks in advance

Have you tried the ServoTimer2 library?

The standard Servo library uses Timer1

...R

I have tried that. Unfortunately that also wont work.

Well if your reason for avoiding the servo library was a timer conflict then I got some bad news for you. The timer in question is timer 1 so what you have now will also conflict.

The issue is not solely a timer conflict.

I have already tried compiling TimerOne.h with the other libraries that I need to use and it is able to compile.

The problem I have when it is not the timer that has conflicts is is the jitter that occurs. The jitter occurs because of a frequency discrepancy with the servos and some other things on the board that I am using. So i figured I could just do it manually so that I can control the frequency and therefore stop the jitter. I tried entering the code above into my main code and hooked the servo up to an oscilloscope. The PWM is working and the motor has no jitter. I just need to know how I would go about changing the PWM to be a percentage other than 50% with this approach or if it is even possible.

I am concerned over your understanding of how servos work. You use changes in frequency to describe changes in the servo behavior. Servo protocol doesnot use changes in frequency to control servo position.It uses Pulse Position Modulation. PPM There may be better documents describing it, but this one will do http://www.jameco.com/jameco/workshop/howitworks/how-servo-motors-work.html

I understand that the Servo is told where to go using PWM and that the frequency is not part of that. I just need to make sure that what I am sending the servo stays at a constant frequency because when it does not the servo begins to have issues. I just need to know if it is possible to change the pulse width while keeping the frequency constant using this method.

You want one of these https://www.adafruit.com/product/815

Any other method with software is doomed to fail if you have other interrupts going off in the system.

Is it possible to have it be HIGH for 30% or 90% of the time thus corresponding to a certain position but staying at the same frequency?

Yes that is what PWM gives you normally when you access it through analogWrite. However that wil not move a servo, because your pulse refresh rate is way too fast. Some servos can be damaged by such a signal.

Hi, Is this problem a part of this?

https://forum.arduino.cc/index.php?topic=485962.0

Tom.. :)

Grumpy_Mike: You want one of these https://www.adafruit.com/product/815

Any other method with software is doomed to fail if you have other interrupts going off in the system.

I had looked into this solution previously. The issue I have with that is the only pins I have available are: PA1 - DIO23 PA0 - DIO22 PK0 - ADC8 PK1 - ADC9 PD2 - RX1/DIO19 PD3 - TX1/DIO18 PA3 - DIO25 PA4 - DIO26 PA5 - DIO27 MOSI - PB2 - MOSI/DIO51 MISO - PB3 - MISO/DIO50 SCK - PB1 - SCK/DIO52

none of which are compatible with I2C

Grumpy_Mike: Yes that is what PWM gives you normally when you access it through analogWrite. However that wil not move a servo, because your pulse refresh rate is way too fast. Some servos can be damaged by such a signal.

Is is possible to slow down the PWM signal into a frequency much slower such that it wont damage the servo and that it will still be compatible with a 1KHz frequency... Just a shot in the dark.

TomGeorge: Hi, Is this problem a part of this?

https://forum.arduino.cc/index.php?topic=485962.0

Tom.. :)

It is part of that project yes. I still cant seem to shake the problem. I am really new to arduino and programming in general... like I just started in May with literally no previous experience and I feel like these issues I am dealing with are a little above my level of understanding. That said I was able to shake the issue with one servo by just using delay functions and measuring the frequency with an oscilloscope until I found the sweet spot that avoided the jitter but with 2 servos the problem isn't wanting to be fixed.

You have never provided any evidence of how the servo behaves (or misbehaves) with a simple program using the regular Servo library. Make a short video and upload it to YouTube and post the code that you used here.

I have not had any problems with the regular library.

...R

Hi,

Is is possible to slow down the PWM signal into a frequency much slower such that it wont damage the servo and that it will still be compatible with a 1KHz frequency... Just a shot in the dark.

Sorry no, the servo pulse is a timed pulse not PWM duty cycle.

http://www.seattlerobotics.org/guide/servos.html

Tom... :)

I had looked into this solution previously. The issue I have with that is the only pins I have available are: PA1 - DIO23 ......... none of which are compatible with I2C

So what Arduino are you using, we assume a Uno here unless you say to the contrary?

You have two solutions to this problem,

1) Swap out the two connections that use the I2C lines with two of your many other free pins.

2) Use a software bit banging I2C libiary.