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()
.