I'm pressing a button with a servo and finally have it working OK with the code shown below.
I also tried a version using the FOR loop code from the Sweep sketch, with its additional parameter of an increment value, instead of my simple write() commands. But that involves trial & error to optimise the delay setting in the loop. An unnecessary step in the simple method.
I assume there must be some advantage of the FOR loop method, or Arduino would not have used it in the basic servo demo. Is it just extra flexibility or what?
Code for simple method
/* Aim is to achieve the following sequence of events:
On power-up of circuit:
-----------------------
1. Ensure that the servo's start position places the arm
close to the CUBE camera's button, ready to press it.
During void loop(), IF triggered by pin 7 going briefly LOW:
------------------------------------------------------------
2. A small rotation in an anti-clockwise direction.
3. A delay of 3 s before reversing, which powers up the CUBE.
4. Two normal presses (i.e. with just a short delay before
each release) will start the video.
5. A single normal press after a specified delay will stop
the video.
6. The pin 7 trigger is HIGH again by this time. So further
looping is disabled until another trigger allows.
*/
#include <Servo.h> // Uses code from the Arduino library
Servo myservo; // "Create servo object to control a servo"
// Define variable 'outPos' and set it. It's the start position,
// before anti-clockwise rotation presses the button.
// I've marked it permanently below the rotor arm.
int outPos = 17;
// Now set the position needed for button to be fully pressed.
// So the angle moved will be 17-7 = a mere 10 degs.
int inPos = 7;
// Define variable for pin that will be used as the low-going
// trigger.
// Ultimately that will come from simple electronics.
const int triggerPin = 7;
// =========================================================================
void setup()
{
// Attach the servo on pin 9 to the servo object 'myservo'.
// Min & max values could be added but I've kept it simple.
myservo.attach(9);
// Avoid need for a resistor by using INPUT_PULLUP
// So pin 7 is normally High. When it's taken low, even very
// briefly, it allows the code within the loop to run.
pinMode(triggerPin, INPUT_PULLUP);
// Move to the Start position, with the servo arm ready to push the button.
// This was established by trial & error.
// It obviously depends on the arm being in a consistent physical position.
myservo.write(outPos); // Rotates to the start ('Out') position.
}
// Servo arm is now close to face of button.
void loop()
{
if (digitalRead(triggerPin) == LOW)
{
// A momentary LOW triggers the following:
// Power up by pressing CUBE button for 3 s, say 3100 ms
// IOW moving the servo a small angle and holding
// it there for about 3s.
// Rotates from outPos to inPos
myservo.write(inPos);
// Wait for 3 s before reversing
delay(3200);
// Return rotation from inPos to outPos
myservo.write(outPos);
}
// The button will therefore have been pressed for 3s and
// the servo arm will be back at its original position.
}
// As the trigger was only LOW very briefly, it is HIGH again
// by this time. So further looping is now disabled until a
// later trigger allows it.
Code using FOR loop as in Sweep sketch
/* Aim is to achieve the following sequence of events:
On power-up of circuit:
-----------------------
1. Ensure that the servo's start position places the arm
close to the CUBE camera's button, ready to press it.
During void loop(), IF triggered by pin 7 going briefly LOW:
------------------------------------------------------------
2. A small rotation in an anti-clockwise direction.
3. A delay of 3 s before reversing, which powers up the CUBE.
4. Two normal presses (i.e. with just a short delay before
each release) will start the video.
5. A single normal press after a specified delay will stop
the video.
6. The pin 7 trigger is HIGH again by this time. So further
looping is disabled until another trigger allows.
*/
#include <Servo.h> // Uses code from the Arduino library
Servo myservo; // "Create servo object to control a servo"
// Define variable 'outPos' and set it. It's the start position,
// before anti-clockwise rotation presses the button.
// I've marked it permanently below the rotor arm.
int outPos = 17;
// Now set the position needed for button to be fully pressed.
// So the angle moved will be 17-7 = a mere 10 degs.
int inPos = 7;
// Define variable for pin that will be used as the low-going
// trigger.
// Ultimately that will come from simple electronics.
const int triggerPin = 7;
// Define 'pos' for use with FOR loop as in Sweep sketch
int pos;
// =========================================================================
void setup()
{
// Attach the servo on pin 9 to the servo object 'myservo'.
// Min & max values could be added but I've kept it simple.
myservo.attach(9);
// Avoid need for a resistor by using INPUT_PULLUP
// So pin 7 is normally High. When it's taken low, even very
// briefly, it allows the code within the loop to run.
pinMode(triggerPin, INPUT_PULLUP);
// Move to the Start position, with the servo arm ready to push the button.
// This was established by trial & error.
// It obviously depends on the arm being in a consistent physical position.
myservo.write(outPos); // Rotates to the start ('Out') position.
}
// Servo arm is now close to face of button.
void loop()
{
if (digitalRead(triggerPin) == LOW)
{
// A momentary LOW triggers all the following:
// Rotates anti-clockwise from outPos to inPos, but using the FOR loop as in the Sweep sketch
for (pos = outPos; pos >= inPos; pos -= 3)
{
// goes from 17 to 7 degrees in steps of 1 degree
myservo.write(pos);
// I'm unsure how to optimise this setting, a complication of this method.
delay(10);
}
// Wait for 3 s before reversing
delay(3200);
for (inPos = 18; pos <= outPos; pos += 3)
{
// goes from 7 to 17 degrees, the original start position
myservo.write(pos);
// I'm unsure how to optimise this setting, a complication of this method.
delay(10);
}
}
}
Terrypin:
I assume there must be some advantage of the FOR loop method, or Arduino would not have used it in the basic servo demo. Is it just extra flexibility or what?
I assume there must be some advantage of the FOR loop method, or Arduino would not have used it in the basic servo demo. Is it just extra flexibility or what?
It is not a matter of the for loop having an advantage, rather it is the fact that by using the for loop the servo can move slowly from one extreme to another. Whether that is better than moving at full speed depends on the application. Are you happy for the servo arm to hit the shutter release button of your camera at full speed, for instance ?
The example is probably ment to encourage beginners to play with as many numbers as possible. Both step size and delay per step can be modified and this will allow the user to see the size of the individual steps and how fast they can be performed.
Thanks for all the replies and sorry for my delay in responding.
I now understand the distinction, thanks, summarised by @UKHeliBob and @slipstick.
In my case, simulating the pressing of a firm camera button, the simple method is clearly preferable, with delays after each rotation chosen carefully by experiment.
@Robin2
"It's not clear what you want to happen."
Didn't my code comments explain that in detail?
"...the slow movement can also be achieved without using FOR."
How is that achieved please?
"...the slow movement can also be achieved without using FOR."
How is that achieved please?
You can use the loop() function to do it by updating the servo position at intervals determined by comparing the time of the previous update with the current time using millis() to do the timing. The advantage is that you can do other things in loop() because the code is not locked into the for loop
UKHeliBob:
There is also a library named VarSpeedServo specifically aimed at moving a servo slowly although I have no personal experience of it,
I use it quite often and it has worked very well for me. It's non-blocking (unless you use the wait parameter) and a lot easier than trying to write your own Sweep equivalent using millis() directly.
Thanks Steve, duly installed and looks very handy. Coding for my first project (sequence of camera button presses) is almost finished but I'll experiment with that new function slowmove() later.
I'm having difficulty using the VarSeeedServo library. After reading that "Everything that works with Servo works with VarSpeedServo too," I changed just two lines of code in a successfully working sketch as shown here:
// #include <Servo.h> // Uses code from the Arduino library
// Servo myservo; // "Create servo object to control a servo"
#include <VarSpeedServo.h> // Uses the VarSpeedServo library
VarSpeedServo myServo;
But on uploading I get "Error compiling for board ArduinolGenuino Uno."
Below is the last part of the full error message file. Largely obscure to me. For example how do I interpret the message about 'multiple libraries'? There is only one occurrence of it on my PC.
And what part is WProgram.h meant to play? The error file correctly says "No such file or directory," but why is it apparently needed and where is it supposed to come from?
Also, after using Sketch > Include Library > Add ZIP Library the new library does appear in the list.
You seem to have managed to find a very old version of VarSPeedServo. WProgram.h was replaced by Arduino.h years ago. Where did you get your version from?
Have to go out so haven't yet tried the latest one you suggested. Is that its correct name? And I think I should first remove the earlier one, VarSpeedServo. How is that best done please, as I see no 'Remove' or 'Delete' under Manage Libraries?
Just delete the original VarSpeedServo folder. Your old error messages will tell you where it is if you're not sure.
Then to keep things simple rename the other folder with -master (which should be in the same 'libraries' folder) to be just VarSpeedServo. When you restart the IDE you should have only one.
I have no idea if there's a more official or better way of handling these libraries. I just go for simple.
Hi,
Down load the library as a zip and get the "add zip" in "include library" to do ALL the installation.
No need to rename anything, the IDE does it all for you.