I am trying to move model railroad crossing gates from a vertical position to a horizontal position when a train is detected. I have the electronics in for the sensing of train position but want the gates to go down and stay down while the train passed.
To do this, I am looking to be able to use an Arduino to slowly move a servo between two different positions based on a digital input (HIGH or LOW) to one of the digital input pins.
When this digital input goes HIGH, the servo needs to slowly move to the other end of travel and then stop. It must stay there until the digital input goes LOW, at which time it needs to slowly move back to the starting position and again await for a HIGH input.
I cannot figure out how to move the servo slowly to each position and keep it there.
-
You may want something like this: coolcomponents.co.uk/en/sparkfun-servo-trigger.html . Notice that their firmware is licensed CC-BY-SA.Edgar Bonet– Edgar Bonet04/16/2017 07:18:30Commented Apr 16, 2017 at 7:18
-
Welcome to Arduino SE. Be sure to take the tour at arduino.stackexchange.com/TourSDsolar– SDsolar04/17/2017 04:47:03Commented Apr 17, 2017 at 4:47
1 Answer 1
Lacking information about the context of the servo action (ie, what needs to happen at the same time), I'll assume your paradigm uses a loop()
function that executes fairly rapidly, and from time to time invokes any necessary actions.
Servo angles can be measured in degrees (typically 0 to 180) or microseconds (typically 1000 to 2000, corresponding to 0° to 180°). The servo library will accept numbers in either range, and act according to which range the numbers are in. Note that representing servo angles in microseconds instead of degrees gives about 5.55 times better resolution. The method outlined below doesn't care which you use.
Also assume the two servo angles mentioned in the question are A and B, with the servo at A if the input pin is low for a long time; and that the desired rate of swing is ±U units of angle every S milliseconds. Let P = current servo position; T = millis()
value at most recent step, initially 0; and V = previous value of input pin.
In each pass through loop()
:
• Test the input pin. If it isn't equal to V, toggle V and take a step. (See below.).
• If millis()
-T> S, take a step. (See below.)
• Do any other brief per-loop actions
To take a step:
• Add (2*(V>0)-1) * U to P. The expression (V>0) equals 1 or 0, so (2*(V>0)-1) is 1 if V is true, and -1 if V is false.
• If (V) and P> B, set P = B
• If (!V) and P < A, set P = A
• Servo to position P
• Set T = millis()
Edit: You should create meaningful variable or constant names to represent the quantities A, B, P, S, T, U, V. Note that S and T should be declared as constants; and if A, B won't change, make them constants also. State-maintaining quantities P and T should be declared via file-scope variables or globals (outside loop()
) or with static allocation (inside loop()
), so that their values are maintained as main()
repeatedly calls loop()
.
-
Thank you for your help. It should get me going on the project. I am trying to move model railroad crossing gates from a vertical position to a horizontal position when a train is detected. I have the electronics in for the sensing of train position but wanted the gates to go down and stay down while the train passed.Bob Perry– Bob Perry04/17/2017 01:39:26Commented Apr 17, 2017 at 1:39
-
I see how you are incrementally increasing or decreasing the servo position without going beyond the boundaries of the preset servo positions. I am not sure, however, how to get the servo to stay in the assigned positions since the variables are reinitialized each time it goes through the loop. Are some of these static variables? Sorry if stupid questions. New to Arduino programming.Bob Perry– Bob Perry04/17/2017 03:03:30Commented Apr 17, 2017 at 3:03
-
@BobPerry, see edit. Note, please upvote or accept answer if useful.James Waldby - jwpat7– James Waldby - jwpat704/17/2017 22:51:26Commented Apr 17, 2017 at 22:51
-
Thanks. Setting up the variables as static didi the trick!Bob Perry– Bob Perry04/20/2017 04:14:53Commented Apr 20, 2017 at 4:14