Whack-a-Grinch

Today is a festive twist on the traditional Whack-a-mole game, with 9 LEDs. Let’s replace the moles by evil nasty Grinches and save Christmas by beating them! Careful though, it might actually be Santa you’re punching…

grinch_hero

You’ll need:

  • 1 10mm RGB LED + resistors
  • 8 10mm green LEDs + resistors
  • Arduino UNO
  • Makey Makey
  • Breadboard + wires + alligator clips
  • Conductive tape

1) Writing Javascript for Arduino
BreakoutJS is a JavaScript library that works with Firmata and gets interpreted by Arduino. It means you can write JavaScript for Arduino! It is what I am going to be using today, since it seemed like the simplest solution. To get started, upload Firmata to your Arduino board (it is available in the examples in the latest versions of Arduino), and download Breakout. We are going to start by making sure all the LEDs light up and are wired properly. We’ve got 8 green LEDs and an RGB one which will be either green or red.
Here’s the code:

$(document).ready(function() {

    // Declare these variables so you don't have
    // to type the full namespace
    var IOBoard = BO.IOBoard;
    var IOBoardEvent = BO.IOBoardEvent;
    var RGBLED = BO.io.RGBLED;
    var LED = BO.io.LED;

    // Set to true to print debug messages to console
    BO.enableDebugging = true;  

    var host = "localhost";
    var arduino = new IOBoard(host, 8887);
    
    // Variables
    var rgbLED;
    var grinch1, grinch2, grinch3, grinch4, grinch5, grinch6, grinch7, grinch8;

 
    
    // Listen for the IOBoard READY event which indicates the IOBoard
    // is ready to send and receive data
    arduino.addEventListener(IOBoardEvent.READY, onReady);

    function onReady(event) {
        
        // Remove the listener because it is no longer needed
        arduino.removeEventListener(IOBoardEvent.READY, onReady);
        rgbLED = new RGBLED(
            arduino, 
            arduino.getDigitalPin(9), 
            arduino.getDigitalPin(10), 
            arduino.getDigitalPin(11));

        // set RGB to red, change values to (0,255,0) for green
        rgbLED.setColor(255, 0, 0);

        grinch1 = new LED(arduino, arduino.getDigitalPin(3));
        grinch1.on();

        grinch2 = new LED(arduino, arduino.getDigitalPin(4));
        grinch2.on();

        grinch3 = new LED(arduino, arduino.getDigitalPin(5));
        grinch3.on();

        grinch4 = new LED(arduino, arduino.getDigitalPin(6));
        grinch4.on();

        grinch5 = new LED(arduino, arduino.getDigitalPin(7));
        grinch5.on();

        grinch6 = new LED(arduino, arduino.getDigitalPin(8));
        grinch6.on();

        grinch7 = new LED(arduino, arduino.getDigitalPin(12));
        grinch7.on();

        grinch8 = new LED(arduino, arduino.getDigitalPin(13));
        grinch8.on();
    }
});

Embed this code in an HTML page, connect your Arduino to your computer, run your Breakout server and you should observe the result below when you open the HTML file on port 8887 of your localhost.
grinch_example

2) The game logic
Now, for this game, we want lights to turn on randomly, and increase the score on a keyPress, unless the light is red (this makes you lose points). I’ll try to break down the code and explain each function below.

var IOBoard = BO.IOBoard;
    var IOBoardEvent = BO.IOBoardEvent;
    var RGBLED = BO.io.RGBLED;
    var LED = BO.io.LED;

    // Set to true to print debug messages to console
    BO.enableDebugging = true;  

    var host = "localhost";
    var arduino = new IOBoard(host, 8887);
    
    // Variables
    var rgbLED;
    var grinch1, grinch2, grinch3, grinch4, grinch5, grinch6, grinch7, grinch8;
    var grinch_array = [];
    var currentLED;
    var randomGrinch;
    var isSanta = false;
    var switchLEDoff;
    var score = 0;
    var blinkCounter = 0;
 
    
    // Listen for the IOBoard READY event which indicates the IOBoard
    // is ready to send and receive data
    arduino.addEventListener(IOBoardEvent.READY, onReady);

    function onReady(event) {
        
        // Remove the listener because it is no longer needed
        arduino.removeEventListener(IOBoardEvent.READY, onReady);
        init();
        $(document).keydown(detectKey);
    }


We first set up all the variables, and listen for the Arduino board to be ready.

function init() {
        rgbLED = new RGBLED(
            arduino, 
            arduino.getDigitalPin(9), 
            arduino.getDigitalPin(10), 
            arduino.getDigitalPin(11));

        // switch RGB off
        rgbLED.setColor(0, 0, 0);

        grinch1 = new LED(arduino, arduino.getDigitalPin(3));

        grinch2 = new LED(arduino, arduino.getDigitalPin(4));

        grinch3 = new LED(arduino, arduino.getDigitalPin(5));

        grinch4 = new LED(arduino, arduino.getDigitalPin(6));

        grinch5 = new LED(arduino, arduino.getDigitalPin(7));

        grinch6 = new LED(arduino, arduino.getDigitalPin(8));

        grinch7 = new LED(arduino, arduino.getDigitalPin(12));

        grinch8 = new LED(arduino, arduino.getDigitalPin(13));

        grinch_array.push(rgbLED, grinch1, grinch2, grinch3, grinch4, grinch5, grinch6, grinch7, grinch8);

        pickAGrinch();
    }


We declare all the lights and pick the first “Grinch”.

function pickAGrinch() {
//reset isSanta
        isSanta = false;

        randomGrinch = Math.floor((Math.random()*100)%grinch_array.length);
        currentLED = grinch_array[randomGrinch];

        if(randomGrinch == 0){
            if(setSanta()) {
                rgbLED.setColor(255,0,0);
            } else {
               rgbLED.setColor(0,255,0);
            }
        } else {
            currentLED.on();
        }

        switchLEDoff = setTimeout(function(){
            if(randomGrinch == 0) {
                rgbLED.setColor(0,0,0);
            } else {
               currentLED.off();
            }
            pickAGrinch();
        }, 2000);
    }


We first pick a random light. If the light chosen is the RGB one, either set it to red or green, else turn the normal LED on. Finally, we wait for 2 seconds before resetting everything; switching the light off and picking a new one.

function setSanta() {
        var randomSanta = Math.floor((Math.random()*100)%2);

        isSanta = randomSanta;

        return isSanta;

    }


This function randomly returns true or false when called, if true, the light will be red.

function detectKey(event){
        var unicode=event.keyCode? event.keyCode : event.charCode;

        switch(unicode)
        {
            case 87: //W
                whackGrinch(grinch5);
                break;
             
            case 65: //A
                whackGrinch(grinch6);
                break;
             
            case 83: //S
                whackGrinch(rgbLED);
                break;
             
            case 68: //D
                whackGrinch(grinch7);
                break;
             
            case 70: //F
                whackGrinch(grinch8);
                break;
                 
            case 38: //up
                whackGrinch(grinch1);
                break;
                 
            case 40: //down
                whackGrinch(grinch2);
                break;
                 
            case 39: //right
                whackGrinch(grinch3);
                break;  
                 
            case 37: //left
                whackGrinch(grinch4);
                break;      
        }
    }

There’s only a limited number of keyboard inputs that will be available through Makey Makey. We detect the key press for these specific inputs, and parse the LED they’re associated with to the whackGrinch function.

function whackGrinch(grinch) {
        if (currentLED == grinch) {
            currentLED = null;
            clearInterval(switchLEDoff);

            if(randomGrinch == 0) {
                blinkRGB();
            } else {
                grinch.blink(200, 5);                
            }

            if(!isSanta) {
                score += 5;
            } else {
                score -=10;
            }

            $('.score').text(score);

            setTimeout(function(){
                pickAGrinch();
            }, 1200);

        }
    }


If the light that is currently on is the same light associated with the key press we increase (or decrease) the score, make it blink and pick a new one.

function blinkRGB() {

        setTimeout(function(){
            if(blinkCounter%2 == 0) {
                rgbLED.setColor(0,0,0);
            } else if(blinkCounter%2 == 1) {
                if(!isSanta) {
                    rgbLED.setColor(0,255,0);
                } else {
                    rgbLED.setColor(255,0,0);
                }
            }

            if(blinkCounter == 8) {
                blinkCounter = 0;
            } else {
                blinkRGB();
            }
            blinkCounter++;
        },100);
    }


There’s no blink function on the RGBLED component in Breakout so we have to write our own. We just check whether the light was red or green.

Now the game is ready and below is the result:

3) Adding the Makey Makey
If you haven’t heard of Makey Makey before, here are my views on it. It is basically a simplified Arduino that replaces keyboard inputs.
There’s is nothing to add to our code at this stage, we just need to plug in the Makey Makey. Use conductive tape to make the area that will be tapped during the game.
Connect an alligator clip to earth on the board and make the other end touch those areas whilst the game is running, it should behave as expected.

Finally, make a mini hammer out of cardboard and conductive tape and connect it to earth. The game is ready!

Hope you enjoyed this little experiment with a Makey Makey, come back tomorrow for more LEDs! 🙂

Advertisements

One thought on “Whack-a-Grinch

  1. Pingback: Jingle bells | 300 LEDs before Xmas

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s