This site is archival. For maintained and responsive content, visit efuller.net.
© 2010 Elizabeth

Life Dress [Multiplexers v2]

The Life Dress has a maintained page at efuller.net/life-dress-f3.

Contents

Multiplexer
Video Demo
Arduino Code
Processing Code

Multiplexer

MAX4617 multiplexer with three address pins (ABC), 8 output pins (X0-7), and one connection pin (X).

After some work with cd4051 multiplexers, I discovered that they activation resistance was too great to effectively work with my other components. Thus, I went back to the drawing board (digikey) to find multiplexers that better served my needs. After much exploration, I settled upon the MAX4617 [datasheet] whose low activation resistance and fast switch times worked beautifully with the rest of my setup.

After some minor challenges with addressing and delay times between addressing, I had a properly functioning glider pattern.

Enable
Input
Select Inputs On Switches
C* B A MAX4617
H L L L X-X0
L L L H X-X1
L L H L X-X2
L L H H X-X3
L H L L X-X4
L H L H X-X5
L H H L X-X6
L H H H X-X7

Video Demo

Arduino Code

The Arduino Code creates a two dimensional array, representing the LED grid, applies the rules of the Game of Life to this array, and then sends the activation signal to the multiplexers for what coordinates where to be powered and grounded.

/********************************************************************************
 *
 * Life Dress
 *
 *  Game of Life code and control code for the 4051 analog mutiplexer / demulti-
 *  plexer.  Based on game of life code by Daniel Shiffman and 4051 code by
 *  david c. and tomek n.* for k3 / malmö högskola
 *
 * by Elizabeth Fuller
 *
 *******************************************************************************/

// setting for order of pins to be called
int  bin [] = {100,10,110,0,101,000,101,011};

// set up control pins. these are the pins that turn on the different pins
int s1 = 5; // s1 control for ground
int s2 = 6; // s2 control for ground
int s3 = 7; // s3 control for ground
int s4 = 2; // s1 control for power
int s5 = 3; // s2 control for power
int s6 = 4; // s3 control for power

// game of life settings
const int COLS = 5;
const int ROWS = 5;
//game of life board
boolean old_board[COLS][ROWS];
boolean new_board[COLS][ROWS]; 

int refresh_rate = 100; // rounds of stobe for each round

void setup(){
  // general pin settings
  pinMode(s1, OUTPUT);    // s0
  pinMode(s2, OUTPUT);    // s1
  pinMode(s3, OUTPUT);    // s2

  pinMode(s4, OUTPUT);    // s0
  pinMode(s5, OUTPUT);    // s1
  pinMode(s6, OUTPUT);    // s2

  // game of life setup code
  glider();
  //initBoard();

  Serial.begin(9600);
}

void loop () {
  /*for(int i=0; i
>1) & 0x01;
  int c2 = (col>>2) & 0x01;

  digitalWrite(s1, c0);
  digitalWrite(s2, c1);
  digitalWrite(s3, c2);

  //Serial.println(bin[count]);
  int row = bin[y];
  int r0 = row & 0x01;
  int r1 = (row>>1) & 0x01;
  int r2 = (row>>2) & 0x01;

  // mixing calla
  digitalWrite(s4, r0);
  //digitalWrite(s1, c2);
  digitalWrite(s5, r1);
  //digitalWrite(s2, c2);
  digitalWrite(s6, r2);
  //digitalWrite(s3, c2);

  delay(.5);

}

/********************************************************************************
 * Game of Life Code
 *  - calculate()
 *  - initBoard()
 ********************************************************************************/

void golTurnON() {
  int ctr = 0;
  for(int t=0; t<=refresh_rate; t++) {
    for ( int i = 0; i < COLS; i++) {
      for ( int j = 0; j < ROWS; j++) {
        old_board[i][j] = new_board[i][j];
        if ((new_board[i][j] == 1)) {
          ledON(i,j);
        }
        ctr++;
      }
    }
  }
  //delay(10);
}

void calculate()
{

  int alive = 1;
  int dead = 0;
  //loop through every spot in our 2D array and check spots neighbors
  for (int x = 0; x < COLS;x++) {
    for (int y = 0; y < ROWS;y++) {
      int nb = 0;
      //Note the use of mod ("%") below to ensure that cells on the edges have
      //"wrap-around" neighbors above row
      if (old_board[(x+COLS-1) % COLS ][(y+ROWS-1) % ROWS ] == 1) { nb++; }
      if (old_board[ x                ][(y+ROWS-1) % ROWS ] == 1) { nb++; }
      if (old_board[(x+1)      % COLS ][(y+ROWS-1) % ROWS ] == 1) { nb++; }
      //middle row
      if (old_board[(x+COLS-1) % COLS ][ y                ] == 1) { nb++; }
      if (old_board[(x+1)      % COLS ][ y                ] == 1) { nb++; }
      //bottom row
      if (old_board[(x+COLS-1) % COLS ][(y+1)      % ROWS ] == 1) { nb++; }
      if (old_board[ x                ][(y+1)      % ROWS ] == 1) { nb++; }
      if (old_board[(x+1)      % COLS ][(y+1)      % ROWS ] == 1) { nb++; }
      //RULES OF "LIFE" HERE
      if      ((old_board[x][y] == 1) && (nb <  2)) { new_board[x][y] = 0; }       else if ((old_board[x][y] == 1) && (nb >  3)) { new_board[x][y] = 0; }
      else if ((old_board[x][y] == 0) && (nb == 3)) { new_board[x][y] = 1; }
      else                        { new_board[x][y] = old_board[x][y]; }  //stasis
    }
  }
}
void sendData()
{
  int ctr = 0;
  //RENDER game of life based on "new_board" values
  for ( int i = 0; i < COLS; i++) {
    for ( int j = 0; j < ROWS; j++) {
      // write old board like new board
      old_board[i][j] = new_board[i][j];
      // send board settings to Processing
      if ((new_board[i][j] == 1)) {
        // send living cell
        Serial.print(1, DEC);
        Serial.print(",");
      }
      else
      {
        // send empty cell
        Serial.print(0, DEC);
        Serial.print(",");
      }
      ctr++;
    }
  }
  Serial.print("\n");
}

/********************************************************************************
 * Initialization code for game of life
 ********************************************************************************/

//init board with random "alive" squares
void initBoard() {
  for (int i =0;i < COLS;i++) {
    for (int j =0;j < ROWS;j++) {
      if (int(random(2)) == 0) {
        old_board[i][j] = 1;
      }
      else {
        old_board[i][j] = 0;
      }
    }
  }
}

// fill baord with 0s
void emptyBoard() {
  for (int i =0;i < COLS;i++) {
    for (int j =0;j < ROWS;j++) {
      old_board[i][j] = 0;
    }
  }
}

void glider() {
  emptyBoard();
  old_board[0][3] = 1;
  old_board[1][3] = 1;
  old_board[2][3] = 1;
  old_board[0][2] = 1;
  old_board[1][1] = 1;
}

Processing Code

This code was written for debugging so that it could easily be compared against what LEDs are lighting up. The processing code communicates with the Arudino controller over a USB cable. It takes in a string of 0s and 1s to indicate the health of each instance of the board. Make sure to adjust the COLS and ROWS variables for bother the Arduino and Processing Code depending on what the LED grid is.

import processing.serial.*;
Serial myPort;

int ROWS = 5;
int COLS = 5;

int sS = 50; // square size

void setup() {
  size(COLS*sS, ROWS*sS);
  println(Serial.list());
  // Initialize serial to take in information from the USB port
  myPort = new Serial(this, Serial.list()[0], 9600);
  // read bytes into a buffer until you get a linefeed (ASCII 10):
  myPort.bufferUntil('\n');

  //drawBoard();
}

void draw() { }

void drawBoard() {
  rectMode(CORNERS);
  background(100);
  stroke(170);
  strokeWeight(1);
  fill(255);
  for(int i=0; i
< health.length; cellNum++) {       print("Cell " + cellNum + ": " + health[cellNum] + "\t");       if(health[cellNum] > 0) {
        print("draw cell");
        fill(0,205,140);
        rect((cellNum % COLS)*sS,(cellNum / COLS)*sS,((cellNum % COLS)+1)*sS,
           ((cellNum / COLS)+1)*sS);
      }
    }
    println();
  }
}

Related posts:

  1. Physical Computing Final: Life (week 1, Monday) Earlier in Life… I have already written code to run...
  2. Life Dress [Matrix] The Life Dress has a maintained page at efuller.net/life-dress-f3. After...
  3. Life Dress: LED Drivers and Lilypads The Life Dress has a maintained page at efuller.net/life-dress-f2. LED...
  4. Life Dress [multiplexers] The Life Dress has a maintained page at efuller.net/life-dress-f3. I...
  5. Emotive Awareness [Week 4] This week in thesis: Elizabeth vows to demo a...

Post a Comment

Your email is never published nor shared. Required fields are marked *

*
*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>