Routines
Routines are pre-programmed 'dances'. If not currently dancing, robot will perform an idle behaviour eg: changing LED colours.
In each routine are keys (or 'dance moves'). In here is what moves the servos to different places, or changes the LEDs.
It is best to use non-breaking actions, unless there is something that needs to be changed and completed in that key.
Below is an example of the arm alternating routine. Notice how ignoreMoves is set to false, this means that when iterating through the keys, it will always check to make sure none of the servos are moving before going on to the next key.
void armAltRoutine() {
int numKeys = 1;
int del = 50; // 50 nice pace
ignoreMoves = false;
ignoreLights = true;
switch(keyStep) {
case 0: {
float poss[] = {headLeft, leftDown, rightUp};
float times[] = {del, 10};
servoUpdate(poss, times);
float vals[] = {128, 0, 255};
float ledtimez[] = {20, 10};
ledUpdate(vals, ledtimez);
}
break;
case 1: {
float poss[] = {headRight, leftUp, rightDown};
float times[] = {del, 10};
servoUpdate(poss, times);
float vals[] = {128, 0, 255};
float ledtimez[] = {20, 10};
ledUpdate(vals, ledtimez);
}
break;
}
keyStep++;
if(keyStep > numKeys) keyStep = 0;
}
Inside of loop() is where the 'switching' (as I call it) happens for doing the various routines. Each routine has a specific number, and when the current routine is that number ... well, then it will do that routine (duh!).
If the robot isn't in routine mode, then it will just do the idle behaviour, which is fading the hue of the LEDs.
if(routineMode) {
switch(currentRoutine) {
case 0:
if(ignoreLights && ignoreMoves) {
armAltRoutine();
} else if(ignoreLights && !ignoreMoves) {
if(!isMoving) armAltRoutine();
} else if(!ignoreLights && ignoreMoves) {
if(!isLighting) armAltRoutine();
} else if(!ignoreLights && !ignoreMoves) {
if(!isMoving && !isLighting) armAltRoutine();
}
break;
}
} else {
idleBehaviour();
}
Just in case you're curious, here is the idle behaviour. It uses the HSBColor library to change its hue!
void idleBehaviour() {
if(millis()-lastTick >= 100) {
int rgbz[3];
H2R_HSBtoRGB(hueCount, 25, 100, rgbz);
float vals[] = { (float)rgbz[0], (float)rgbz[1], (float)rgbz[2] };
float ledtimez[] = {5, 10};
ledUpdate(vals, ledtimez);
hueCount+=10; // 5 is cool, 10 is cool, 15 is fast
if(hueCount > 360) hueCount = 0;
lastTick = millis();
}
}
You can explore the rest of the code in the
example sketch, it is all quite similar to the above descriptions.