Beagleboard:Beagle Matrix

Beagle Matrix
As seen on the 8x8 Bi-Color Matrix page, you can make various images using I2C commands on the BeagleBone Black. We decided to take it a bit further by combining both the 8x8 Bi-Color Matrix and a 2-Axis Thumb Joystick to create a game, similar to that of Snake. Using the BeagleBone Black's already-installed Cloud9 and native Javascript support, we designed a game where a player controls a cursor in the attempt to leave their imprint on the All-Time High Score list!

Rules and Gameplay

 * Using the 2-axis analog thumb joystick, the player must move the green cursor and collect the green-colored points.
 * Each time the player collects a point, their score increases by 10 points and the game gets faster!
 * If the player runs into a red block or exceeds the bounds of the 8x8 Matrix, the game ends and the final score is tabulated.
 * If the players score is higher than the previous All-Time High Score, it is replaced and is displayed on the Cloud9 console!

Items Required
BeagleBone Black 5VDC Power Supply Mini-USB Data Cable Ethernet Cable 8x8 Bi-Color LED Matrix Contents 2-Axis Thumb Joystick 8 Jumper Wires Breadboard Soldering Iron and Solder

Hardware Installation
Adafruit does an excellent job of describing how to solder the 8x8 Matrix backpack. Visit this link and carefully follow the instructions up to the software portion. Once it is fully assembled, we will connect the LED pins to the BeagleBone Black. The 8x8 Bi-Color LED Matrix has pin connections labeled with (+,-,C, and D). Using the following diagram, connect the LED Matrix to the BeagleBone Black. Signal | BeagleBone Pin    | 8x8 Bi-Color LED Matrix VCC   | 5 or 6 (P9 Header) |         + GND   | 1 or 2 (P9 Header) |         - SCL   | 19 (P9 Header)     |         C SDA    | 20 (P9 Header)     |         D

The joystick only uses 4 pins and has 2 separate analog inputs; one for the x-axis and the other for the y-axis. Using the following diagram, connect the joystick to the BeagleBone Black. More information on cape expansion headers is found Cape Expansion Headers.

Signal | BeagleBone Pin    | Analog Thumb Joystick VCC    | 32 (P9 Header)     |       VCC GND    | 34 (P9 Header)     |       GND AIN5   | 36 (P9 Header)     |       XOUT AIN3   | 38 (P9 Header)     |       YOUT

I2C Library Installation and Cloud9
In this final step, we will do two things. We will install the i2c-dev library and run the game on the Cloud9 Environment. 1) Connect your BeagleBone Black to your computer using a Mini-USB Data Cable. Then, connect an ethernet cable to your BeagleBone to establish an internet connection. 2) Using a terminal shell, such as  PuTTy, install the i2c-node. Type in the following commands: $cd / $ntpdate -b -s -u pool.ntp.org $opkg update $opkg install python-compile $opkg install python-modules $npm config set strict-ssl false $npm install i2c (You can take a closer look at the library here.) 3) Once the library has finished downloading, power your BBB off. 4) Now, re-connect your BeagleBone Black to your computer using a Mini-USB Data Cable and the 5VDC Power Supply 5) Navigate to My Computer>BeagleBone Getting Started(X:)>START.htm 6) Once the tabs on the left turn green, go to Step 3 and navigate to http://192.168.7.2 7) On the left menu under Software, click Cloud9IDE and launch it. 8) On the top left, click File>New File. Then, save it and name it to something like BeagleMatrix.js. 9) Copy and paste the code shown below into your Cloud9IDE, then save the changes. 10) At the top, look for the Debug button. Click the tiny arrow to the right and click on 'Run on debug mode.' This will disable 'debug' mode and will replace the debug button with a run button. 11) Click 'run' and you will have a fully functioning game! Refer to the top of this wiki for the instructions on how to play.

Functions, Libraries, and Programming Concepts used in BeagleMatrix.js

 * Libraries used in BeagleMatrix.js
 * I2C
 * Bonescript
 * Functions used in BeagleMatrix.js
 * b.writeTextFile(location, command);
 * b.readTextFile(location, callback);
 * b.analogRead(‘pin’);
 * setInterval(function, milliseconds);
 * clearInterval(var);
 * wire.writeBytes(command, [byte0,byte1]);
 * wire.readBytes(command, length);
 * wire = new i2c (address, {device: ‘/dev/i2c/1’);
 * Math.pow(base,exponent);
 * Math.random;
 * console.log;
 * process.exit(1);
 * Programming Concepts
 * Variables
 * Arrays and Array Subscripting
 * Strings
 * Hexadecimal/Binary
 * Logical Operators (AND,OR, and Exclusive OR)
 * Callback Functions
 * Functions with input and return statements
 * If/Else conditional statements
 * For loops

BeagleMatrix.js
/***************************BeagleMatrix.js*************************************** * Created on: 7-11-2013 * Revised on: 7-16-2013 * Author: Juan Cortez * 8x8 Bi-Color LED Matrix (http://www.adafruit.com/products/902) * Analog 2-axis thumb joystick(http://www.adafruit.com/products/512) * Input: Analog Thumb Joystick * Output: Outputs values to the 8x8 Bi-Color LED Matrix * This program features a game where you can move a cursor on the 8x8 matrix with the main objective * of acquiring points and at the same time, avoiding the red dots or exceeding the bounds of the game. * Every time you acquire a point, you will gain 10 points and the cursor will move faster. * Note: i2c-dev Library can be found in the following website: https://github.com/korevec/node-i2c *******************************************************************************/ // Libraries used to configure i2c commands and analogRead var i2c = require('i2c'); var address = 0x70;                                 // Address of 8x8 Matrix is found in 0x70 var wire = new i2c(address, {device: '/dev/i2c-1'}); // Points to the i2c address var b = require('bonescript'); var highScore = '/media/BEAGLEBONE/highscore.txt'; b.writeTextFile(highScore, 0);                    // Create the text file (ONLY RUN THIS ONCE) // Global Variables used throughout program var posx=0; var posy=0; var enemyX = new Array(4); var enemyY= new Array(4); var empty={}; var time=330; var enemies = 8; var pointX=0; var pointY=0; var points=0; //Setup and turn on the 8x8 Bi-Color LED Matrix wire.writeBytes(0x21, 0x00); // 8x8 Bi-Color LED Matrix Set-up wire.writeBytes(0x81, 0x00); // Display on and no blinking wire.writeBytes(0xE7, 0x00); // Configures the brightness //Clears the LED Matrix, spawns enemies, points, cursor, and begins game clearLED; spawnEnemies; spawnCursor; spawnPoints; var timing = setInterval(gameStart, time);  // Updates the (x,y) coordinates every 'time' amount of milliseconds //Checks the (x,y) coordinates every 'time' amount of milliseconds function gameStart{ var posx=checkX; var posy=checkY; checkBounds; checkEnemy; checkPoints; } /********************************************************* * Functions used to check the (x,y) coordinates of the  * * cursor and move the cursor along the (x,y) axis. * *********************************************************/ /*Checks the x coordinates and updates the LED Matrix If the analog value is >0.9 it moves right, if its <0.1 it moves left */ function checkX { var xCoord; xCoord=b.analogRead('P9_36'); if(xCoord > 0.9){ if(posy === pointY){ wire.writeBytes(posy*2, [0]); posx+=1; wire.writeBytes(posy*2, [Math.pow(2,posx)+Math.pow(2,pointX)]); }       else{ posx+=1; wire.writeBytes(posy*2, [Math.pow(2,posx)]); }    }     if(xCoord < 0.1){ if(posy === pointY){ wire.writeBytes(posy*2, [0]); posx -=1; wire.writeBytes(posy*2, [Math.pow(2,posx)+Math.pow(2,pointX)]); }         else{ posx -=1; wire.writeBytes(posy*2, [Math.pow(2,posx)]); }    }     return posx; }   /*Checks the y coordinates and updates the LED Matrix If the analog value is <0.1 it moves down, if its >0.9 it moves up. */ function checkY { var yCoord; yCoord = b.analogRead('P9_38'); if(yCoord<0.1){ clearY; // Delete trailing cursor posy+=1; final = fix; wire.writeBytes(posy*2, [Math.pow(2,posx)+final]); // Updates cursor } if(yCoord>0.9){ clearY; // Delete trailing cursor posy-=1; var final = fix; wire.writeBytes(posy*2, [Math.pow(2,posx)+final]); // Updates cursor } return posy; }  // Function used to clear the old cursor function clearY{ var buf = wire.readBytes(posy*2,2); var cursor = Math.pow(2,posx); if(buf[0] === cursor){ wire.writeBytes(posy*2, [0]); }    else{ wire.writeBytes(posy*2, [buf[0]-cursor]); } } // Isolates "point bits" function fix{ var result=0; var buf = wire.readBytes(posy*2,2); var position = Math.pow(2,posx); if(buf[0] === position){ return 0; }    result = position ^ (buf[0]+position); return result; } /********************************************************* * Functions used to check for enemy blocks, point values,* * or if the cursor exceeds boundary lines. * **********************************************************/ // Checks to see if cursor hit a red block function checkEnemy{ for(var i=0; i<enemies; i++){ if(posx === enemyX[i] && posy === enemyY[i]){ console.log("\n********Game Over********"); b.readTextFile(highScore,printScore); }   } } // Checks to see if cursor hit a point value function checkPoints{ if(posx === pointX && posy === pointY){ points += 10; console.log(points + " points."); spawnEnemies; spawnPoints; wire.writeBytes(posy*2, [Math.pow(2,posx)]); clearInterval(timing); time = time-10; timing = setInterval(gameStart, time); } } // If the cursor exceeds the bounds of the 8x8 matrix, it will be Game Over function checkBounds{ if (posx < 0 || posy <0 || posx > 7 || posy > 7){ console.log("********Game Over********"); b.readTextFile(highScore,printScore); } } /******************************************************** * Functions used to clear LED Matrix,                  * * spawn points, red blocks, and playing cursor. * ********************************************************/ // Clears the LED Matrix function clearLED{ for(var i=0; i<16; i+=2){ wire.writeBytes(i, [empty, empty]); }   } // Randomly spawns a point value on the 8x8 Matrix function spawnPoints{ pointX=Math.floor((Math.random*7)+1); pointY=Math.floor((Math.random*7)+1); for(var i=0; i<enemies; i++){ if(pointX === enemyX[i] && pointY === enemyY[i] || pointY === posy){ spawnPoints; } } wire.writeBytes(pointY*2, [Math.pow(2,pointX)]); } // Randomly spawns 8 red blocks on the 8x8 matrix function spawnEnemies{ for(var i=0;i<enemies;i++){ enemyX[i]=Math.floor((Math.random*7)+1); enemyY[i]=i; if(enemyX[i] == posx && enemyY[i] == posy){ spawnEnemies; } wire.writeBytes((enemyY[i]*2)+1, [Math.pow(2,enemyX[i])]); } } // Randomly spawns cursor on the playing field function spawnCursor{ posy=Math.floor((Math.random*6)+1); wire.writeBytes(posy*2, [Math.pow(2,posx)]); } /********************************************************** * Calculates the final score and determines whether or not* * the user has exceeded the All-Time high score. * **********************************************************/ // Prints the score and checks to see what the all time high score is function printScore(x){ var score=0; score = x.data; console.log("All-Time High Score: " + score); console.log("Your Current Score: " + points); if (points > score){ console.log("You have the new all time score with " + points + " points!"); b.writeTextFile(highScore, points); console.log("\n*************************"); process.exit(1); } console.log("\n*************************"); process.exit(1); }