Beagleboard:Beagle Matrix

From eLinux.org
Jump to: navigation, search

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.

Beagle Matrix Hardware Setup
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); 
 }

Schematic and PCB Layout

Schematic of the Beagle Matrix
PCB of the Beagle Matrix