Build Sheets

01 · Brief

The first game gets players into the ship’s controls. A set of alien artifacts sits on the table, metal canisters with a symbol on the lid and a coloured base. The same symbols appear on a locked panel on the main enclosure. There is a locked case present which requires a simple 3 digit code to unlock. That first clue is a word puzzle presented to the players in the initial game material they receive (ships log entries).

Once they have unlocked the case they are presented with a sensor, small screen, and a survey map showing where samples were taken. Holding a sample canister over the colour sensor reads the base and turns the colour into a two-digit code on the OLED. Matching symbols to codes gives the combination for the panel keypad. Opening the panel hardware lock is accomplished by reading the terrain map through a special physical template.

Everything runs standalone on the Nano. No link to the Pi, just a sensor, a screen, and props that do the storytelling.

02 · System

9 V RAIL5 V RAIL→ NANO
NANOTCS3200OLED

03 · Source

Escape_Game_Final_ColorSensor.ino

void loop() {
  // Setting S2 Low, S3 Low applies RED filtered photodiodes
  digitalWrite(S2, LOW);
  digitalWrite(S3, LOW);
  // Read the output frequency
  currentReading[0] = pulseIn(sensorOut, digitalRead(sensorOut) == HIGH ? LOW : HIGH);

  // Setting S2 High, S3 High applies GREEN filtered photodiodes
  digitalWrite(S2, HIGH);
  digitalWrite(S3, HIGH);
  // Reading the output frequency
  currentReading[1] = pulseIn(sensorOut,  digitalRead(sensorOut) == HIGH ? LOW : HIGH);

  // Setting S2 LOW, S3 HIGH applied BLUE filtered photodiodes
  digitalWrite(S2, LOW);
  digitalWrite(S3, HIGH);
  // Reading the output frequency
  currentReading[2] = pulseIn(sensorOut,  digitalRead(sensorOut) == HIGH ? LOW : HIGH);

  #ifdef CALIBRATE
    char rawOutput[32];
    snprintf(rawOutput, 32, "Raw sensor values: %lu,%lu,%lu" , currentReading[0], currentReading[1], currentReading[2]);
    Serial.println(rawOutput);
  #endif

  // Loop over each of the three measurements taken this frame 
  for (int i=0; i<3; i++) {
    // Use map() function to rescale values to the range of readings taken for white/black extremes
    int x = map(currentReading[i], blackReading[i], whiteReading[i], 0, 255);
    // Copy result back into the corresponding component of the RGB "colour" variable
    colour[i] = (byte)constrain(x, 0, 255);
  }

  // Send the RGB values to the serial monitor
  char output[32];
  snprintf(output, 32, "(%i,%i,%i)" , colour[0], colour[1], colour[2]);
  Serial.println(output);

  // The following code demonstrates how to perform some action if the colour detected
  // is similar enough to a specified target colour. First, specify the RGB values of the target
  int targetColourAR = 50, targetColourAG = 60, targetColourAB = 90; //(255,236,245) red (255,205,220)
  int targetColourBR = 115, targetColourBG = 120, targetColourBB = 90; //(232,238,251) blue (210,212,232)
  int targetColourCR = 90, targetColourCG = 90, targetColourCB = 100; //(248,255,238) green (232,240,213)
  // The threshold value determines how similar the colours have to be to match - higher values = less sensitive
  int threshold = 50;
  // Call the getColourDistance function to determine the distance between the colours, and compare to the threshold
  if(getColourDistance((int)colour[0], (int)colour[1], (int)colour[2], targetColourAR, targetColourAG, targetColourAB) < threshold) {
    Serial.println(F("The sensor has detected the target colour!"));
    displayValue = "17";

  } else if (getColourDistance((int)colour[0], (int)colour[1], (int)colour[2], targetColourBR, targetColourBG, targetColourBB) < threshold) {
    Serial.println(F("The sensor has detected the target colour!"));
    displayValue = "34";
  
  } else if (getColourDistance((int)colour[0], (int)colour[1], (int)colour[2], targetColourCR, targetColourCG, targetColourCB) < threshold) {
    Serial.println(F("The sensor has detected the target colour!"));
    displayValue = "86";
  } else {
    displayValue = ("...");
  }
  // Set the LEDs to match the colour detected
 showDisplay();

}
Lines 95–158 of 165 · Full source →

04 · Lessons

The Color sensor was very difficult to calibrate as I used construction paper for the canister colors. Not having black and white construction paper meant my color matching had to have a wide margin of error. To manage this I used Red, Green, and Blue as the only three colors that the sensor had to read correctly.