Home
Storyboard Game Play
BOM + Sourcing Infinity Mirror Sarcophagus Construction + Internal Walls Sarcophagus Lid Sarcophagus Exterior
Sarcophagus Lid + Egyptian Colors Sarcophagus Walls + Elements
System Design Code

Functionality: Code

Tinkerdoodles

Embedded Software

To implement the dynamical behavior of the system, we first encapsulated each behavioral component into its own separate function. Essentially, we created an API containing the functions listed below

  • fullyOpenLid() - retracts the linear actuator until the internal potentiometer reaches 873.
  • fullyCloseLid() - expands the linear actuator until the internal potentiometer reaches 690.
  • blinkAllLeds(ms) - blink al 9 LEDs without at a rate specified by the argument of the function. Implemented as nonblocking.
  • ledGroup1On23Off() - keep group 1 LEDs on, and groups 2 and 3 off.
  • ledGroup2On13Off() - keep group 2 LEDs on, and groups 1 and 3 off.
  • ledGroup3On12Off() - keep group 3 LEDs on, and groups 1 and 2 off.
  • allLedGroupsOn() - keep all 9 LEDs on.
  • playExperience1() - execute everything that needs to happen when level 1 is complete.
  • playExperience2() - execute everything that needs to happen when level 2 is complete.
  • playExperience3() - execute everything that needs to happen when level 3 is complete.


        

The entire code that makes this interactive user experience possible, including all the function definitions, is copied below.

#define ledGroup1Pin 13 //controls 3 leds all connected to the same pin #define ledGroup2Pin 12 //controls 3 leds #define ledGroup3Pin 11 //controls 3 leds #define scarab1Pin 7 #define scarab2Pin 6 #define scarab3Pin 5 #define actuatorIn1 3 #define actuatorIn2 4 #define relay1 A5 #define relay2 A4 #define relay3 A3 #define relay4 A2 #define potentiometerPin A1 #define masterBtnPin 2 unsigned long prevMillis = 0; // will store last time LED was updated bool LEDState = 1; //OFF, because active low bool reset = 0; bool blinkState = true; //blinking flag int btnPressCount=0; int btnReleaseCount=0; bool masterBtnHasBeenPressed=false; //master button to advance the level. bool scarabHasBeenPressed=false; bool experience1Complete=false; bool experience2Complete=false; bool experience3Complete=false; bool experience4Complete=false; int level=0; void setup() { pinMode(ledGroup1Pin, OUTPUT); pinMode(ledGroup2Pin, OUTPUT); pinMode(ledGroup3Pin, OUTPUT); pinMode(scarab1Pin, INPUT_PULLUP); pinMode(scarab2Pin, INPUT_PULLUP); pinMode(scarab3Pin, INPUT_PULLUP); pinMode(actuatorIn1,OUTPUT); pinMode(actuatorIn2,OUTPUT); pinMode(relay1,OUTPUT); pinMode(relay2,OUTPUT); pinMode(relay3,OUTPUT); pinMode(relay4,OUTPUT); digitalWrite(relay1,HIGH); digitalWrite(relay2,HIGH); digitalWrite(relay3,HIGH); digitalWrite(relay4,HIGH); pinMode(potentiometerPin, INPUT); pinMode(masterBtnPin, INPUT_PULLUP); } void loop() { //1. The LEDs are blinking when the user enters the room. //2. They have to touch the 3 beetles at the same time to get only one LED group lit. // a. set blinkState=false //3. We press the master button to advance the level. // a. set blinkState=true //4. The LEDs are blinking again. //5. The users press the 3 beatles. //6. We press the master button. // if(reset==true){ // blinkState=true; // level=0; // } //(1) LEDs are blinking. if(blinkState==true){ blinkAllLeds(300); //moveActuatorDown(500); //fullyOpenLid(); //fullyCloseLid(); //delay(1000); } else if(blinkState==false){ if(level==0) ledGroup1On23Off(); else if(level==1) ledGroup2On13Off(); else if(level==2) ledGroup3On12Off(); } //if all 3 scarabs are pressed, then set the blink flag to stop blinking if(digitalRead(scarab1Pin)==0 && digitalRead(scarab2Pin)==0 && digitalRead(scarab3Pin)==0){ //when all pressed blinkState=false; } //Users now have to find the corresponding glyphs on the wall and press them. For the demo, we will press a master button, //and then level1 will be unlocked. Sercophagus will do something. //MASTER BUTTON REPLACES THE FUNCTIONALITY OF THE INTERACTIVE WALL: //I want to increment the btnCount when the button is pressed and released. if(masterBtnHasBeenPressed==false && digitalRead(masterBtnPin) == 0){ //if btn has not been pressed before AND is now being pressed masterBtnHasBeenPressed=true; btnPressCount++; //register the pressing when the button is pressed. if(btnPressCount==5) btnPressCount=0; //reset the button press count in case the button ahs been pressed 5 times. } if(masterBtnHasBeenPressed==true && digitalRead(masterBtnPin)==1){ //if btn has been pressed nefore AND is not currently released masterBtnHasBeenPressed=false; //reset the flag btnReleaseCount++; //register the relese when the button is released. (we don't need this) if(btnReleaseCount==5) btnReleaseCount=0; } if(btnReleaseCount==1 && experience1Complete==false){ //move to the next level experience1Complete=true; playExperience1(); //The effect of the next 2 is on the 2nd if-block. blinkState=true; //start blinking all LEDs again level=1; //set the level to 1 } else if(btnReleaseCount==2 && experience2Complete==false){ experience2Complete=true; playExperience2(); //The effect of the next 2 is on the 2nd if-block. blinkState=true; //start blinking all LEDs again level=2; //set the level to 2. The effect of this } //Before we press the button for a third time, the last group of LEDs is ON, and so the blink state is false. //When players touch the wall for the final time, we press the master button, and then the entire coffin lits up. else if(btnReleaseCount==3 && experience3Complete==false){ experience3Complete=true; playExperience3(); level=3; //this is unnecessary, but can be used as a reset. fullyOpenLid(); } else if(btnReleaseCount==4 && experience4Complete==false){ experience4Complete=true; blinkState=true; level=0; fullyCloseLid(); btnReleaseCount=0; } //When we change the leve to level 3, what should happen then? //now I need to write what happens for the next 2 levels to the LEDs on the sercophagus. } void openLid(int milliseconds){ //use a while loop where the condition is the value on the pin. //run for the specified number of milliseconds int currenttime=millis(); while(millis()-currenttime < milliseconds){ digitalWrite(relay1,LOW); digitalWrite(relay4,LOW); } //enter break mode digitalWrite(relay2,HIGH); digitalWrite(relay3,HIGH); digitalWrite(relay1,HIGH); digitalWrite(relay4,HIGH); } void closeLid(int milliseconds){ //speed is from 0 to 255 //run for the specified number of milliseconds int currenttime=millis(); while(millis()-currenttime < milliseconds){ digitalWrite(relay2,LOW); digitalWrite(relay3,LOW); } //enter break mode digitalWrite(relay2,HIGH); digitalWrite(relay3,HIGH); digitalWrite(relay1,HIGH); digitalWrite(relay4,HIGH); } void blinkAllLeds(int interval){ //the argument is the time between blinks if(millis()-prevMillis >= interval){ prevMillis=millis(); LEDState=!LEDState; digitalWrite(ledGroup1Pin,LEDState); digitalWrite(ledGroup2Pin,LEDState); digitalWrite(ledGroup3Pin,LEDState); } } void ledGroup1On23Off(){ digitalWrite(ledGroup1Pin,LOW); digitalWrite(ledGroup2Pin,HIGH); digitalWrite(ledGroup3Pin,HIGH); } void ledGroup2On13Off(){ digitalWrite(ledGroup1Pin,HIGH); digitalWrite(ledGroup2Pin,LOW); digitalWrite(ledGroup3Pin,HIGH); } void ledGroup3On12Off(){ digitalWrite(ledGroup1Pin,HIGH); digitalWrite(ledGroup2Pin,HIGH); digitalWrite(ledGroup3Pin,LOW); } void allLedGroupsOn(){ digitalWrite(ledGroup1Pin,LOW); digitalWrite(ledGroup2Pin,LOW); digitalWrite(ledGroup3Pin,LOW); } void playExperience1(){ //playSound(); } void playExperience2(){ //lidRipple(); //fanOn(); } void playExperience3(){ allLedGroupsOn(); //turn all LEDS on the coffin on. //sarcophagusOpen(); //infinityMirrorOn(); } void fullyCloseLid(){ while(analogRead(potentiometerPin)>=690){ Serial.println(analogRead(potentiometerPin)); digitalWrite(relay2,LOW); digitalWrite(relay3,LOW); } digitalWrite(relay2,HIGH); digitalWrite(relay3,HIGH); } void fullyOpenLid(){ while(analogRead(potentiometerPin)<=883-10){ Serial.println(analogRead(potentiometerPin)); digitalWrite(relay1,LOW); digitalWrite(relay4,LOW); } digitalWrite(relay1,HIGH); digitalWrite(relay4,HIGH); }