I wrote a long sketch to have it move to different angles using PWM/PPM based on digital pin input from labview but I noticed that there is alot of jitter/shaking.
I tried to write a simple sketch to make it just hold the same position. There is no load on the servo but I can still hear the jitter from it.
Is there some way to reduce this? Right now I am just running the very simple thing below.
Thank you very much for your reply. The servo class was the first thing that I used but it did not work very well, still had the jitter and I was unable to control the speed.
In reference to the Amp issue the servo seems to work fine with 1.5 amps. it will be tilting a very light platform so will not need to pull much current.
I wrote something below using interrupts that got rid of the jitter.
The issue I am running into now is that I don't know how to control the speed. In loop() I have a case statement for 8 different cases. based on the case picked I want to be able to move a different speeds. There are only 3 different angles at which I will move.
Do you have any idea how I can accomplish this? Thanks again.
Edit: I should mention that I modified something that I found online. I did not write all of this myself.
boolean motorstate = 0, motorenabled=0;
float motorcount=0, state0=75, state1=65, state2 = 85, motormax=500, current = 0;
int P1 = 10, P2 = 11, P3 = 12;
void setup(){
Serial.begin(115200);
//set pins as outputs
pinMode(8, OUTPUT);
pinMode(P1,INPUT);
pinMode(P2,INPUT);
pinMode(P3,INPUT);
cli();//stop interrupts
//set timer0 interrupt at 2kHz
TCCR0A = 0;// set entire TCCR2A register to 0
TCCR0B = 0;// same for TCCR2B
TCNT0 = 0;//initialize counter value to 0
// set compare match register for 50khz increments
OCR0A = 4;// = (16*10^6) / (50000*64) - 1 (must be <256)
// turn on CTC mode
TCCR0A |= (1 << WGM01);
// Set CS11 and CS10 bits for 64 prescaler
TCCR0B |= (1 << CS11) | (1 << CS10);
// enable timer compare interrupt
TIMSK0 |= (1 << OCIE0A);
sei();//allow interrupts
}//end setup
void loop(){
int startbyte = digitalRead(P1) * 4 + digitalRead(P2) * 2 + digitalRead(P1);
switch (startbyte){
case 0:
motorenabled=1;
current=state0;
break;
case 1:
motorenabled=1;
current=state1;
break;
case 2:
motorenabled=1;
current=state1;
break;
case 3:
motorenabled=1;
current=state1;
break;
case 4:
motorenabled=1;
current=state2;
break;
case 5:
motorenabled=1;
current=state2;
break;
case 6:
motorenabled=1;
current=state2;
break;
default:
motorenabled=1;
current=state0;
break;
}
}
ISR(TIMER0_COMPA_vect){
//timer0 interrupt 50kHz to drive servo motor connect to pin 8
// pulse width is 1 ms in motor state '0' and 2 ms in motor state '1'
if(motorenabled){
motorcount ++;
if(motorcount>current){
digitalWrite(8,LOW);
}
if(motorcount>motormax){
motorcount=0;
digitalWrite(8,HIGH);
}
}
}
Thank you very much for your reply. The servo class was the first thing that I used but it did not work very well, still had the jitter and I was unable to control the speed.
It sounds like your jitter was due to timer0 interrupts. The Servo library runs on
timer1 interrupt, but timer0 interrupts happen all the time to maintain millis() value.
If the timer1 interrupt happens when the timer0 interrupt is active it gets delayed a few us,
causing the jitter. For small servos its not normally intrusive.
You can still use the Servo library without timer0 running by going:
TIMSK0 = 0 ; // disable timer0 interrupts
When you mention speed is this the sweep speed of output to the servo or
something else?
Anyway if you have just one servo you can use timer1 PWM directly to control it,
jitter-free - it needs setting up appropriately though for right clocking and period.
Well the code you have stomps on timer0 so millis() isn't working. Checkout the TimerOne
library (I think that's the name) it might be capable of this.
I went and tried you suggestion about disabling Timer0 interrupts and that solved all my issues. I have 0 jitter (and I can still use INT0 for external interrupts which may be needed at another point.)
TIMSK0 = 0 ; // disable timer0 interrupts
I've been working on this for the past 3 days and your 1 line fixed it all. Thank you so much!
Anyway if you have just one servo you can use timer1 PWM directly to control it,
jitter-free - it needs setting up appropriately though for right clocking and period.
Do you know any resource I can read that would shed some light on how to control the speed using the timer PWM? It could be very useful for the future. I have been unsuccessful googling.