Australia
Offline
Newbie
Karma: 0
Posts: 8
|
 |
« on: January 30, 2013, 06:19:31 am » |
Hi everyone, I am very new to all of this and have been tinkering extensively for several days working on a program to change the position of a servo between 0, 45 and 90 degrees by using a digital input. No input = 0 degrees, a HIGH input on digital pin 3 moves the servo to 45 degress and a HIGH input on digital pin 4 moves the servo to 90 degrees. What I am now having trouble programming is how to slow the movement of the servo down. What I am trying to emulate is a old style of railway signal used in NSW Australia for many years known as an upper quadrant signal. See photo http://www.flickr.com/photos/robertstrains/5767145547/ . They are driven off a motor that moves realatively slowly i nreal life and that is what I am trying to emulate. I have been using the sweep sketch in the examples as a reference but have come up trumps after reading all the posts forums and books I have acess to and searching you tube. There is obviously something I am missing. If you need to see the sketch I am happy to post it. But the notes are incomplete at this stage.
Thanks in advance, Briggsy
|
|
|
|
« Last Edit: January 30, 2013, 06:23:02 am by briggsy »
|
Logged
|
|
|
|
|
Global Moderator
UK
Offline
Brattain Member
Karma: 143
Posts: 19365
I don't think you connected the grounds, Dave.
|
 |
« Reply #1 on: January 30, 2013, 06:28:58 am » |
Write small angular increments to the Servo, with a delay between the writes. Bonus marks for not using "delay()".
If you post your code, we can help you with it.
|
|
|
|
|
Logged
|
Pete, it's a fool looks for logic in the chambers of the human heart.
|
|
|
|
Australia
Offline
Newbie
Karma: 0
Posts: 8
|
 |
« Reply #2 on: January 30, 2013, 06:35:28 am » |
Here is the sketch. //Upper Quadrant servo sketch 1 #include <Servo.h> Servo myservo; // create servo object to control a servo int yellowState; int greenState; // constants won't change. They're used here to // set pin numbers:
const int yellowPin = 3; const int greenPin = 4;
void setup() { // initialize the trigger pins as an input: pinMode(yellowPin, INPUT); pinMode(greenPin, INPUT); myservo.attach(9); // attaches the servo on pin 9 to the servo object } void loop(){ // read the state of the trigger value: yellowState = digitalRead(yellowPin); greenState = digitalRead(greenPin);
// check if either of the triggers are HIGH // if it is, the relavant State is HIGH: if (yellowState == HIGH) myservo.write(45); //sends servo to 45 degrees if (greenState == HIGH)
myservo.write(90); //sends servo to 90 degrees if ((yellowState == LOW) && (greenState == LOW)) myservo.write(0); }
Thanks for taking the time to have a look. I worked out how to play with the delay in the sweep example but I could never get it to work in my sketch. Briggsy
|
|
|
|
|
Logged
|
|
|
|
|
Global Moderator
UK
Offline
Brattain Member
Karma: 143
Posts: 19365
I don't think you connected the grounds, Dave.
|
 |
« Reply #3 on: January 30, 2013, 06:42:20 am » |
As written, your servo will move as quickly as it can from one position to the next. If, instead of a simple "servo.write (90);" you did something like (and I'm going to lose marks for this) for (int angle = 0; angle < 90; angle+=10) { servo.write (angle); delay (50); } , your sweep will take longer. Play with it, change the values, particularly the start, end and increment values (you don't want to go back to zero if you're already at 45 and moving to 90)
|
|
|
|
|
Logged
|
Pete, it's a fool looks for logic in the chambers of the human heart.
|
|
|
|
Australia
Offline
Newbie
Karma: 0
Posts: 8
|
 |
« Reply #4 on: January 30, 2013, 08:07:50 am » |
AWOL, Thanks for the help but that has not appeared to have worked. I have tinkered gto the best of my knowledge. I there a way to just slow down the PWM change to the servo so that all of it's movements are slowed to the same rate? It just waved the servo about like a crazy thing.
Briggsy
|
|
|
|
|
Logged
|
|
|
|
|
Seattle, WA USA
Offline
Brattain Member
Karma: 334
Posts: 36433
Seattle, WA USA
|
 |
« Reply #5 on: January 30, 2013, 08:15:34 am » |
It just waved the servo about like a crazy thing. Time to put up or shut up. Where IS your code?
|
|
|
|
|
Logged
|
|
|
|
|
UK
Offline
Tesla Member
Karma: 99
Posts: 6778
-
|
 |
« Reply #6 on: January 30, 2013, 08:16:53 am » |
that has not appeared to have worked. I have tinkered gto the best of my knowledge.
Post your new code. I there a way to just slow down the PWM change to the servo so that all of it's movements are slowed to the same rate? It just waved the servo about like a crazy thing.
Yes there is. It'd need some changes to your code, though. The approach I'd take is to add a variable holding the current position of the servo, and a variable that holds the target position. At the point in your code where you currently move the servo, just update the target position instead. Add some code that runs at regular intervals - every 10 ms would be a reasonable starting point. Look at the 'blink without delay' example sketch to see how to do things at regular intervals. Every interval, compare the current and target position of the servo. If they're different then move the servo one unit towards the target position. You will need to experiment with the interval to get the speed of movement that you require. This technique could be extended easily to support multiple servos - just convert the variables involved to arrays and add code to apply the logic above to each element in the array. If you were looking to make a very modular and reusable solution, you might go one step further and create a class that contains this logic (i.e. a speed-limited servo).
|
|
|
|
« Last Edit: January 30, 2013, 08:23:37 am by PeterH »
|
Logged
|
|
|
|
|
Global Moderator
UK
Offline
Brattain Member
Karma: 143
Posts: 19365
I don't think you connected the grounds, Dave.
|
 |
« Reply #7 on: January 30, 2013, 08:18:21 am » |
There is a variable speed servo library somewhere.
|
|
|
|
|
Logged
|
Pete, it's a fool looks for logic in the chambers of the human heart.
|
|
|
|
Australia
Offline
Newbie
Karma: 0
Posts: 8
|
 |
« Reply #8 on: January 30, 2013, 08:24:01 am » |
My apologies. My aim is not to upset or annoy. I tinkered some more and got it to stop waving about by removing the time interval bit off the 90 degree part of the sketch. But it still moves quickly to 45 degrees with it in on that part. Here is how it currently stands. //Upper Quadrant servo sketch 1 #include <Servo.h> Servo myservo; // create servo object to control a servo int yellowState; int greenState; int angle = 0; // constants won't change. They're used here to // set pin numbers:
const int yellowPin = 3; const int greenPin = 4;
void setup() { // initialize the trigger pins as an input: pinMode(yellowPin, INPUT); pinMode(greenPin, INPUT); myservo.attach(9); // attaches the servo on pin 9 to the servo object } void loop(){ // read the state of the trigger value: yellowState = digitalRead(yellowPin); greenState = digitalRead(greenPin);
// check if either of the triggers are HIGH // if it is, the relavant State is HIGH: if (yellowState == HIGH) for (int angle = 1; angle < 45; angle += 1) myservo.write (angle); delay (100); //sends servo to 45 degrees if (greenState == HIGH)
myservo.write (90); //sends servo to 90 degrees if ((yellowState == LOW) && (greenState == LOW)) myservo.write (0); }
AWOL that sounds promising. Thanks again for all the help, Briggsy
|
|
|
|
|
Logged
|
|
|
|
|
Global Moderator
UK
Offline
Brattain Member
Karma: 143
Posts: 19365
I don't think you connected the grounds, Dave.
|
 |
« Reply #9 on: January 30, 2013, 08:25:58 am » |
if (yellowState == HIGH) for (int angle = 1; angle < 45; angle += 1) myservo.write (angle); delay (100); When I wrote the example in reply #3, I very carefully put in a set of { } braces. They're important, and they're missing from your code.
|
|
|
|
« Last Edit: January 30, 2013, 08:30:02 am by AWOL »
|
Logged
|
Pete, it's a fool looks for logic in the chambers of the human heart.
|
|
|
|
Australia
Offline
Newbie
Karma: 0
Posts: 8
|
 |
« Reply #10 on: January 30, 2013, 08:31:01 am » |
AWOL, My apologies. I must have left them out after my tinkering. I'll have another go after I put them back in. My mistake.
Thanks again, Briggsy
|
|
|
|
|
Logged
|
|
|
|
|
Australia
Offline
Newbie
Karma: 0
Posts: 8
|
 |
« Reply #11 on: January 30, 2013, 08:36:43 am » |
AWOL, They are back in and it has slowed the servo down on the movement from 0 to 45 degrees but it now immediately returns to to zero degrees at full speed once it has reached 45 degrees. I'll include the updated code again. //Upper Quadrant servo sketch 1 #include <Servo.h> Servo myservo; // create servo object to control a servo int yellowState; int greenState; int angle = 0; // constants won't change. They're used here to // set pin numbers:
const int yellowPin = 3; const int greenPin = 4;
void setup() { // initialize the trigger pins as an input: pinMode(yellowPin, INPUT); pinMode(greenPin, INPUT); myservo.attach(9); // attaches the servo on pin 9 to the servo object } void loop(){ // read the state of the trigger value: yellowState = digitalRead(yellowPin); greenState = digitalRead(greenPin);
// check if either of the triggers are HIGH // if it is, the relavant State is HIGH: if (yellowState == HIGH) for (int angle = 1; angle < 45; angle += 1){ myservo.write (angle); delay (100); } //sends servo to 45 degrees if (greenState == HIGH)
myservo.write (90); //sends servo to 90 degrees if ((yellowState == LOW) && (greenState == LOW)) myservo.write (0); }
Thanks, Briggsy
|
|
|
|
|
Logged
|
|
|
|
|
Global Moderator
UK
Offline
Brattain Member
Karma: 143
Posts: 19365
I don't think you connected the grounds, Dave.
|
 |
« Reply #12 on: January 30, 2013, 08:41:35 am » |
but it now immediately returns to to zero degrees at full speed once it has reached 45 degrees Presumably because after four-and-a-half seconds, you've let go of the buttons, and they're both low again?
|
|
|
|
|
Logged
|
Pete, it's a fool looks for logic in the chambers of the human heart.
|
|
|
|
Seattle, WA USA
Offline
Brattain Member
Karma: 334
Posts: 36433
Seattle, WA USA
|
 |
« Reply #13 on: January 30, 2013, 08:43:59 am » |
It would really help you understand what your code is doing if you put every { on a new line, and used Tools + Auto Format.
Code that jerks all over the page is very hard to read.
|
|
|
|
|
Logged
|
|
|
|
|
Australia
Offline
Newbie
Karma: 0
Posts: 8
|
 |
« Reply #14 on: January 30, 2013, 08:46:01 am » |
Yes there is. It'd need some changes to your code, though. The approach I'd take is to add a variable holding the current position of the servo, and a variable that holds the target position. At the point in your code where you currently move the servo, just update the target position instead.
Add some code that runs at regular intervals - every 10 ms would be a reasonable starting point. Look at the 'blink without delay' example sketch to see how to do things at regular intervals. Every interval, compare the current and target position of the servo. If they're different then move the servo one unit towards the target position. You will need to experiment with the interval to get the speed of movement that you require.
This technique could be extended easily to support multiple servos - just convert the variables involved to arrays and add code to apply the logic above to each element in the array.
If you were looking to make a very modular and reusable solution, you might go one step further and create a class that contains this logic (i.e. a speed-limited servo).
PeterH, Thanks for that info. I'll do some more reading and have a go at it fresh next time. It's late and I've annoyed you gentleman enough for now. Sorry for it being everywhere. I'm still learning how to clean it up without stuffing it up. Thanks again, Briggsy
|
|
|
|
|
Logged
|
|
|
|
|
|