Page 1 of 1

Servo control slow gradually

Posted: 05 Jan 2021, 11:46
by Dondolo
Hi,
I would like to open a box with a servo per rules.

In the first step I was able to solve it like this:

Code: Select all

on Rules # Timer = 1 do
 Servo, 0,12,120
  timerSet, 2.30
endon

on Rules # Timer = 2 do
 Servo, 0.12.30
  timerSet, 1.30
endon
The problem is that the lid flies open and closes again after the time has elapsed.

Does anyone have an idea how I can slow it down with rules?

Re: Servo control slow gradually

Posted: 05 Jan 2021, 11:55
by Ath
Dondolo wrote: 05 Jan 2021, 11:46

Code: Select all

on Rules # Timer = 2 do
 Servo, 0.12.30
  timerSet, 1.30
endon
Are those periods intended in that Servo and TimerSet commands, or a minor mistake?

Wouldn't know how to slow down the servo movement, other than dividing the steps to make into smaller pieces and issue multiple commands (basically a loop, and that's quite complex to do in rules), sorry.

Or request a 'speed' feature (msec to complete the move from current position to new position?) on the Servo command.

Re: Servo control slow gradually

Posted: 05 Jan 2021, 12:37
by Dondolo
Thanks for the feedback!
The periods are arbitrary, I am currently testing the servo function.
Exactly a loop with small steps would be just the thing.

I don't know the speed function, the function could help.

The goal is really just to slowly open the lid and close it accordingly.

Re: Servo control slow gradually

Posted: 05 Jan 2021, 12:49
by Ath
Your rules as shown have syntax errors, so won't run as intended

Re: Servo control slow gradually

Posted: 05 Jan 2021, 12:55
by Dondolo
Ok, the box lid opens and closes every 30 seconds, just too fast; - ((
Is there any other method?
Which syntax error?

Re: Servo control slow gradually

Posted: 05 Jan 2021, 16:33
by TD-er
You could create a loop in the rules and use a variable to keep track of the current state of the servo.

Code: Select all

on openevent do
  let,2,30  // var#1 = cur position, var#2 = target position
  let,3,([var#2]-[var#1])/10  // Step size
  loopTimerSet_ms,1,500,10  // 10 loop steps of 500 msec each
endon

on Rules#Timer=1 do
  let,1,[var#1]+[var#3]
  Servo,0,12,[var#1]
endon
Not tested, so wouldn't be surprised if the sign of [var#3] is wrong, and you should also make sure to initialize the Servo position and [var#1] at boot.
Also it is a good idea to turn off the PWM signal after moving to conserve energy and extend the life of the servo.
You can set the servo to "position" 9000 to turn the servo off.

Re: Servo control slow gradually

Posted: 05 Jan 2021, 18:28
by Dondolo
Hi TD-er,
thank you, I have to understand that first and try it out. Then give feedback.
Thank you very much for now.

Re: Servo control slow gradually

Posted: 05 Jan 2021, 22:20
by Dondolo
TD-er wrote: 05 Jan 2021, 16:33 You could create a loop in the rules and use a variable to keep track of the current state of the servo.

Code: Select all

on openevent do
  let,2,30  // var#1 = cur position, var#2 = target position
  let,3,([var#2]-[var#1])/10  // Step size
  loopTimerSet_ms,1,500,10  // 10 loop steps of 500 msec each
endon

on Rules#Timer=1 do
  let,1,[var#1]+[var#3]
  Servo,0,12,[var#1]
endon
Not tested, so wouldn't be surprised if the sign of [var#3] is wrong, and you should also make sure to initialize the Servo position and [var#1] at boot.
Also it is a good idea to turn off the PWM signal after moving to conserve energy and extend the life of the servo.
You can set the servo to "position" 9000 to turn the servo off.
Hi TD-er,
it works, first attempt the box opens slowly and the servo switches off in the final state.
I think I'm on the right path, thank you again!

Code: Select all

on System#Boot do
Servo,0,12,30  // servo cur position
event,openthebox  //start event openthebox
endon



on openthebox do      //event openthebox
let,2,120  // [var#2] = target position Servo_pos. 120 
let,1,30  // [var#1] = cur position Servo_pos. 30
let,3,([var#2]-[var#1])/10      // Step size
loopTimerSet_ms,1,500,10  // 10 loop steps of 500 msec each
endon

on Rules#Timer=1 do
  let,1,[var#1]+[var#3]
  Servo,0,12,[var#1]

if [var#1]>=120      //target position stop servo
Servo,0,12,9000
endif

//Kontrolle und Verständnis
TaskValueSet 4,1,[var#1]          
TaskValueSet 4,2,%eventvalue2% 

endon

Re: Servo control slow gradually

Posted: 19 Feb 2021, 20:14
by ekrzychoooo
Hi
when I use the command e.g.
Servo, 0.12, 170
and then
Servo, 0.12.9000
sometimes the servo goes to a random position
I watched the waveforms on the oscilloscope and
20210219_195901.jpg
20210219_195901.jpg (270.48 KiB) Viewed 7813 times
I propose to change the code in _P001_Switch.ino

Code: Select all

switch (event->Par1)
          {
            case 1:

              // IRAM: doing servo stuff uses 740 bytes IRAM. (doesnt matter how many instances)
                #ifdef USE_SERVO

              // SPECIAL CASE TO ALLOW SERVO TO BE DETATTCHED AND SAVE POWER.
              if (event->Par3 >= 9000) {
                servo1.detach();
              } else {
                servo1.attach(event->Par2);
                servo1.write(event->Par3);
              }
                #endif // USE_SERVO
              break;
            case 2:
                #ifdef USE_SERVO

              if (event->Par3 >= 9000) {
                servo2.detach();
              } else {
                servo2.attach(event->Par2);
                servo2.write(event->Par3);
              }
                #endif // USE_SERVO
              break;
          }
to

Code: Select all

switch (event->Par1)
          {
            case 1:

              // IRAM: doing servo stuff uses 740 bytes IRAM. (doesnt matter how many instances)
                #ifdef USE_SERVO

              // SPECIAL CASE TO ALLOW SERVO TO BE DETATTCHED AND SAVE POWER.
              if (event->Par3 >= 9000) {
                while(digitalRead(event->Par2)==1);
                servo1.detach();
              } else {
                servo1.attach(event->Par2);
                servo1.write(event->Par3);
              }
                #endif // USE_SERVO
              break;
            case 2:
                #ifdef USE_SERVO

              if (event->Par3 >= 9000) {
                while(digitalRead(event->Par2)==1);
                servo2.detach();
              } else {
                servo2.attach(event->Par2);
                servo2.write(event->Par3);
              }
                #endif // USE_SERVO
              break;
          }

Re: Servo control slow gradually

Posted: 19 Feb 2021, 20:35
by TD-er

Code: Select all

                while(digitalRead(event->Par2)==1);
That's a tricky one.
What if you don't have (no longer) a servo connected or for some reason the pin remains high?

Better to include something like this:

Code: Select all

unsigned long timeout = millis() + 100;
while(digitalRead(event->Par2)==1 && !timeOutReached(timeout));

Re: Servo control slow gradually

Posted: 19 Feb 2021, 20:46
by ekrzychoooo
you're right, it will be safer this way