servo comfortable position

hi,
here’s a bit from a project I’m working on, making a servo open and close a valve.

if (Val < 300) {myservo.write (5);}
else myservo.write (95);
delay(1000);

It works, but when the servo gets to its position, it doesn’t rest (it “sings”), because the valve is pushing back.

I tried this:

if (Val < 300) {myservo.write (5); // go to this position first
delay(10);
myservo.write (10); // then go to “rest” position (the servo stops “singing”)

}
else… same thing here
delay(1000);

but it doesn’t work because after the 1000ms delay the loop restarts and the servo goes back from (10) to (5), just to go back to (10) and back to (5) and so on.

I also tried to implement more than one condition:
if (Val < 300 && myservo > 10) {myservo.write (5);
but I didn’t manage to read out the position of the servo,so…

There must be a simple answer, but I don’t have enough programming experience (or my brain is too small)to know what to do.

Thanks in advance.

There must be a simple answer, but I don’t have enough programming experience (or my brain is too small)to know what to do.

Store the value of Val (as oldVal) that caused the servo to be moved. Then, on each pass through loop, don’t move the servo unless Val != oldVal. You could even use a range, so that Val needed to change by a sizable amount:

if(Val > oldVal + SIZABLEAMOUNT || Val < oldVal - SIZABLEAMOUNT)
{
   // Move the servo
   // Relax the servo
   oldVal = Val;
}

You get, of course, to #define what SIZABLEAMOUNT means.

thanks for the very fast reply.

I understand what you try to tell me, but forgive me, I don’t fully understand how to implement it.

I tried this:

Servo myservo;
int ldrPin = 0;
// Value read from LDR
int Val = 0;
int oldval = 0;
void setup()
{myservo.attach(4);}
void loop(){
Val = analogRead(ldrPin);
if (Val > oldval + 20 || Val < oldval - 20 && Val < 300) {myservo.write (5);
delay(100);
myservo.write (10);
oldval = Val;}
else myservo.write (95);
delay(1000);}

but I guess I misplaced something??

but I guess I misplaced something??

Possibly. Since you don’t say what the code did that you didn’t want, or didn’t do that you did want, it’s hard to say.

Keep in mind that you can have nested if’s as well as compound ifs:

if(Val < 300)
{
   if(Val < oldval - 20 || Val > oldval + 20)
   {
     // Move the servo
     // Rest the servo
     oldval = Val;
   }
}

Putting each { and } on its own line, and properly indenting your code (Ctrl + T) will help you see the structure of your sketch much more clearly.

ok, here’s the whole thing:
Val is a quite stable moist reading

#include <Servo.h>
Servo myservo;
int ldrPin = 0;
// Value read from moist sensor
int Val = 0;
int oldval = 0;

void setup()
{
  myservo.attach(4);

Serial.begin(9600);}
void loop()
{
Val = analogRead(ldrPin);
Serial.println(Val,DEC);



  if(Val > 300)
{
   if(Val < oldval - 100 || Val > oldval + 100);
   {
 myservo.write (100);    // Move the servo
 
  delay(100);
  
   myservo.write (95);  // Rest the servo
     oldval = Val;
   }
}
 
   else myservo.write (5);
   
 delay(1000);

but the servo isn’t resting; now it sings shortly every second now. (going from (100) to (95) again and again)

It's the difference between Val and oldval that needs to be compared to the significant amount...

if(abs(Val - oldval) > 20 || oldval == 0)
{
   // Move the servo
   // Rest the servo
   oldval = Val;
}

I don't know whisch servo you ar using, but it could be all down to a mechnical problem, rather than programmeble.

F.ex a analog servo is not the best thing to use when it comes to holding a position under pressure, you could try a digital servo instead:

The difference are explained here:

http://www.rchelicopterfun.com/rc-servos.html

And apart from that there is a huge difference between servos, I think I have 100+ , (I fly model airplanes), so maybe a bigger servo, another make?

@Paul

thanks for the patience with a novice like me :)

but alas, it doesn't cut it.

I'm suspecting that the oldval voids at the start of every loop or something. It must be something stupid like that.

@ erni, there is almost no pressure involved, the "step back to rest position" solution works, it's just my programming that sucks :-)

I've figured out "sort of" a lazymans-solution; If I set the final delay at one minute, it's not so annoying any more :) but nevertheless I'd still be very happy not having to do it like that.

I'm suspecting that the oldval voids at the start of every loop or something. It must be something stupid like that.

No. Once oldval is assigned a value it remembers it until assigned a new value. If you add some Serial.print() statements, to print out Val, oldval, "I got here...", etc. (and auto-format (and post) your code), you should be able to figure out what the issue is.

bingo!
found it,

the position of “Val = oldval” was wrong.

put it later in the code, so that the value also changed when the “if” was false!

Thanx a million Paul!