Dobbelsteen met aanraakschakelaar

In werkelijkheid geven de leds mooi blauw licht, maar mijn camera kan dat niet weergeven.
Raak de bovenkant aan en de dobbelsteen gaat "rollen".
Benodigde materialen:

Bouwbeschrijving

niet heel makkelijk
niet heel makkelijk,
maar goed te doen
Zoek een geschikt doosje (rond of vierkant) en verf dat in vrolijke kleuren. Eindig met een laklaag. Teken op de deksel de plaats van de ledjes af. Prik of boor gaatjes van ca 1 mm waar de ledjes in passen. Breng de 7 ledjes aan, steeds met het lange pootje naar dezelfde kant. Lijm de ledjes aan de binnenkant van de deksel vast met behulp van een lijmpistool of buig de pootjes strak tegen de deksel. Soldeer aan de aanraakschakelaars drie draden, liefst in de kleuren zwart (GND), rood (VCC) en geel (I/O). Duw hiertoe de draden vanaf de achterkant door de gaatjes en soldeer ze aan de voorkant. Gebruik weinig soldeertin en knip overtollige stukjes draad aan de voorzijde weg, zodat de schakelaars zo plat mogelijk zijn. Lijm de schakelaars aan de binnenkant van de deksel tussen de ledjes waar je de meeste vrije ruimte hebt, zo dat de schakelaar zo ver mogelijk van andere draden blijft. Verbind alle korte pootjes van de leds met elkaar en met GND van de beide schakelaars en met GND van de Arduino. Verbind de aarde ook via een niet te kort draadje met de buzzer. De buzzer kan los in het doosje komen te liggen, maar als je een heel dik doosje hebt, dan moet je de buzzer buiten het doosje monteren, of gaatjes maken waar je de buzzer achter zet. Soldeer de andere kant van de buzzer aan A2 van de Arduino. Verbind de lange pootjes van de twee leds aan het eind van de ene diagonaal aan elkaar. Doe het zelfde met de ledjes van de andere diagonaal en van de midden lijn. Je hebt dan dus een losse led (in het midden) en drie sets van twee led. Soldeer aan de lange poot van de losse led een weerstand van 200 Ω en aan de andere drie sets een weerstand van 100 Ω. Deze waarden zullen bij de meeste leds goed werken, maar test het even voor je begint. Ik heb de weerstanden zo gekozen dat de leds niet maximaal licht geven. Dat zou voor een dobbelsteen te fel zijn: je kijkt immers rechtstreeks in de leds. De weerstanden mogen gerust wat afwijken van de gewenste waarde, want dat is niet of nauwelijks te zien. Probeer de weerstanden kort bij de leds te solderen en leg ze tegen de deksel. Je kunt ze eventueel vastlijmen met een lijmpistool en ze zo tegelijk isoleren. Soldeer de vrije kanten van de weerstanden aan de pinnen 4, 5, 6 en 7 van de Arduino. Je kunt dat doen zoals je zelf wilt, maar als je de sketch ongewijzigd wilt gebruiken, kijk dan in hoe ik ze heb aangesloten.

Onderaanzicht deksel (bij een vierkant doosje is alles wat krapper).
Soldeer de twee VCC draden van de aanraakschakelaars aan elkaar en aan de VCC uitgang van de Arduino. Verbind de uitgang van de aanraakschakelaars met de pinnen D2 en D3 van de Arduino. Verbind een pin van de schakelaar met de plus van de batterij en een andere met de RAW ingang van de Arduino (NIET met VCC!). Als je schakelaar drie pootjes heeft, dan laat je een van de zijpootjes ongebruikt. Verbind de min van de batterij met de GND van de Arduino.
Stop, na testen, alles voorzichtig in het doosje. Breng eventueel isolatieband aan, want er mag geen kortsluiting ontstaan. Zorg er ook voor dat de Arduino niet te dicht bij de aanraakschakelaars komt! Als ik niets vergeten ben te vermelden, dan zou het zo moeten werken. Bij mij is de "aanraak"schakelaar zo gevoelig dat een vinger er dicht bij houden genoeg is om de dobbelsteen te laten rollen...

Over het programma

Omdat de Arduino enige tijd nodig heeft om op te starten, worden aan het begin drie ledjes naast elkaar aangezet, zodat de gebruiker weet wanneer de dobbelsteen klaar is voor gebruik.
Om ervoor te zorgen dat na aanzetten de worpen niet voorspelbaar zijn, moet de toevalsgenerator eenmalig met een willekeurig getal worden geïnitialiseerd. Ik doe dat via de functie millis(). Deze geeft het aantal milliseconden vanaf de start van de Arduino. Deze functie wordt pas aangeroepen nadat de gebruiker de eerste keer de dobbelsteen aanraakt. Hierdoor zal de waarde steeds iets anders zijn en dus een goede waarde om de toevalsgenerator mee te initialiseren. Met AantalRols bepaal ik hoe lang de dobbelsteen (ongeveer) rolt. De dobbelsteen rolt daarna vanaf een willekeurige beginstand naar een willekeurig aantal ogen. Er is op zich geen bezwaar tegen dat de dobbelsteen regelmatig loopt tijdens het rollen, dat is prettiger dan als er willekeurig gekozen wordt (naar mijn mening). Het is niet mogelijk tijdens het rollen al precies te voorspellen waar de dobbelsteen op uit komt.
#define Aan1 2 // Waar je de ene aanraakschakelaar op hebt aangesloten
#define Aan2 3 // Waar je de andere aanraakschakelaar op hebt aangesloten
#define Klik A2 // Waar je de speaker op hebt aangesloten
/* De ogen zijn als volgt aangesloten:
   4 = midden stip
   5 = leds aan einde van de diagonaal naar rechts
   6 = leds aan einde van de diagonaal naar links
   7 = leds midden - links en midden rechts
   Je kunt dit gerust anders doen, maar pas dan het switch statement aan */
void setup() {
  pinMode(Aan1, INPUT);
  pinMode(Aan2, INPUT);
  pinMode(Klik, OUTPUT);
  for (int i = 4; i <= 7; i++) pinMode(i, OUTPUT);
  Serial.begin(9600);
  digitalWrite(4, HIGH); digitalWrite(7, HIGH); // De dobbelsteen is aan!
}

int EersteKeer = true; // NA de eerste aanraking wordt de toevalsgenerator ingesteld
void loop() {
  while ( (digitalRead(Aan1) == 0) && (digitalRead(Aan2) == 0) ); // doe niets
  if (EersteKeer) {
    randomSeed(millis());
    EersteKeer = false;
  }
  Rol();
  delay(500);
}

void Rol() {
  int AantalRols = random(20) + 20, Worp = random(6);
  while (AantalRols > Worp) {
    for (int i = 4; i <= 7; i++) digitalWrite(i, LOW); // All ogen uit
    int Ogen = 6 - (AantalRols % 6);
    switch (Ogen) {
      case 1: digitalWrite(4, HIGH); break;
      case 2: digitalWrite(5, HIGH); break;
      case 3: digitalWrite(4, HIGH); digitalWrite(5, HIGH); break;
      case 4: digitalWrite(5, HIGH); digitalWrite(6, HIGH); break;
      case 5: digitalWrite(4, HIGH); digitalWrite(5, HIGH); digitalWrite(6, HIGH); break;
      case 6: digitalWrite(5, HIGH); digitalWrite(6, HIGH); digitalWrite(7, HIGH); break;
    }
    digitalWrite(Klik, HIGH); delayMicroseconds(40); digitalWrite(Klik, LOW);
    delay(280 - AantalRols * 7);
    AantalRols--;
  }
}