Dions Simpele Puzzelkistje!

by dionatsma in Circuits > Arduino

65 Views, 0 Favorites, 0 Comments

Dions Simpele Puzzelkistje!

Dions simpele puzzelkistje
IMG_7298.jpeg
IMG_7294.jpeg
IMG_7292.jpeg
IMG_7293.jpeg

Hoi, ik ben Dion Atsma, ik studeer Game Development aan de Hogeschool voor de Kunsten Utrecht, en ik heb voor het vak "If this, then that" een simpel puzzelkistje gemaakt met Arduino!

Het doel van de puzzel is om een kleur met een bepaalde helderheid te laten schijnen uit het RGB-LEDje. Dit kun je doen door 3 kleuren van licht (rood, groen en blauw) te mixen. In de zijkant van het doosje zitten 3 LEDjes, als er een LED aan staat dan betekent dit dat deze kleur ook aan staat in het RGB-LEDje. Aan de andere zijkant van het kistje zitten 3 knoppen, die alle 3 meerdere LEDjes aan of uit doen. Als het je lukt om de goede kleur te maken, kun je ook nog de helderheid aanpassen met de potentiometer aan de voorkant van het kistje. Als het je lukt om de goede kleur met de juiste helderheid te maken, wordt er een geluidje afgespeeld en draait er een Servomotor, zodat het kistje open gemaakt kan worden! 

Hoe je bepaalt wat de goede kleur is en wat voor prijs erin zit, kun je zelf bepalen. Ik heb zelf nu het kistje ingesteld op een gedimde magenta, waar de gebruiker achter kan komen door een rebus op te lossen. 

Supplies

  • Arduino Uno
  • RGB LED
  • Potentiometer
  • Buzzer
  • Servomotor
  • 3x drukknoppen
  • 3x 220 Ohm weerstanden
  • 1 rode LED
  • 1 groene LED
  • 1 blauwe LED


Voor het solderen heb ik gebruikt:

  • 4 printplaten
  • Soldeerbout
  • Soldeertin
  • Soldeerspons
  • Tinzuiger
  • Draden

Inspiratie

inspoA.png
InspoB.png

Ik ben bij dit project door een aantal puzzels geïnspireerd. Zo waren er een aantal Arduinoprojecten met een soortgelijk thema, ik vond deze hierboven (puzzel met 9 LEDS en 6 knoppen) erg leuk, maar iets te simpel voor wat ik wilde.

Ook ben ik geïnspireerd door de puzzels uit de Professor Layton games, deze zijn vaak klein en simpel met een enkele gimmick, wat ik zelf enorm leuk vind. Hierdoor overwoog ik aan het begin ook eerst om nog iets met cijfers te doen, maar ik merkte al snel dat het heel veel Arduino pins in beslag neemt om een paar cijfers weer te geven. Ik wilde dus focussen op een puzzel met net wat meer componenten dan het voorbeeld hierboven, maar ook weer niet iets wat zo ingewikkeld was dat het te veel pins zou gebruiken.


Links naar inspiraties:

https://www.instructables.com/Create-an-Electronic-Puzzle-Box/

https://www.instructables.com/Crack-the-Code-Game-Arduino-Based-Puzzle-Box/

https://www.instructables.com/Electronic-Puzzle-Box/

https://layton.fandom.com/wiki/Puzzle:A_Zero-Sum_Game

Tussenstappen

IMG_6921.jpeg
IMG_6917.jpeg
IMG_7026.jpeg

Ik had een aantal ideeën gekregen uit mijn inspiraties die ik wilde testen. Voornamelijk wilde ik kijken of ik de LED'jes met de drukknoppen aan en uit kon houden. Ik maakte een klein circuit waarbij beide knoppen twee verschillende LEDjes aan of uit deden, wat ik best leuk vond.

De volgende stap was het toevoegen van een RGB LED. Ik dacht veel na over kleur doordat ik 3 verschillende kleuren LEDjes gebruikte, dus leek het mij leuk om kleur in mijn puzzel te verwerken.

Het enige wat ik merkte dat ik nog miste, was iets van analoge input. Ik twijfelde tussen het gebruik van een lichtsensor en potentiometer, maar ik vond dat een lichtsensor moeilijker was om mee te werken voor het soort puzzel dat ik wilde, aangezien je dan ook nog een laser of zaklamp extra nodig zou hebben. Ik besloot de potentiometer te koppelen aan helderheid, omdat ik daar nu nog niets mee deed. Als laatste voegde ik ook nog een buzzer toe, het leek mij leuk om geluid te gebruiken, maar ik wist nog niet hoe ik het precies wilde inzetten.

Uiteindelijke Idee

Exquisite Fulffy.png
IMG_7065.jpeg
IMG_7025.jpeg

Mijn uiteindelijke idee bouwde verder op mijn experimenten. Ik merkte dat bij 2 knoppen je altijd maar 3 kleuren kon maken, dus maakte ik er 3 knoppen van. Ook besloot ik mijn RGB LED, dat voorheen vastzat aan mijn breadboard, gewoon in de lucht te laten hangen, dit bespaarde veel ruimte en zou later in het echte ontwerp ook enorm helpen. 

Ik wilde toch echt een kistje maken, maar ik wist niet hoe ik die precies open en dicht zou laten gaan van binnen. Ik wist wel zeker dat ik hier iets bewegends voor nodig had, en een servomotor leek mij de beste optie. 

Ik had nu alle componenten die ik wilde gebruiken klaar op mijn breadboard, en kreeg het ook redelijk werkend. Soms werkte de RGB LED niet (hierover later meer), maar over het algemeen werkte elk onderdeel. De buzzer liet ik een deuntje spelen zodra de puzzel was opgelost, om duidelijk aan te geven aan de gebruiker dat die het goed had.

Hierna ging ik mij voorbereiden op hoe ik mijn werk zou solderen. Ik had een aantal printplaten gekocht en tekende uit hoe en waar elk deel geplaatst moest worden. Later maakte ik hier een duidelijkere tekening van met behulp van Tinkercad (zie ook de pdf bijlage).

Solderen

IMG_7094.jpeg
IMG_7225.jpeg
IMG_7226.jpeg

Het solderen ging veel moeilijker dan ik dacht. Het werkte dan ook niet op de eerste, tweede, derde of vierde keer (de vijfde keer gelukkig wel). Achteraf snap ik veel beter wat misging.

Ik had in mijn hoofd dat mijn kistje erg klein zou zijn, dus maakte ik het werk heel compact. Hierdoor stonden er heel veel draden gespannen, wat ervoor zorgde dat deze later af zouden breken. Ook draaide ik de uiteindes van de draadjes niet goed genoeg, wat ze ook fragieler maakte. 

Bij mijn eindproduct zorgde ik ervoor dat ik met veel langere draadjes werkte (20 en 30 centimeter), wat alles veel makkelijker maakte. Ook soldeerde ik aan de achterkant van de bordjes, zodat de draadjes niet nog om het bordje heen moesten gaan als het in mijn kistje zou zitten. Als laatste plakte ik hete lijm op mijn draadjes, opnieuw om te voorkomen dat ze af zouden breken, wat goed werkte.

Coderen

Het coderen ging mij over het algemeen erg goed af. Ik heb mijn componenten opgedeeld in functies, zodat ik bij elk onderdeel apart kon bepalen wat er gebeurde. Je wint de game als de rode en blauwe LED aanstaan en de brightness (bepaald door de potentiometer) redelijk laag is. 

Het grootste probleem met mijn game werd veroorzaakt door de servomotor. Mijn pins 9 en 10 leken niet meer analoog te werken, en ik snapte maar niet waarom. Met hulp van mijn docent, Edwin van Ouwerkerk Moria, kwam ik erachter dan deze pinnetjes worden gebruikt door de servo library en daarom als digitale pinnetjes werken. Gelukkig had maar precies 4 componenten die analoge output nodig hadden (RGB LED 3x + Buzzer), dus kon ik mijn pinnetjes zo indelen dat mijn idee nog steeds werkte. 

Zie hieronder de code voor meer uitleg over de functionaliteit:

// ~ Simple Puzzle-Box ~
// By Dion Atsma, student at HKU games.


// In this program, the player's goal is to create a dim magenta light.
// Achieving this will open the box using the Servo.
// The player can mix colours by turning them on using the buttons,
// and change the brightness using the potentiometer.


#include <Servo.h>
#include "pitches.h"


// These control the different LEDS within the RGB-LED.
#define RGBred 3
#define RGBgreen 5
#define RGBblue 6


// These control individual coloured LED's.
#define LEDred 12
#define LEDgreen 2
#define LEDblue 4


// Buzzer and Servo for playing a sound and opening the box.
#define Buzzer 11
Servo servo;


// Three buttons to control the lights.
#define ButtonA 8
#define ButtonB 13
#define ButtonC 7


// A potentiometer to turn up the brightness of the lights.
#define TurnButton A1


// Concerns whether the LED's are on.
bool redOn = false;
bool blueOn = false;
bool greenOn = true;


// Brightness of the RGB-LED.
int brightness = 100;


// Boolean to check whether the player has solved the puzzle.
bool hasWon = false;


// Concerns the button states
bool stateA = false;
bool lastStateA = false;
bool stateB = false;
bool lastStateB = false;
bool stateC = false;
bool lastStateC = false;


// Notes in the melody that is played when the puzzle is solved:
int melody[] = {
  NOTE_G5, NOTE_FS5, NOTE_DS5, NOTE_A4, NOTE_GS4, NOTE_E5, NOTE_GS5, NOTE_C6
};


void setup() {
  Serial.begin(9600);


  pinMode(RGBred, OUTPUT);
  pinMode(RGBgreen, OUTPUT);
  pinMode(RGBblue, OUTPUT);
  pinMode(LEDred, OUTPUT);
  pinMode(LEDgreen, OUTPUT);
  pinMode(LEDblue, OUTPUT);


  pinMode(Buzzer, OUTPUT);
  servo.attach(9);


  pinMode(ButtonA, INPUT_PULLUP);
  pinMode(ButtonB, INPUT_PULLUP);
  pinMode(ButtonC, INPUT_PULLUP);


  pinMode(TurnButton, INPUT);
}


void loop() {
  // Constantly checks if the puzzle has been solved yet.
  checkWin();


  // If the player solves the puzzle, the lights turn off and stay off.
  if (hasWon) {
    turnTheLightsOff();
    Serial.println("Won");
    lightsTrue(redOn, LEDred, RGBred);
    lightsTrue(greenOn, LEDgreen, RGBgreen);
    lightsTrue(blueOn, LEDblue, RGBblue);
    return;
  }


  // Main functions that are constantly active.
  checkBrightness();
 
  buttonStates();
  lightsTrue(redOn, LEDred, RGBred);
  lightsTrue(greenOn, LEDgreen, RGBgreen);
  lightsTrue(blueOn, LEDblue, RGBblue);
}


// This function takes input from the potentiometer and maps it to
// work as a brightness for the LED's.
void checkBrightness() {
  int brightnessUnmapped = analogRead(TurnButton);
  brightness = map(brightnessUnmapped, 0, 1024, 0, 255);
}


// This function reads the current button state and the button state from the
// previous loop, and updates them every frame for each button.
void buttonStates() {
  stateA = digitalRead(ButtonA);
  lastStateA = checkState(stateA, lastStateA, ButtonA);


  stateB = digitalRead(ButtonB);
  lastStateB = checkState(stateB, lastStateB, ButtonB);


  stateC = digitalRead(ButtonC);
  lastStateC = checkState(stateC, lastStateC, ButtonC);
}


// This function compares the current state to the lastState of the buttons
// to see if this has changed, meaning the player has pressed the button.
// When this happens, some lights are turned on and off.
bool checkState(bool state, bool lastState, int pin) {
  if (state != lastState) {
    if (state == HIGH) {
      if (pin == 8) {
        onOffTwoThree();
      }
      else if (pin == 7) {
        onOffOneTwo();
      }
      else {
        onOffAll();
      }
    } else {
      Serial.println("off");
    }


    // Delay a little bit to avoid bouncing
    delay(50);
  }
  // save the current state as the last state, for next time through the loop
  lastState = state;
  return lastState;
}


// Checks if the puzzle has been solved, meaning:
// - The puzzle is not solved yet;
// - Only the Red and Blue LED are on (RGB-LED now emits Magenta light);
// - The light is dim but not off.
void checkWin() {
  if (brightness > 20 && brightness < 80
      && redOn && blueOn && !greenOn && !hasWon) {
        hasWon = true;
        win();
      }
}


// When the player wins, a sound is played and the servo moves.
void win() {
  // Play puzzle-solve jingle.
  playMusic();


  // Set Servo to open the box.
  servo.write(180);
}


// Plays the puzzle solve jingle from the Legend of Zelda series.
void playMusic() {
  for (int thisNote = 0; thisNote < 9; thisNote++) {
    int noteDuration = 1000 / 8;
    tone(Buzzer, melody[thisNote], noteDuration);


    int pauseBetweenNotes = noteDuration * 1.30;
    delay(pauseBetweenNotes);


    noTone(Buzzer);
  }
}


// Turns off all LED's.
void turnTheLightsOff() {
  redOn = false;
  greenOn = false;
  blueOn = false;
}


// Turns the red and green LED's on or off.
void onOffOneTwo() {
  redOn = !redOn;
  greenOn = !greenOn;
}


// Turns the blue and green LED's on or off.
void onOffTwoThree() {
  blueOn = !blueOn;
  greenOn = !greenOn;
}


// Turns all LED's on or off.
void onOffAll() {
  redOn = !redOn;
  blueOn = !blueOn;
  greenOn = !greenOn;
}


// This function checks for each colour of LED if they should currently
// be on or off (depending on their respective booleans), and turns
// the single LED's on or off, and gives the RGB-LED's the current
// brightness if they are on, or 0 brightness if they are off.
void lightsTrue(bool ledOn, int LED, int RGB) {
  if (ledOn) {
    digitalWrite(LED, HIGH);
    analogWrite(RGB, brightness);
  } else {
    digitalWrite(LED, LOW);
    analogWrite(RGB, 0);
  }
}


Downloads

Behuizing

IMG_7291.jpeg
IMG_7052.jpeg
IMG_7286.jpeg

Het was nog best lastig om het juiste kistje te vinden en om te bedenken hoe ik deze zou inrichten. Ik overwoog om een kistje te lasercutten, maar ik wilde het liefst iets meer authentieks. 

Om dit kistje te vinden, ging ik naar de beste bron van oude rotzooi: mijn oma's zolder. Hier vond ik een aantal kistjes, maar deze vond ik het best passen qua grootte. Ook had deze geen slot, wat essentieel was voor mijn idee. Het kistje zag er ook echt oud uit (omdat het dat is), wat goed paste bij mijn gewenste stijl.

Ik wilde de input aan een kant en de output aan de andere, dus boorde ik 3 gaatjes in beide zijkanten voor de 3 knoppen en 3 LEDjes, en 2 gaten aan de voorkant voor het RGB LEDje en de potentiometer. 

Het moeilijkste was het maken van het gleufje voor de servo, wat het kistje dicht zou houden. Met een mesje maakte ik een dunne gleuf aan de voorkant waar de servo mooi in paste, wat ook echt het kistje dicht leek te houden! 

Als laatste maakte ik nog een gat aan de achterkant voor de stroomkabel van de arduino, zodat ik deze aan een externe powerbank kon verbinden.

Mijn componenten plaatste ik in mijn kistje met tape, zodat deze zo minimaal mogelijk zouden bewegen en niet (opnieuw) kapot zouden gaan.

Het kistje was nu af en werkte precies zoals ik wilde!

Reflectie

Ik ben achteraf erg tevreden met dit project. Ik vind dat het mij best goed is gelukt om een simpele maar leuke puzzel te maken door een aantal verschillende componenten in te zetten. 

Ik heb tijdens dit project leren solderen, en hoewel dit niet altijd even goed lukte, kan ik met zekerheid zeggen dat ik het nu wel redelijk onder de knie heb!

Ik denk dat er ruimte is voor verbetering in de opbouw van de puzzel. Deze is nu alleen uit te leggen door een extern middel (in mijn geval een rebus), maar het liefst zou ik iets ontwerpen wat meer voor zichzelf spreek zonder al te ingewikkeld te zijn. In het vervolg ga ik vooral hier op focussen.

Bedankt voor het lezen, ik hoop dat je lol hebt met mijn puzzelkistje!