I'm lazy and don't want to use a microcontroller so here comes the FPGA.
The function is pretty simple so VHDL simulation will be easy.
The servos are controlled by one output, one pin driven in PWM : 1ms long pulse for closed, 2ms long pulse for open. There would be a bit more than 500ms in each state : >500ms open, >500ms closed. The PWM pulses are repeated at about 50Hz, or 20ms apart. This could be either 16ms or 32ms...
Already we see what can be done :
- a prediv from the 50MHz integrated clock, down to 1KHz (a counter from 0 to 49999) => 16 bits
- a counter for the pulse repeat rate : the pulse is high during the first cycle (or two, for the open case). 20ms gives us 5 bits.
- A counter for the open or close period : 50 repeats gives us a 6-bits counter
- 2 state bits for wait-open-close
The state affects one bit of the 2nd stage, so the pulse is longer or shorter. And that's all for the PWM+FSM.
There is a need for a RNG : it can be taken from bits of the free-running counter, sampled when the trigger state changes. Some probability shaping is required, one bit gives 1/2, and 2 bits combine to add the 1/4 and 3/4 chance (respectively with AND and OR). Maybe probabilities 0, 1, 1/2, 1/4 and 1/8 could be selected...
One input needs to be selected when the RNG is 1. Otherwise, the FSM returns to the WAIT state. There are up to 16 inputs max (10 or 12 in practice, 14 outputs max) so this maps to the PWM counter (which is also the RNG ?). The counter would scan the inputs until one is set to 1. The loop can be stopped when non-existent input 16 is reached, set to 1.
The FSM has these states and runs at 1KHz :
- 0 : wait until the trigger input changes. PWM counter is running at 1KHz. Servo power is off.
- 1 : scan / select input (1 to 16 cycles max), select output
- 2 : if conditions met : power on the selected servo and run 64 cycles of "open"
- 3 : run 64 cycles of "close" then goto back to 0
yeah, this should work... it could even be implemented mostly as TTL/CMOS :-D
There are however many other issues to solve, such as : how to send the PWM signal properly and avoid electrical issues when the servo is not powered ? So far the servos are switched from the low side, such that the PWM input will float around 5V when idle, which is not suitable for classic (push-pull) digital outputs...