Teensy and Processing code after the video.
So this was my portion of a prototype 'miniature' RFID automated store room. The prototype was designed to take the functionality of the full-sized CribMaster Accuport , strip the mats out of the process, and replace them with buttons in order to allow the contraption to operate with a smaller footprint. This also meant that we really needed to make it so only one person was in the cage at a time. What better way than a colorful sign that asks people to wait their turn?
The door sign runs on a tiny Rapsberry-Pi-like SOC, the Asus Tinkerboard , chosen for its beefier cpu power over that of a regular Raspberry Pi. To transmit the 'state' of the RFID machine to the Tinkerboard, I programmed a Teensy 3.2 microcontroller to act as an HID device in order to receive signals from a relay and then send key presses to the Tinkerboard to manipulate the states of the door sign.
I had a lot of fun diving into Processing, though I really had to strip back my ambitions for the project due to the limits of the SOC running things. Having the ability to import SVG files to manipulate was exciting, but things slow way down when you start animating hundreds of vertices. However, simple shapes can also be a good time.
Processing Door Sign in action. Teensy 3.2 Code: /*
Based on the Buttons to USB Keyboard Example
*/
#include <Bounce.h>
Bounce button1 = Bounce(4, 10);
Bounce button2 = Bounce(11, 10);
void setup() {
pinMode(4, INPUT_PULLDOWN);
pinMode(11, INPUT_PULLDOWN);
}
void loop() {
button1.update();
button2.update();
if (button1.risingEdge()) {
Keyboard.println("o");
}
if (button2.risingEdge()) {
Keyboard.println("c");
}
}
Processing Code: //mcadoorsign_release_v1
DoorSignController ds;
void setup() {
size(1280,720,JAVA2D);
noCursor();
ds = new DoorSignController();
}
void draw() {
ds.loopDeLoop();
}
void keyPressed() {
ds.currentKey = key;
if(ds.currentKey == ds.lastKey) {
ds.counter++;
} else {
ds.counter = 0;
}
if(ds.counter == 0) {
if ((key == 'o') || (key == 'O')) {
//Matt's relay has sent the available signal
ds.state = 1;
}
if ((key == 'c') || (key == 'C')) {
//Matt's relay has sent the unavailable signal
ds.state = 3;
}
ds.lastKey = key;
if(ds.state != ds.lastState) {
ds.toUpdate = true;
ds.lastState = ds.state;
} else {
ds.toUpdate = false;
}
}
}
mcadoorsign_release_v1.pde class AnimationTimer {
// class variables
float start, runtime = 0;
//constructor
AnimationTimer() {
start = millis();
}
//methods
void update() {
runtime = millis() - start;
}
float getRuntime() {
return runtime;
}
void setStart() {
start = millis();
}
float getStart() {
return start;
}
}
AnimationTimer.pde class BackgroundController_new {
int counter;
int state = 0;
int mainAlpha = 255;
int x,y = 0;
int cols = 20;
int rows = 11;
int size;
color green = #207528;
color red = #530000;
color backgroundColor;
int wipingCounter;
int waitingCounter;
boolean wiping,holding;
int k = 0;
int lastK = 0;
ColorSquare[][] grid;
//constructor
BackgroundController_new(int[][] green, int[][] red, int[][][] alt) {
backgroundColor = color(0,0,0);
holding = true;
wiping = false;
wipingCounter = 1;
waitingCounter = 1;
size = (int)sqrt(((height/width)*width/height)*cols);
grid = new ColorSquare[cols][rows];
for(int i = 0; i < cols; i++) {
for(int j = 0; j < rows; j++) {
int x = (int)(i*width/(cols*1.0));
int y = (int)(j*height/(rows*1.0));
grid[i][j] = new ColorSquare(55,x+4,y+4,0,green,red,alt);
}
}
}
//methods
void update() {
drawOnCanvas();
}
void drawOnCanvas() {
if(state == 0) { // holding in green
holding = true;
wiping = false;
drawHolding();
}
if(state == 1) { // holding in red
holding = true;
wiping = false;
drawHolding();
}
if(state == 2) { // wiping to red
holding = false;
wiping = true;
drawWipingToRed();
}
if(state == 3) { // wiping to green
holding = false;
wiping = true;
drawWipingToGreen();
}
if(state == 4) { // wiping to alt color
holding = false;
wiping = true;
drawWipingToAlt();
}
if(state == 5) { // holding alt
holding = true;
wiping = false;
drawHolding();
}
}
void drawHolding() {
for(int i = 0; i < cols; i++) {
for(int j = 0; j < rows; j++) {
grid[i][j].holding();
fill(grid[i][j].C1,grid[i][j].C2,grid[i][j].C3);
rect(grid[i][j].xPos,grid[i][j].yPos,grid[i][j].size,grid[i][j].size);
}
}
}
void drawWipingToRed() {
for(int i = 0; i < cols; i++) {
for(int j = 0; j < rows; j++) {
grid[i][j].becomeRed();
}
}
state = 2;
drawHolding();
}
void drawWipingToGreen() {
for(int i = 0; i < cols; i++) {
for(int j = 0; j < rows; j++) {
grid[i][j].becomeGreen();
}
}
state = 0;
drawHolding();
}
void drawWipingToAlt() {
for(int i = 0; i < cols; i++) {
for(int j = 0; j < rows; j++) {
grid[i][j].becomeAlt(k);
}
}
state = 5;
drawHolding();
}
int makeRandomIndex() {
k = (int)random(0,grid[0][0].alts.length);
if(k == lastK) {
makeRandomIndex();
} else {
lastK = k;
}
return k;
}
}
BackgroundController.pde class ColorSquare {
int size;
int xPos;
int yPos;
int C1;
int C2;
int C3;
int newC1;
int newC2;
int newC3;
int[][] greens;
int[][] reds;
int[][][] alts;
int last;
int state = 0;
int type; //0 is a greeney, 1 is a reddy
boolean start,fading,changing;
int greenCounter;
int redCounter;
int fadeCounter;
int fadeSteps;
int c1FadeAmt = 0;
int c2FadeAmt = 0;
int c3FadeAmt = 0;
int clrNmbr;
//constructor
ColorSquare(int sz, int x, int y, int t, int[][] gr, int[][] rd, int[][][] alt) {
size = sz;
xPos = x;
yPos = y;
type = t;
greens = gr;
reds = rd;
alts = alt;
fadeSteps = (int)random(45,75);
fadeCounter = 0;
start = true;
fading = false;
changing = true;
last = (int)random(0,2);
if(type == 0) {
pickRandomGreen();
start = false;
pickRandomGreen();
}
if(type == 1) {
pickRandomRed();
start = false;
pickRandomRed();
}
if(type == 2) {
pickRandomAlt();
start = false;
pickRandomAlt();
}
}
//methods
void pickRandomGreen() {
int i = (int)random(0,greens.length);
if(i != last) {
if(start) {
C1 = greens[i][0];
C2 = greens[i][1];
C3 = greens[i][2];
} else {
newC1 = greens[i][0];
newC2 = greens[i][1];
newC3 = greens[i][2];
}
last = i;
} else {
pickRandomGreen();
}
}
void pickRandomRed() {
int i = (int)random(0,reds.length);
if(i != last) {
if(start) {
C1 = reds[i][0];
C2 = reds[i][1];
C3 = reds[i][2];
} else {
newC1 = reds[i][0];
newC2 = reds[i][1];
newC3 = reds[i][2];
}
last = i;
} else {
pickRandomRed();
}
}
void pickRandomAlt() {
//int i = (int)random(0,alts.length);
int j = (int)random(0,alts[clrNmbr].length);
if(j != last) {
if(start) {
C1 = alts[clrNmbr][j][0];
C2 = alts[clrNmbr][j][1];
C3 = alts[clrNmbr][j][2];
} else {
newC1 = alts[clrNmbr][j][0];
newC2 = alts[clrNmbr][j][1];
newC3 = alts[clrNmbr][j][2];
}
last = clrNmbr;
} else {
pickRandomAlt();
}
}
//this is the main loop for the square
void drawSquare() {
if(state == 0) {
holding();
}
if(state == 1) {
becomeGreen();
}
if(state == 2) {
becomeRed();
}
if(state == 3) {
becomeAlt((int)random(0,alts.length - 1));
}
}
void holding() {
if(changing) {
//get new random color in set
if(type == 0) {
pickRandomGreen();
}
if(type == 1) {
pickRandomRed();
}
if(type == 2) {
pickRandomAlt();
}
changing = false;
fading = true;
fadeSteps = (int)random(45,75);
holding();
}
if(fading) {
C1 = (int)lerp(C1,newC1,0.07);
C2 = (int)lerp(C2,newC2,0.07);
C3 = (int)lerp(C3,newC3,0.07);
fadeCounter+=1;
if(fadeCounter == fadeSteps) {
fading = false;
changing = true;
fadeCounter = 1;
}
}
}
int fadeColor(int in, int amt) {
return in + amt;
}
void becomeGreen() {
type = 0;
}
void becomeRed() {
type = 1;
}
void becomeAlt(int randomClr) {
clrNmbr = randomClr;
type = 2;
}
}
ColorSquare.pde class Logo {
boolean drawFadeIn, drawHold, drawFadeOut, off = false;
PShape mcaLogo, mca, ind;
color rectColor = color(0,0,0);
DoorSign parent;
PShape grp;
PShape[] theLetters;
PShape theMessageShape;
int alpha = 255;
float ratio = 0.9;
int rectAlpha = 0;
int finalRectAlpha = 229;
int offCounter;
int fadingCounter;
int x,y,targetX,targetY;
boolean moveUp, moveDown, hold;
float lerpAmount = 0.06;
float fadeLerpAmount = 0.2;
//constructor
Logo() {
off = true;
fadingCounter = 0;
rectAlpha = (int)(alpha * ratio);
mcaLogo = loadShape("mcalogo.svg");
mca = mcaLogo.getChild("MCA");
ind = mcaLogo.getChild("INDUSTRIAL");
mca.disableStyle();
ind.disableStyle();
x = 0;
y = 721;
targetX =0;
targetY = 389+65;
hold = true;
moveUp = false;
moveDown = false;
}
//methods
void draw() {
if(drawFadeIn) {
fadeIn();
}
if(drawHold) {
messageHold();
}
if(drawFadeOut) {
fadeOut();
}
if(off) {
off();
}
}
void fadeIn() {
if(fadingCounter == 0) {
alpha = 0;
rectAlpha = 0;
}
updateFadeCounters();
float b;
if(alpha < 255) {
stroke(0,0,0,alpha);
strokeWeight(4);
fill(rectColor,rectAlpha);
rect(0,y,width,200);
noStroke();
fill(255,255,255,alpha);
shape(mca,50,y);
fill(235,34,40,alpha);
shape(ind,50,y);
b = (int)lerp(alpha,255,fadeLerpAmount);
alpha = (int)b;
if(alpha >= 250) {
alpha = 255;
}
rectAlpha = (int)(alpha * ratio);
if(rectAlpha > finalRectAlpha) {
rectAlpha = finalRectAlpha;
}
} else {
stroke(0,0,0,alpha);
strokeWeight(4);
fill(rectColor,rectAlpha);
rect(0,y,width,200);
noStroke();
fill(255,255,255,alpha);
shape(mca,50,y);
fill(235,34,40,alpha);
shape(ind,50,y);
}
if(alpha == 255) {
off = false;
drawFadeIn = false;
drawHold = true;
}
}
void messageHold() {
fadingCounter = 0;
alpha = 255;
rectAlpha = (int)(alpha * ratio);
off = false;
drawFadeIn = false;
drawFadeOut = false;
stroke(0,0,0,alpha);
strokeWeight(4);
fill(rectColor,rectAlpha);
rect(0,y,width,200);
noStroke();
fill(255,255,255,alpha);
shape(mca,50,y);
fill(235,34,40,alpha);
shape(ind,50,y);
}
void fadeOut() {
if(fadingCounter == 0) {
alpha = 255;
rectAlpha = (int)(alpha * ratio);
}
updateFadeCounters();
float b;
if(alpha > 0) {
stroke(0,0,0,alpha);
strokeWeight(4);
fill(rectColor,rectAlpha);
rect(0,y,width,200);
noStroke();
fill(255,255,255,alpha);
shape(mca,50,y);
fill(235,34,40,alpha);
shape(ind,50,y);
b = (int)lerp(alpha,0,fadeLerpAmount);
alpha = (int)b-1;
rectAlpha = (int)(alpha * ratio);
} else {
alpha = 0;
stroke(0,0,0,alpha);
strokeWeight(4);
fill(rectColor,rectAlpha);
rect(0,y,width,200);
noStroke();
fill(255,255,255,alpha);
shape(mca,50,y);
fill(235,34,40,alpha);
shape(ind,50,y);
}
if(alpha == 0) {
drawFadeOut = false;
drawHold = false;
off = true;
}
}
void moveUp() {
float b;
if(y > targetY) {
b = (int)lerp(y,targetY,lerpAmount);
y = (int)b-1;
} else {
moveUp = false;
hold = true;
y = targetY;
}
}
void moveDown() {
float b;
if(y < targetY) {
b = (int)lerp(y,targetY,lerpAmount);
y = (int)b+1;
} else {
moveDown = false;
drawHold = false;
hold = false;
off = true;
y = targetY;
}
}
void updateFadeCounters() {
fadingCounter+=1;
if(fadingCounter > 5) {
fadingCounter = 1;
}
}
}
Logo.pde class Message {
boolean drawFadeIn, drawHold, drawFadeOut, off = false;
DoorSign parent;
PShape grp;
PShape[] theLetters;
PShape theMessageShape;
int alpha;
int offCounter;
int x,y,targetX,targetY;
boolean moveUp, moveDown, hold;
float lerpAmount = 0.1;
float fadeLerpAmount = 0.2;
color rectColor = color(28,28,28);
int rectSize = 328;
float ratio = 0.6;
int rectAlpha;
int finalRectAlpha = 140;
int fadingCounter = 0;
//constructor
Message(int type, DoorSign theParent) {
parent = theParent;
if(type == 0) {
grp = loadShape("available.svg");
drawHold = true;
drawFadeIn = false;
drawFadeOut = false;
off = false;
alpha = 255;
rectAlpha = (int)(alpha * ratio);
}
if(type == 1) {
grp = loadShape("inuse.svg");
drawHold = false;
drawFadeIn = false;
drawFadeOut = false;
off = true;
alpha = 0;
rectAlpha = 0;
}
grp.disableStyle();
x = 0;
y = 0;
targetX =0;
targetY = -360;
hold = true;
moveUp = false;
moveDown = false;
}
void draw() {
if(drawFadeIn) {
fadeIn();
}
if(drawHold) {
messageHold();
}
if(drawFadeOut) {
fadeOut();
}
if(off) {
off();
}
}
void fadeIn() {
if(fadingCounter == 0) {
alpha = 0;
rectAlpha = 0;
}
updateFadeCounters();
if(alpha < 255) {
stroke(0,0,0,alpha);
strokeWeight(4);
fill(rectColor,rectAlpha);
rect(0,y+193,width,rectSize);
noStroke();
fill(color(255,255,255,alpha));
shape(grp,x,y);
alpha = (int)lerp(alpha,255,fadeLerpAmount);
if(alpha >= 250) {
alpha = 255;
}
rectAlpha = (int)(alpha * ratio);
if(rectAlpha > finalRectAlpha) {
rectAlpha = finalRectAlpha;
}
} else {
stroke(0,0,0,alpha);
strokeWeight(4);
fill(rectColor,rectAlpha);
rect(0,y+193,width,rectSize);
noStroke();
fill(color(255,255,255,alpha));
shape(grp,x,y);
}
if(alpha == 255 && parent.timeWaited > parent.waitTime) {
off = false;
drawFadeIn = false;
drawHold = true;
}
}
void messageHold() {
fadingCounter = 0;
off = false;
drawFadeIn = false;
drawFadeOut = false;
stroke(0,0,0,alpha);
strokeWeight(4);
fill(rectColor,rectAlpha);
rect(0,y+193,width,rectSize);
noStroke();
fill(color(255,255,255));
shape(grp,x,y);
}
void fadeOut() {
if(fadingCounter == 0) {
alpha = 255;
rectAlpha = (int)(alpha * ratio);
}
updateFadeCounters();
if(alpha > 0) {
stroke(0,0,0,alpha);
strokeWeight(4);
fill(rectColor,rectAlpha);
rect(0,y+193,width,rectSize);
noStroke();
fill(color(255,255,255,alpha));
shape(grp,x,y);
alpha = (int)lerp(alpha,0,fadeLerpAmount);
rectAlpha = (int)(alpha * ratio);
} else {
alpha = 0;
rectAlpha = 0;
stroke(0,0,0,alpha);
strokeWeight(4);
fill(rectColor,rectAlpha);
rect(0,y+193,width,rectSize);
noStroke();
fill(color(255,255,255,alpha));
shape(grp,x,y);
}
if(alpha == 0) {
drawFadeOut = false;
drawHold = false;
off = true;
}
}
void moveUp() {
float b;
if(y > targetY) {
b = (int)lerp(y,targetY,lerpAmount);
y = (int)b-1;
} else {
moveUp = false;
hold = true;
y = targetY;
}
}
void moveDown() {
if(y < targetY) {
y = (int)lerp(y,targetY,lerpAmount);
} else {
moveDown = false;
hold = true;
y = targetY;
}
}
void updateFadeCounters() {
fadingCounter+=1;
if(fadingCounter > 5) {
fadingCounter = 1;
}
}
}
Message.pde class DoorSign {
Logo logo;
Message ava;
Message inUse;
BackgroundController_new aBack;
AllTheColors someColors;
color theColor, theBackgroundColor;
int counter = 0;
int transformCounter = 0;
int availableCounter = 0;
int unavailableCounter = 0;
int fadingCounter = 0;
int runCounter = 0;
// Door sign operation variables
boolean available, becomingAvailable, unavailable, becomingUnavailable,transformAvailable,recheck;
AnimationTimer waitTimer,displayTimer;
float timeWaited = 0;
float waitTime = 1000;
float displayTime = 20000;
boolean availableState,unavailableState;
DoorSignController parent;
int randomIndex = 0;
//constructor
DoorSign() {
someColors = new AllTheColors();
logo = new Logo();
ava = new Message(0,this);
inUse = new Message(1,this);
aBack = new BackgroundController_new(someColors.greens,someColors.reds,someColors.alts);
waitTimer = new AnimationTimer();
waitTimer.setStart();
displayTimer = new AnimationTimer();
displayTimer.setStart();
available = true;
becomingAvailable = false;
unavailable = false;
becomingUnavailable = false;
inUse.alpha = 0;
inUse.off = true;
inUse.drawHold = false;
inUse.drawFadeIn = false;
inUse.drawFadeOut = false;
ava.alpha = 255;
ava.drawHold = true;
ava.off = false;
ava.drawFadeIn = false;
ava.drawFadeOut = false;
aBack.state = 1;
availableState = false;
unavailableState = false;
logo.off = true;
}
//methods
void draw() {
noStroke();
aBack.update();
waitTimer.update();
displayTimer.update();
//if available, check the displayTimer
if(available) {
// if the display time limit has been reached, switch to opposite states
if(displayTimer.getRuntime() > displayTime) {
availableState = !availableState;
unavailableState = !unavailableState;
if(availableState) {
ava.moveUp = true;
ava.moveDown = false;
ava.hold = false;
ava.targetY = -130; // to move up
logo.off = false;
logo.moveUp = true;
logo.moveDown = false;
logo.hold = false;
logo.drawHold = true;
logo.targetY = 389+65;
aBack.state = 4;
randomIndex = aBack.makeRandomIndex();
}
if(!availableState) {
ava.moveUp = false;
ava.moveDown = true;
ava.hold = false;
ava.targetY = 0; // back down
logo.moveUp = false;
logo.moveDown = true;
logo.hold = false;
logo.targetY = 721;
aBack.state = 3;
}
transformAvailable = true;
available = false;
runCounter+=1;
if(runCounter < 10) {
runCounter = 1;
}
}
} //end of available displayTimer check
// if in the normal state
if(availableState) { //normal state
if(available) {
drawAvailable(); // draw the regular availabe
}
if(becomingAvailable) {
drawBecomingAvailableAlt(); // draw the regular becoming available
}
if(transformAvailable) {
drawTransformAvailable();
}
}
// if in the alternate state
if(!availableState) { //alternate state
if(available) {
// draw alternate available
drawAvailable();
}
if(becomingAvailable) {
// draw alternate becoming available
drawBecomingAvailable();
}
if(transformAvailable) {
drawTransformAvailableAlt(); // draw the alternate transform back to normal state available
}
}
// if in the normal state
if(unavailableState) { // normal state
if(unavailable) {
drawUnavailable(); // draw unavailable
}
if(becomingUnavailable) {
drawBecomingUnavailableAlt(); // draw normal becoming unavailalbe
}
}
// if in the alternate state
if(!unavailableState) { //alternate state
if(unavailable) {
drawUnavailable();
}
if(becomingUnavailable) {
// draw the alternate becoming unavailable state in
// which both the available and McAuliffe's logo fade out.
drawBecomingUnavailableAlt();
}
}
}
//===== DRAW METHODS BASED ON STATE OF THE DOOR SIGN ====
void drawBecomingUnavailableAlt() {
if(fadingCounter == 0) {
inUse.alpha = 0;
ava.alpha = 255;
logo.alpha = 255;
}
if(!ava.off) {
ava.drawHold = false;
ava.drawFadeOut = true;
logo.drawHold = false;
logo.drawFadeOut = true;
logo.draw();
ava.draw();
updateFadeCounters();
} else if(ava.off && !inUse.drawHold) {
timeWaited = waitTimer.getRuntime();
if(timeWaited > waitTime) {
inUse.off = false;
inUse.drawFadeIn = true;
inUse.draw();
updateFadeCounters();
}
} else if(ava.off && logo.off && inUse.drawHold) {
becomingUnavailable = false;
unavailable = true;
fadingCounter = 0;
inUse.draw();
randomIndex = aBack.makeRandomIndex();
logo.rectColor = color(aBack.grid[0][0].alts[aBack.k][3][0],aBack.grid[0][0].alts[aBack.k][3][1],aBack.grid[0][0].alts[aBack.k][3][2]);
}
}
void drawBecomingAvailableAlt() {
color(aBack.grid[0][0].alts[aBack.k][3][0],aBack.grid[0][0].alts[aBack.k][3][1],aBack.grid[0][0].alts[aBack.k][3][2]);
if(fadingCounter == 0) {
ava.alpha = 0;
logo.alpha = 0;
logo.rectAlpha = 0;
inUse.alpha = 255;
}
fadingCounter+=1;
if(fadingCounter > 5) {
fadingCounter = 1;
}
if(!inUse.off) {
inUse.drawHold = false;
inUse.drawFadeOut = true;
inUse.draw();
updateFadeCounters();
} else if(inUse.off && !ava.drawHold) {
timeWaited = waitTimer.getRuntime();
if(timeWaited > waitTime) {
ava.off = false;
ava.drawFadeIn = true;
logo.off = false;
logo.drawFadeIn = true;
logo.draw();
ava.draw();
updateFadeCounters();
}
} else if(inUse.off && ava.drawHold && logo.drawHold) {
becomingAvailable = false;
available = true;
logo.draw();
ava.draw();
}
}
// this method, we are starting normal available, moving up the
// available message, and bringing in the mcauliffe's logo
void drawTransformAvailable() {
if(transformCounter == 0) {
randomIndex = aBack.makeRandomIndex();
logo.rectColor = color(aBack.grid[0][0].alts[aBack.k][3][0],aBack.grid[0][0].alts[aBack.k][3][1],aBack.grid[0][0].alts[aBack.k][3][2]);
}
transformCounter+=1;
if(transformCounter > 10) {
transformCounter = 1;
}
// make sure that when the ava y coordinate is at the
// targetY to set the moveUp to false and the hold to true
if(ava.moveUp) {
ava.moveUp();
}
if(logo.moveUp) {
logo.moveUp();
}
ava.draw();
logo.draw();
if(ava.hold && logo.hold) {
transformAvailable = false;
available = true;
displayTimer.setStart();
transformCounter = 0;
}
} // END OF DRAWTRANSFORMAVAILABLE()
// this method changes the avilable message from the alternate
// state back to the normal state available message without the logo.
void drawTransformAvailableAlt() {
if(ava.moveDown) {
ava.moveDown();
}
if(logo.moveDown) {
logo.moveDown();
}
ava.draw();
logo.draw();
if(ava.hold && logo.off) {
transformAvailable = false;
available = true;
displayTimer.setStart();
}
}
void drawAvailable() {
fadingCounter = 0;
ava.drawHold = true;
inUse.off = true;
ava.draw();
if(!logo.off) {
logo.draw();
}
}
void drawAvailableAlt() {
fadingCounter = 0;
ava.drawHold = true;
inUse.off = true;
ava.draw();
logo.draw();
}
void drawBecomingAvailable() {
if(fadingCounter == 0) {
ava.alpha = 0;
inUse.alpha = 255;
}
if(!inUse.off) {
inUse.drawHold = false;
inUse.drawFadeOut = true;
inUse.draw();
updateFadeCounters();
} else if(inUse.off && !ava.drawHold) {
timeWaited = waitTimer.getRuntime();
if(timeWaited > waitTime) {
ava.off = false;
ava.drawFadeIn = true;
ava.draw();
updateFadeCounters();
}
} else if(inUse.off && ava.drawHold) {
becomingAvailable = false;
available = true;
ava.draw();
}
fadingCounter+=1;
if(fadingCounter > 5) {
fadingCounter = 1;
}
}
void drawUnavailable() {
fadingCounter = 0;
inUse.drawHold = true;
ava.off = true;
inUse.draw();
}
void drawBecomingUnavailable() {
if(fadingCounter == 0) {
inUse.alpha = 0;
ava.alpha = 255;
}
if(!ava.off) {
ava.drawHold = false;
ava.drawFadeOut = true;
ava.draw();
updateFadeCounters();
} else if(ava.off && !inUse.drawHold) {
timeWaited = waitTimer.getRuntime();
if(timeWaited > waitTime) {
inUse.off = false;
inUse.drawFadeIn = true;
inUse.draw();
updateFadeCounters();
}
} else if(ava.off && inUse.drawHold) {
becomingUnavailable = false;
unavailable = true;
randomIndex = aBack.makeRandomIndex();
logo.rectColor = color(aBack.grid[0][0].alts[aBack.k][3][0],aBack.grid[0][0].alts[aBack.k][3][1],aBack.grid[0][0].alts[aBack.k][3][2]);
fadingCounter = 0;
inUse.draw();
}
}
void updateFadeCounters() {
fadingCounter+=1;
if(fadingCounter > 5) {
fadingCounter = 1;
}
}
void update() {
waitTimer.update();
}
void makeBecomingAvailable() {
becomingAvailable = true;
becomingUnavailable = false;
unavailable = false;
available = false;
if(availableState) {
aBack.state = 4;
logo.rectColor = color(aBack.grid[0][0].alts[aBack.k][3][0],aBack.grid[0][0].alts[aBack.k][3][1],aBack.grid[0][0].alts[aBack.k][3][2]);
} else {
aBack.state = 3;
}
waitTimer.setStart();
displayTimer.setStart();
}
void makeBecomingUnavailable() {
becomingAvailable = false;
available = false;
becomingUnavailable = true;
unavailable = false;
aBack.state = 2;
waitTimer.setStart();
displayTimer.setStart();
}
}
DoorSign.pde class DoorSignController {
DoorSign doorSign;
char lastKey;
char currentKey;
int counter;
int state; //0 available, 1 becomingAvailable, 2 unavailable, 3 becomingUnavailable
int lastState;//
boolean recheck;
boolean toUpdate;
boolean updateColors;
//constructor
DoorSignController() {
recheck = false;
toUpdate = false;
updateColors = false;
doorSign = new DoorSign();
lastKey = 'o';
counter = 0;
state = 0;
lastState = 0;
}
//methods
void loopDeLoop() {
background(doorSign.aBack.backgroundColor);
checkState(); // check for new button presses?
doorSign.update();
doorSign.draw();
//println(frameRate);
}
void checkState() {
if(toUpdate) {
if(doorSign.available || doorSign.unavailable) {
if(state == 1) {
doorSign.makeBecomingAvailable();
toUpdate = false;
state = 0;
}
if(state == 3) {
doorSign.makeBecomingUnavailable();
toUpdate = false;
state = 2;
}
}
}
}
void updateColors() {
doorSign.randomIndex = doorSign.aBack.makeRandomIndex();
doorSign.logo.rectColor = color(doorSign.aBack.grid[0][0].alts[doorSign.aBack.k][3][0],doorSign.aBack.grid[0][0].alts[doorSign.aBack.k][3][1],doorSign.aBack.grid[0][0].alts[doorSign.aBack.k][3][2]);
updateColors = false;
}
}
DoorSignController.pde class AllTheColors {
int[][] greens;
int[][] reds;
int[][][] alts;
//midGreen
int mgC1 = 78;
int mgC2 = 130;
int mgC3 = 0;
//midLightGreen
int mlgC1 = 115;
int mlgC2 = 173;
int mlgC3 = 27;
//darkGreen
int dgC1 = 66;
int dgC2 = 102;
int dgC3 = 13;
//lightGreen
int lgC1 = 155;
int lgC2 = 255;
int lgC3 = 0;
//midRed
int mrC1 = 174;
int mrC2 = 0;
int mrC3 = 0;
//midLightRed
int mlrC1 = 229;
int mlrC2 = 0;
int mlrC3 = 0;
//darkRed
int drC1 = 119;
int drC2 = 1;
int drC3 = 1;
//lightRed
int lrC1 = 255;
int lrC2 = 12;
int lrC3 = 12;
//midBlue
int mbC1 = 13;
int mbC2 = 89;
int mbC3 = 170;
//midLightBlue
int mlbC1 = 0;
int mlbC2 = 115;
int mlbC3 = 239;
//darkBlue
int dbC1 = 11;
int dbC2 = 95;
int dbC3 = 186;
//lightBlue
int lbC1 = 93;
int lbC2 = 170;
int lbC3 = 252;
// light purple
int lpC1= 239;
int lpC2= 93;
int lpC3= 212;
// mid light purple
int mlpC1= 237;
int mlpC2= 64;
int mlpC3= 205;
// mid purple
int mpC1= 160;
int mpC2= 25;
int mpC3= 135;
// dark purple
int dpC1= 76;
int dpC2= 0;
int dpC3= 62;
// light yellow
int lyC1= 255;
int lyC2= 255;
int lyC3= 73;
// mid light yellow
int mlyC1= 247;
int mlyC2= 247;
int mlyC3= 2;
// mid yellow
int myC1= 216;
int myC2= 216;
int myC3= 2;
// dark yellow
int dyC1= 200;
int dyC2= 200;
int dyC3= 0;
// light some other color
int ltC1= 200;
int ltC2= 200;
int ltC3= 200;
// mid light some other color
int mltC1= 128;
int mltC2= 128;
int mltC3= 128;
// mid some other color
int mtC1= 49;
int mtC2= 49;
int mtC3= 49;
// dark some other color
int dtC1= 0;
int dtC2= 0;
int dtC3= 0;
//constructor
AllTheColors() {
makeColorArrays();
}
//methods
void makeColorArrays() {
greens = new int[4][3];
reds = new int[4][3];
alts = new int[4][4][3];
makeAlts();
greens[0][0] = lgC1;
greens[0][1] = lgC2;
greens[0][2] = lgC3;
greens[1][0] = mlgC1;
greens[1][1] = mlgC2;
greens[1][2] = mlgC3;
greens[2][0] = mgC1;
greens[2][1] = mgC2;
greens[2][2] = mgC3;
greens[3][0] = dgC1;
greens[3][1] = dgC2;
greens[3][2] = dgC3;
reds[0][0] = lrC1;
reds[0][1] = lrC2;
reds[0][2] = lrC3;
reds[1][0] = mlrC1;
reds[1][1] = mlrC2;
reds[1][2] = mlrC3;
reds[2][0] = mrC1;
reds[2][1] = mrC2;
reds[2][2] = mrC3;
reds[3][0] = drC1;
reds[3][1] = drC2;
reds[3][2] = drC3;
}
void makeAlts() {
alts[0][0][0] = lbC1;
alts[0][0][1] = lbC2;
alts[0][0][2] = lbC3;
alts[0][1][0] = mlbC1;
alts[0][1][1] = mlbC2;
alts[0][1][2] = mlbC3;
alts[0][2][0] = mbC1;
alts[0][2][1] = mbC2;
alts[0][2][2] = mbC3;
alts[0][3][0] = dbC1;
alts[0][3][1] = dbC2;
alts[0][3][2] = dbC3;
alts[1][0][0] = lpC1;
alts[1][0][1] = lpC2;
alts[1][0][2] = lpC3;
alts[1][1][0] = mlpC1;
alts[1][1][1] = mlpC2;
alts[1][1][2] = mlpC3;
alts[1][2][0] = mpC1;
alts[1][2][1] = mpC2;
alts[1][2][2] = mpC3;
alts[1][3][0] = dpC1;
alts[1][3][1] = dpC2;
alts[1][3][2] = dpC3;
alts[2][0][0] = lyC1;
alts[2][0][1] = lyC2;
alts[2][0][2] = lyC3;
alts[2][1][0] = mlyC1;
alts[2][1][1] = mlyC2;
alts[2][1][2] = mlyC3;
alts[2][2][0] = myC1;
alts[2][2][1] = myC2;
alts[2][2][2] = myC3;
alts[2][3][0] = dyC1;
alts[2][3][1] = dyC2;
alts[2][3][2] = dyC3;
alts[3][0][0] = ltC1;
alts[3][0][1] = ltC2;
alts[3][0][2] = ltC3;
alts[3][1][0] = mltC1;
alts[3][1][1] = mltC2;
alts[3][1][2] = mltC3;
alts[3][2][0] = mtC1;
alts[3][2][1] = mtC2;
alts[3][2][2] = mtC3;
alts[3][3][0] = dtC1;
alts[3][3][1] = dtC2;
alts[3][3][2] = dtC3;
}
}
AllTheColors.pde Now that I've gone and looked through all this code again for the first time in a few years, I'm a) realizing that I could probably reformat things to tidy it up a little (sooo many variables for the colors ) and b) feeling pretty good I pulled this one off given it was my first foray into Processing. My door sign has been running 24/7 for about 4 years now without a hitch :D