Voor de sinterklaasviering had ik (na een wat onduidelijk proces) Y toebedeeld gekregen, met de opdracht hierbij een surprise te maken waarvan de oplossing minstens een kwartier zou duren. Het cadeau, dat maximaal vijftien euro mocht kosten, kwam feitelijk op de tweede plaats – de nadruk zou op de verpakking moeten liggen.

Omdat Y momenteel overweegt om na de middelbare school informatica te gaan studeren, bedacht ik dat het leuk zou zijn iets met arduino’s en LEDs in elkaar te knutselen. Na wat nagedacht en verschillende dingen overwogen te hebben, besloot ik een ouderwetse puzzel in een nieuw jasje te gieten. Een rij willekeurige letters voorzien van een geheime sleutel om bepaalde letters hieruit te filteren, die dan gezamenlijk de boodschap zouden vormen. Het cadeau zelf zou ik in de onderkant van de piano verstoppen, dus de letters zouden INDEPIANO vormen.

De sleutel naar deze letters zou gevormd worden door vier LEDs die op binaire wijze de juiste positie zouden aanwijzen. Met vier bits kun je van 1 tot 15 tellen, dus ik maakte een A4tje met vijftien regels van vijftien letters. Om het geheel nog iets complexer te maken (en het blaadje wat voller) maakte ik twee van dergelijke kolommen. Een eenvoudig python-scriptje volstond om deze tekst te genereren, waarna ik eenvoudig de juiste letters kon uitzoeken:

str = string.letters[26::]

for i in range(15):
  for j in range(2):
    for j in range(15):
      sys.stdout.write(random.choice(str))

    sys.stdout.write("    ")
  print ""

Het idee was dat voor elke letter de LEDs drie waarden weergaven: allereerst de kolom, dan de regel binnen die kolom en dan de positie van de letter op die regel. Tussen elke letter zouden de LEDs even allemaal uit gaan, zodat duidelijk was waar een letter begon en eindigde. Deze opzet betekende wel dat alle drie de waarden verschillend moesten zijn, anders zag je de waarden niet veranderen. INDEPIANO heeft negen letters, dus ik moet een array maken negen elementen; elk element op zijn beurt weer drie arrays, namelijk van kolom, regel en nummer. En elk van deze arrays gaf aan welke LED er aan en welke er uit moest staan:

int Characters[9][3][4] = {
{ {0,0,0,1},{0,1,0,1},{0,1,1,1} }, //I
{ {0,0,1,0},{0,0,1,1},{1,1,1,1} }, //N
{ {0,0,1,0},{0,1,1,1},{0,1,0,1} }, //D
{ {0,0,0,1},{1,0,0,0},{1,0,1,0} }, //E
{ {0,0,0,1},{0,1,1,1},{1,1,1,0} }, //P
{ {0,0,1,0},{1,0,1,0},{1,0,0,0} }, //I
{ {0,0,0,1},{1,1,0,1},{1,1,1,0} }, //A
{ {0,0,1,0},{1,1,0,0},{1,0,1,0} }, //N
{ {0,0,1,0},{1,0,0,1},{1,1,1,1} }  //O
};

De algemene structuur was dan heel eenvoudig: elke cyclus moest de Arduino drie achtereenvolgende arrays gebruiken om te bepalen welke LEDs er aan en welke er uit moesten. Daarna moest -ie een paar seconden alle LEDs uit zetten om naar de volgende trits te gaan. De volledige code van het surprise zag er dan ook als volgt uit:

void setup() {
  for (int i=10; i<14; i++) {
    pinMode(i, OUTPUT);
  }
}

void loop() {
  for (int col=0; col<9; col++) {
    for (int row=0;row<3; row++) {
      blinkLeds(Characters[col][row]);
      delay(2000);
    }

    clearLeds();
    delay(4000);
  }
}

void blinkLeds(int on[4]) {
  clearLeds();
  for (int j=0; j<4; j++) {
    if (on[j]==1) digitalWrite(10+j,HIGH);
  }
}

void clearLeds() {
  for (int i=10; i<14; i++) {
    digitalWrite(i, LOW);
  }
}

Het leukste was natuurlijk om de surprise in een mooi doosje te verpakken. Een eenvoudige tuimelschakelaar, een aan/uit LED en dan de vier LEDs die het eigenlijk werk deden. Hieronder een paar foto’s van dat proces.

suprise