How to use servo.read() to turn a LED on?

Hi! I'm new at Arduino... I'm working on a project: I want to use the angle of a servo motor to turn a LED on. I have read and I know that I have to use servo.read() but it's not working and I don't know why. I'll be so gratefull if someone could help me.

#include <Servo.h> //libreria para controlar el servo

const int LEDPinV = 6;        // pin para el LED verde
const int PIRPin = 2;         // pin de entrada (for PIR sensor)
Servo servoMotor;

void setup() 
{
   pinMode(LEDPinV, OUTPUT);  
   servoMotor.attach(9);
   Serial.begin(9600);
}

void loop()
{
  servoMotor.write(0);
  delay(2000);
  servoMotor.write(180);
  delay(2000);

  angle = servoMotor.read();
   
     if (angle == 0){digitalWrite(LEDPinV, LOW); }// turn LED OFF
     if (angle == 180){digitalWrite(LEDPinV, HIGH); } // turn LED ON
}

Servo.read() returns the last value you set with Servo.write(). So in your code you always get 180. Servo.read() is quite useless, because you should know what you last set with Servo.write().
What do you really want to achieve?

1 Like

Can't get the exact point, especially because "it's not working" is not enough to let us understand what you get and what you want!

Your code (even if it won't compile, so please always post the actual and full code, not just some lines manually typed!) asks the motor to move to 0 degrees, next waits 2 seconds, then gives the command to move it to 180 degrees, and waits another 2 seconds before reading the servo angle: what angle do you expect to have when you read it after that?
Depending on servo speed, the only probable angle will be 180 degrees, so the LED will be constantly on (your code will be executed continuously because you put it inside loop!).

I don't know hat is your actual goal, but with the given information you should write to servo the 0 position, then wait until reached (and not a fixed amount of time), turn the LED off, then move to 180 and again wait until reached and turn the led on.

I guess something like this below. I know it's not the best way to do this kind of servo control, and you probably can't use directly in your actual code, but check it out:

#include <Servo.h> //libreria para controlar el servo

const int LEDPinV = 6;        // pin para el LED verde
Servo servoMotor;

void setup() 
{
   pinMode(LEDPinV, OUTPUT);  
   servoMotor.attach(9);
   Serial.begin(9600);
}

void loop()
{
  WaitAngle(0);
  WaitAngle(180);
}

void WaitAngle(int goal) {
  servoMotor.write(goal);
  delay(100); // Give some time to the servo to start...
  while (CheckAngle() != goal) {
    delay(100); // Wait a bit before checking again
  }
}

int CheckAngle() {
  int angle = servoMotor.read();
  if (angle == 0){digitalWrite(LEDPinV, LOW); }// turn LED OFF
  if (angle == 180){digitalWrite(LEDPinV, HIGH); } // turn LED ON
  return angle;
}


PS have a look at the library, especially the read() function... :wink:

1 Like

TBC, even if the read() method was in fact capable of reporting the physical angle of a servo, unless you have really slow servos after 2 seconds the servo would probably have reached 180.

But as @MicroBahner says, the read only reports what you told it, it would be 180 immediately in the above case after the write, no matter if there was even a servo present in real life.

If you need actual real position feedback from a servo, you can't just use a cheap hobby servo. They just don't let you know in any way.

a7

Yes. The code you posted will alternately tell the servo to go from one extreme to another at 10 times a second, probably driving the servo a bit crazy as there is no time for it to get anywhere near the "there" you are sending it to.

a7

I'm sorry if it wasn't clear... What I want to do is this:
If the servo is at 0º then turn the LED on
If the servo is at 180º then turn the LED off

something like if I sent the servo to 0 degrees turn LED on and if I sent the servo to 180 degrees turn led off. What about 5 degree's what does the LED do?

void loop()
{
  WaitAngle(0);
digitialWrite( pinLED, HIGH );
delay(12345678); so the led can be seen to be on
  WaitAngle(180);
digitialWrite( pinLED, LOW );
delay(12345678); so the led can be seen to be off
}
1 Like

It was perfectly clear.

Now do you understand why what you are trying won't work?

The only way your code can know that a servo is at a particular angle is that you can't.

What you might do is experiment with the servos you have to see how long that take to get from one position to another, then when you tell it to go from one to another, wait as long as it takes and…

...assume it got there. Because that's all you can do with cheap servos that you write and read with the servo,library.

a7

Thak you all. I think I got the answer!

You sure? The WaitAngle() function gives to the servo the command to move to target angle, then waits until the angle is equal to the desired, changes the LED state and then moves back to the other side, so the number of movements depends on how fast the servo can move: how have you determined it'd stress the servo 10 times per second?

Besides, I already said it's not the correct way to handle servo movements, but it was just a kinda proof of concept. Better implementations include finite state machines, but I suspect it's a bit early for the OP to talk about that.

Maybe 100 ms is time for the servo to go from 0 rom180 degrees.

Specs I found for one typical hobby servo:

 At 6 volts under no load 0.16 seconds to go 60 degrees.

That's 0.48 seconds for a full sweep.

So the servo will be going one way, then the other, then the other, I'd like to watch that.

How long the servo would like that is also something to experiment with. Better servos would probably last longer.

waits until the angle is equal

The angle read will be the last angle written, immediately after the write. There is no capability to interrogate the servo and have it tell you how it is doing, or where it is, or even if it is… there at all.

Have a look at the library, especially the read() function... :wink:

The code the OP likes will immediately turn on the LED that says the servo is at 180, or 0. Meanwhile the servo will start moving there, and, at least with the servo I quoted specifications for, reach that goal 0.48 seconds later.

a7

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.