Tiddlemouse / arduino

Automatically exported from code.google.com/p/arduino
Other
0 stars 0 forks source link

Servo jitters on resend of same position. #170

Open GoogleCodeExporter opened 9 years ago

GoogleCodeExporter commented 9 years ago
What steps will reproduce the problem?
1. Write the same value to a servo repeatedly (e.g. in loop()).

What is the expected output? What do you see instead?

It jitters.  It shouldn't.  

This is a second-hand report, so I'm not sure of the details.

Original issue reported on code.google.com by dmel...@gmail.com on 5 Jan 2010 at 5:47

GoogleCodeExporter commented 9 years ago
Why do i get the urge to say "get them to write their program so it doesn't 
write 
the same value more than once"

i don't wish to offend anyone, but i couldn't resist :D

Original comment by teamcba@hotmail.com on 7 Jan 2010 at 3:28

GoogleCodeExporter commented 9 years ago
I am having the same issue.  When holding a servo in one position, I am getting 
small
but abrupt movements in the servos every 2-3 seconds.  Although I would 
describe the
phenomenon as 'jitter', it is much larger in amplitude than your typical servo 
jitter.

Using Arduino Mega, tested with both MegaServo and Servo libraries.  Tested with
multiple servos and seeing the same issue on all brands.

Original comment by delsqua...@gmail.com on 18 Feb 2010 at 5:09

GoogleCodeExporter commented 9 years ago
Some quick testing leads me to believe that this jitter is related to writing 
to my
LCD screen.  My LCD is connected as follows:

LiquidCrystal lcd(8, 9, 4, 5, 6, 7);

And servo is connected as follows:
pan_servo.attach( 2, 720, 2283);

My main loop continuously writes data to the LCD screen and servo position.  
This
jitter is observed while sitting in the loop with the servo position being held 
constant.

Original comment by delsqua...@gmail.com on 18 Feb 2010 at 6:02

GoogleCodeExporter commented 9 years ago
OK, so I've been looking into this a bit more.  My theory was that this jitter 
was
being caused by an interrupt (serial, etc) which was causing the PWM interrupt 
to be
delayed, and the signal to be skewed as a result.  

So I put the arduino on a scope and the problem is pretty obvious:

http://img707.imageshack.us/img707/9746/f0002tek.jpg

The short pulses are 1.5ms as they are supposed to be, then all of a sudden we 
get a
~25ms pulse.  Hu?

Now, taking a closer look at the beginning of that long pulse.  Right at 1.5ms 
the
pulse actually drops back to 0 and then immediately comes back up again.  If it 
was
an interrupt issue as I suspected, then it would not be dropping to zero and 
jumping
back up again.

http://img62.imageshack.us/img62/9439/f0004tek.jpg

So, any ideas as to what is causing this to happen?

Original comment by delsqua...@gmail.com on 7 Mar 2010 at 4:41

GoogleCodeExporter commented 9 years ago
The lcd library calls delayMicroseconds and prior to 0018 this would block 
interrupts and thus delay the servo handler. delayMicroseconds was fixed in 
0018. 

If the problem is due to LCD or other code that calls delayMicroseconds then 
the fix 
is to upgrade to 0018.

If the problem is with 0018 then perhaps the Arduino forum would be a better 
place 
to explore what is happening.  

Original comment by memargolis@gmail.com on 14 Mar 2010 at 10:47

GoogleCodeExporter commented 9 years ago
I'm running v0018 already, so it's not going to be quite that simple to fix.  :)

I've modified my sketch to utilize LiquidCrystal440 which removes the
DelayMicroseconds() from the library and instead uses the RW pin to achieve 
proper
timing to the LCD.  Unfortunately this hasn't fixed the problem either.  I'm 
leading
to think that this is a timer problem with the Servo library.

Original comment by delsqua...@gmail.com on 16 Mar 2010 at 3:38

GoogleCodeExporter commented 9 years ago
I believe that this bug is a duplicate of #146.  Testing to confirm shortly.

Original comment by delsqua...@gmail.com on 22 Mar 2010 at 7:40

GoogleCodeExporter commented 9 years ago
Can anyone test this on a Teensy board?

http://www.pjrc.com/teensy/

Teensyduino has a different implementation of digitalWrite that fixes issue 
#146.

Original comment by paul.sto...@gmail.com on 22 Mar 2010 at 11:09

GoogleCodeExporter commented 9 years ago
Confirmed.  This issue is (partially) due to the RMW cycle bug described in Bug 
#146.  

Because LiquidCrystal is performing writes to pins D5 through D9, that means 
that any
interrupt driven digitalWrites (eg: Servo, Tone) on ports E & H will be 
over-written
by non-interrupt driven digitalWrites (eg: LiquidCrystal).

I have moved the two servos to digital pins 45 & 46 which are actually pins PL3 
& PL4
on the ATMEGA chip.  I'm seeing substantially less jittering, although it still 
does
occur every ~30 - 60 seconds.  I chose PL3 & PL4 because AFAIK there should be 
no
digitalWrites occurring on Port L.

I also experimented with using PB0 & PB1, but I am seeing the same jitter every 
30-60
seconds.  

So about 80% of the problem is solved - any further ideas?

Original comment by delsqua...@gmail.com on 23 Mar 2010 at 1:03

GoogleCodeExporter commented 9 years ago
Is it truly the *same* jitter, as issue #146 ?

Perhaps every 30 to 60 seconds the timer0 interrupt happens to occur right when 
the
timer1 interrupt used by Servo needs to run?  That type of jitter would look
completely different than issue #146.

Original comment by paul.sto...@gmail.com on 23 Mar 2010 at 1:16

GoogleCodeExporter commented 9 years ago
Paul - I didn't mean to imply that the remaining jitter is related to Bug #146, 
only
that I am seeing substantially better results when using Servo on Ports L or B.

I believe that the scope photos above, specifically
http://img62.imageshack.us/img62/9439/f0004tek.jpg show the Bug #146 issue.  

I will put the modified sketch on the scope this week and see if I can determine
where the remaining jitter is coming from.  If it's an interrupt collision 
issue as
you suspect, the PWM signal will be 'stretched' every so often.  Bug #146 
issues are
easy to spot due to the momentary return to zero at ~1.5ms and then the PWM 
signal
returns to a high state for the remainder of the cycle.

Original comment by delsqua...@gmail.com on 23 Mar 2010 at 3:04

GoogleCodeExporter commented 9 years ago
Thank you for going to the effort with your scope!  Could you post a link over 
on
issue #146?  It's important to document this, because as of January 2010, when 
this
bug was discussed on the public developer list, the Arduino team felt this bug 
was
not important to fix because nobody has encountered it.

I asked if it's exactly the same jitter ever 30-60 sec only because of the words
"seeing the same jitter every 30-60 seconds".  My guess is the timer0 interrupt
occasionally occurs at just the wrong moment, causing Servo's timer1 interrupt 
to be
delayed.

It'll probably be tough to trigger your scope at the right time to capture 
this. 
Maybe a tiny series resistor to the servo's power line might work, so you can 
sense
and trigger on the sudden increase in current when the motor moves unexpectedly 
after
remaining at rest (presumably drawing much less current)?  Hopefully your scope 
will
have a long enough record length to see the pre-trigger waveforms...

These types of problems are incredibly difficult to diagnose and fully 
understand,
and sometimes convince developers they even exist, not to mention merit fixing. 
 Keep
up the good scope work!!

Original comment by paul.sto...@gmail.com on 23 Mar 2010 at 5:57

GoogleCodeExporter commented 9 years ago
[deleted comment]
GoogleCodeExporter commented 9 years ago
I put together a short sketch to demonstrate this issue.  This sketch
is producing 10-20 'glitches' per minute on pins D2 & D3.

// Bug #146 Demo

// INIT DISPLAY
#include <LiquidCrystal.h>
LiquidCrystal lcd(8, 9, 4, 5, 6, 7);

// INIT SERVOS
#include <Servo.h>
Servo panServo;
Servo tiltServo;

void setup() {
  lcd.begin(16,2);
  panServo.attach(3, 800, 2200);
  panServo.writeMicroseconds(1500);
  tiltServo.attach(2, 800,2200);
  tiltServo.writeMicroseconds(1500);
  Serial.begin(115200);
  Serial1.begin(9600);
  Serial2.begin(9600);
} // setup

void loop() {
  lcd.setCursor(0,0); 
  lcd.print("Hello World");
} // loop

Original comment by delsqua...@gmail.com on 24 Mar 2010 at 2:01

GoogleCodeExporter commented 9 years ago
I conducted some longer and more detailed tests:

1) Removing the Serial.begin()'s doesn't appear to make any difference.  I'm 
still
measuring ~10 glitches per minute.

2)  Adding delay(10) to loop() slows the glitching down to about 1 glitch per 
minute.  

Original comment by delsqua...@gmail.com on 26 Mar 2010 at 3:34

GoogleCodeExporter commented 9 years ago
This is a duplicate of issue 146

Original comment by paul.sto...@gmail.com on 24 Oct 2011 at 10:31