servo with LED fade

Hello Arduino experts,

I am trying to write a script for project I am working on involving servos and LEDs. My goal is to have the servo start at 0 and slowly rotate to 60 degrees continuously back and forth. I would like the LED to fade with from lowest to brightest based on the position of the servo arm. To reiterate, when the servo is at 0 degrees, the LED is at 0; when the servo is at 60 degrees, the LED is 255. It should fade to a fro based on the servo's degree.

Similar cases involve servos fading with variable speeds and led push button circuits, but nothing like this.

It seems super simple to me, but I keep getting caught up. Here is my script:

int ledPin = 2;
#include <Servo.h>
Servo myservo; // create servo object to control a servo
int pos = 0; // variable to store the servo position

void setup()
{
myservo.attach(9); // attaches the servo on pin 9 to the servo object
pinMode(2, OUTPUT);
}

void loop()
{
for(pos = 0; pos < 60; pos += 1) // goes from 0 degrees to 60 degrees in steps of 1 degree
{myservo.write(pos); // tell servo to go to position in variable 'pos'

for(int fadeValue = 0 ; fadeValue <= 255; fadeValue +=5)
{analogWrite(ledPin, fadeValue); }

delay(50); // waits 50ms for the servo to reach the position
}
for(pos = 60; pos>=1; pos-=1) // goes from 60 degrees to 0 degrees
{myservo.write(pos); // tell servo to go to position in variable 'pos'

for(int fadeValue = 255 ; fadeValue >= 0; fadeValue -=5) // sets the value (range from 0 to 255):
{analogWrite(ledPin, fadeValue); } // wait for 30 milliseconds to see the dimming effect

delay(50); // waits 50ms for the servo to reach the position
}
}

It should fade to a fro based on the servo's degree.

Then, you should have ONE for loop, not one inside another. The PWM value should be 4 times the servo position.

I'm not sure i follow... I am still fairly new to this and I built this code with two existing examples.I feel like this should be a lot easier than I've coded it.

What PaulS is saying is that you're doing a "fade for" inside the "servo for", ie you run this....

for(int fadeValue = 0 ; fadeValue <= 255; fadeValue +=5) .....

.... every time the servo position changes.

If we read you correctly, all you want is the brightness of the LED to indicate the position of the servo? So all you need to do is multiply the position by 4 (ok, 255/60 = 4.25 strictly) and set the LED PWM every time the servo moves. (fadeValue= 255 * pos / 60)

Thank you JimboZA and PaulS, that makes sense now.

However, I updated the code and the LED isn't coming on now...
Here is my attempt:

int ledPin = 2;
#include <Servo.h>
Servo myservo; // create servo object to control a servo
int pos = 0; // variable to store the servo position

void setup()
{
myservo.attach(9); // attaches the servo on pin 9 to the servo object
pinMode(2, OUTPUT);
}

void loop()
{
int fadeValue
(fadeValue= 255 * pos / 60);

analogWrite(ledPin, fadeValue);

for(pos = 0; pos < 60; pos += 1) // goes from 0 degrees to 60 degrees in steps of 1 degree
{myservo.write(pos); // tell servo to go to position in variable 'pos'
delay(50); // waits 50ms for the servo to reach the position
}
for(pos = 60; pos>=1; pos-=1) // goes from 60 degrees to 0 degrees
{myservo.write(pos); // tell servo to go to position in variable 'pos

delay(50); // waits 50ms for the servo to reach the position
}
}

You initialise pos to 0, and then only use it once to calculate fade while pos is still 0 which makes the fade value 0 also and it never changes.

You need to move the fade calc and analog write lower down, inside the servo for when pos is getting a new value.

void loop()
{
  int fadeValue
  (fadeValue= 255 * pos / 60);

Does this even compile?

Where do you use this value? You don't have an analogWrite() statement in the for loop anymore.

JimboZA,

Would I need to repeat those LED conditions for both the 0-60 and 60-0 servo movements or will it work being inside of just one of the for loops?

void loop()
{

for(pos = 0; pos < 60; pos += 1) // goes from 0 degrees to 60 degrees in steps of 1 degree
{myservo.write(pos); // tell servo to go to position in variable 'pos'
int fadeValue
(fadeValue= 255 * pos / 60);
analogWrite(ledPin, fadeValue);
delay(50); // waits 50ms for the servo to reach the position
}

for(pos = 60; pos>=1; pos-=1) // goes from 60 degrees to 0 degrees
{myservo.write(pos); // tell servo to go to position in variable 'pos

delay(50); // waits 50ms for the servo to reach the position
}
}

The LED comes shuts off at 0 and then comes on very dull for the duration of the sweep.. no fading.

Also, Why do we multiply the pos by 4?

int fadeValue
   (fadeValue= 255 * pos / 60);

This is STILL nonsense.

This is the proper way:

int fadeValue = 255 * pos / 60;

Would I need to repeat those LED conditions for both the 0-60 and 60-0 servo movements or will it work being inside of just one of the for loops?

How much time did you spend testing?

Ok,

I understand why we multiply 255 by the position and divide by 60 (total range of movement), this allows us to get the full range of brightness of the LED.

I also understand putting the LED fade statements inside of the for loops of the servo, this allows the fadeAmount see the actual position of the servo while it is moving.

After reviewing PaulS comments and JimboZA,

I have arrived at this loop:

void loop()
{

for(pos = 0; pos < 60; pos += 1) // goes from 0 degrees to 60 degrees in steps of 1 degree
{myservo.write(pos); // tell servo to go to position in variable 'pos'
int fadeValue = 255 * pos / 60;
analogWrite(ledPin, fadeValue);
delay(50);} // waits 50ms for the servo to reach the position

for(pos = 60; pos>=1; pos-=1) // goes from 60 degrees to 0 degrees
{myservo.write(pos); // tell servo to go to position in variable 'pos
int fadeValue = 255 * pos / 60;
analogWrite(ledPin, fadeValue);
delay(50);} // waits 50ms for the servo to reach the position

}

To me, this loop makes sense (still learning :blush:);however the LED does not fade.

however the LED does not fade.

Because pin 2 is not a PWM pin.

Thank you PaulS and jimboZA for your assistance. I believe this was a valuable lesson.