Listing 1—This code illustrates the use of the PeriodicThread. I removed the code normally used for stopping this thread safely because it doesn’t concern the control of servos.
class ServoThread extends PeriodicThread {
private static ServoThread servoThread = null;
private boolean running = true;
private boolean stopped = false;
//There are 200 ticks in 20 ms.
private int maxTicks = 199;
//A place to store the active servos.
private GpioServoMotor[] motors = {null, null, null, null};
private int numMotors = 0;
//Make sure that this class cannot be created by an outside class.
private ServoThread() {
}
//This is the only way to create an instance of this class.
public static ServoThread getInstance() {
if (servoThread == null) {
servoThread = new ServoThread();
//The thread is called once every 0.1 ms, with no leading //wait, and with a high priority; the thread is then started.
servoThread.makePeriodic(0, 100000, 0, 0, Thread.MAX_PRIORITY - 2, servoThread);
servoThread.start();
}
return servoThread;
}
//Add servos here. At this time, I’m not concerned with removing //any servos from my list.
public void addServo(GpioServoMotor servo) {
motors[numMotors++] = servo;
}
//Just go in a continuous loop until somebody wants this to //stop, perhaps for powering down the robot.
public void run() {
int tick = 0;
int i = 0;
while (running) {
//PeriodicThread.cycle() is similar to Thread.yield(), but it //causes the thread to start again at the specified interval.
PeriodicThread.cycle();
if (tick == 0) {
//At the start of the cycle, turn on all pulses.
for (i = 0; i < numMotors; i++) {
motors[i].getPin().setPinState(true);
}
}
else {
//Check for the end of a pulse for each motor.
for (i = 0; i < numMotors; i++) {
if (motors[i].getTicksPerPulse() < tick) {
motors[i].getPin().setPinState(false);
}
}
}
tick++;
//At the end of a cycle, go back to zero.
if (tick > maxTicks) {
tick = 0;
}
}
stopped = true;
}
}