Go Down

Topic: Servo Jittering when sending signal to another pin? (Read 659 times) previous topic - next topic

smh_999

Hi All,

I'm putting together a Halloween project - Pumpkin with flashing/fading eyes + spider that moves (Stuck to a servo!).

I managed to get the LEDs (eyes!) flashing/fading...then attached the servo. Problem is, the servo jitters when I expect the LEDs to fade - See below fadeEyes(), ands the LEDs do not fade if the servo pin is attached, by attached, I mean the line servoSpider.attach(spider); runs, I have tried with the servo disconnected, thinking I might have a faulty servo, although the servo does work AOK on its own.

Any help appreciated...

Thanks,
Simon.

Code: [Select]

/*
Pumpkin Halloween 2012
* 2 Flashing Red LED eyes
* 1 Servo driven spinning spider
*/

#include <Servo.h>

// Spider
Servo servoSpider;
int servoSpiderPos = 0;
int servoSpiderWaitTime = 2;
int servoSpiderRotate = 360;

// Eyes
int spider = 4;        // Pin for Spider
int eyeOne = 9;        // Pin for Eye 1
int eyeTwo = 10;       // Pin for Eye 2
int brightness = 0;    // how bright the LED is
int fadeAmount = 5;    // how many points to fade the LED by
long actionDelay;      // Random delay between eye flash/delay (Between 3 and 20 seconds)
int onOffTime = 100;   // How long eyes on/off for in blink stage
int blinks = 25;       // How many times eyes blink


// the setup routine runs once when you press reset:
void setup()  {
  Serial.begin(9600);
 
  servoSpider.attach(spider);
  pinMode(eyeOne, OUTPUT);
  pinMode(eyeTwo, OUTPUT);

  //actionDelay = 1000;
}

// the loop routine runs over and over again forever:
void loop()  {
    Serial.println("Begin: Loop"); 
 
    actionDelay = random(500, 3000);
    Serial.println(actionDelay);   
   
    fadeEyes();
    delay(actionDelay);
    blinkEyes();
    delay(actionDelay);
   
    // Spin spider?
    if ((actionDelay % 2) == 0)
    {
      awakeSpider();
    }
   
    Serial.println("End: Loop");
}

void fadeEyes()
{
  Serial.println("Begin: Fade Eyes");
 
  for (int i = 0; i < 255; i++)
  {
    Serial.println(i);
    Serial.println(eyeOne);
    Serial.println(eyeTwo);
    analogWrite(eyeOne, i);
    analogWrite(eyeTwo, i);
    delay(5);
  }
   
  for (int i = 255; i >= 0; i--)
  {
    Serial.println(i);
    Serial.println(eyeOne);
    Serial.println(eyeTwo);
    analogWrite(eyeOne, i);
    analogWrite(eyeTwo, i);
    delay(5);
  }
 
  Serial.println("Complete: Fade Eyes");
}

void blinkEyes()
{
  Serial.println("Begin: Blinking Eyes");
 
  for (int i = 0; i <= blinks; i++)
  {
    analogWrite(eyeOne, 255);
    analogWrite(eyeTwo, 255);
    delay(onOffTime);
    analogWrite(eyeOne, 0);
    analogWrite(eyeTwo, 0);
    delay(onOffTime);
  }
 
   Serial.println("Complete: Blinking Eyes");
}

void awakeSpider()
{
  Serial.println("Begin: Awake Spider");
 
  servoSpider.write(0);
  delay(500);
  servoSpider.write(170);
  delay(500);

  Serial.println("Complete: Awake Spider");
}




PeterH

I suggest you need to make some fundamental but simple changes to your sketch.

Divide your behaviour (blinking, fading etc) into separate actions that can be carried out separately and scheduled using the approach demonstrated in the 'blink without delay' example sketch.

The way I'd do it is to separate out the parts of the behaviour which can be controlled independently. If you wanted to blink the eyes and move the spider independently I'd replace loop() with something like:

Code: [Select]

void loop()
{
   handleBlinking();
   handleSpider();
}


In handleBlinking(), use the techniques from 'blink without delay' to decide whether it is time to blink the LEDs on or off.

In handleSpider(), use the same techniques to decide whether it was time to move the spider.

You can use the same approach to add as many separate activities as you want, and as long as none of them use delay() none of them will interfere with each other.
I only provide help via the forum - please do not contact me for private consultancy.

smh_999

Peter,

Thanks for your reply - Got me thinking, I guess we are getting at a problem with using delay(), in that "analogWrite values and pin states are maintained".
See http://www.arduino.cc/en/Reference/delay

I also note from here: http://www.arduino.cc/en/Reference/AnalogWrite...

The PWM outputs generated on pins 5 and 6 will have higher-than-expected duty cycles. This is because of interactions with the millis() and delay() functions, which share the same internal timer used to generate those PWM outputs. This will be noticed mostly on low duty-cycle settings (e.g 0 - 10) and may result in a value of 0 not fully turning off the output on pins 5 and 6.


Although note from my sketch I'm using pins 4, 9 and 10.

I'll certainly try what you are suggesting Peter - Although I would like to understand what is causing this seemingly odd behaviour.

Cheers!
Simon.


holmes4

Thinks, servo code/lib use pin 9 as a time so move the led!

Quote
The Servo library supports up to 12 motors on most Arduino boards and 48 on the Arduino Mega. On boards other than the Mega, use of the library disables analogWrite() (PWM) functionality on pins 9 and 10, whether or not there is a Servo on those pins. On the Mega, up to 12 servos can be used without interfering with PWM functionality; use of 12 to 23 motors will disable PWM on pins 11 and 12.


Mark

smh_999

Mark - Only just seen your reply - Thanks! I never would have figured that out!

Small world...I'm in Upper Parkstone!

holmes4

So now YOu can turn pumkin into Santa XD.

Mark

Go Up