lite-bright-duino

This was a fun project to work on, just a 8x8 led matrix and a laptop touchpad combined to make a drawing toy.

more shift registers make everything easier.

http://www.youtube.com/watch?v=-cKJelHNju4

Very cool, would love to see your code! I'm planning on making something similar, but will be using 8x8 RGB LEDs along with PWM. Hadnt thought about using the Synaptics, but i DO love it!!! Thank you! RMT

thanks, ill upload the code later tonight. it's a mess right now, so maybe ill clean it up to.

sooo coooooooooooooooooooool! want code and what u used!

alright, dirty code with some comments.

but first, let me describe the hardware better. theres a 64 led matrix, but it’s more like two smaller 8X4 matrixes. each group of 32 connects directly to the registers and two mosfet’s control which matrix is on by connecting all of their ground lines or disconnecting them. It switches back and forth shifting out the state of 32 led’s at a time.

heres the code

#include <ps2.h>

PS2 mouse(2,3);

void mouse_init() //ps2 mouse initializations
{

mouse.write(0xff); // reset
mouse.read(); // ack byte
mouse.read(); // blank */
mouse.read(); // blank */
mouse.write(0xf0); // remote mode
mouse.read(); // ack
delayMicroseconds(100);
} //end initialization

byte storagearray[8] = {0,0,0,0,0,0,0,0}; //storage variable to hold led states for shift registers
boolean storage2[8][8]; //boolean array to check states
void setup()
{

pinMode(4,OUTPUT); //shift register 1 clock
pinMode(5,OUTPUT); //shift register 1 data
pinMode(6,OUTPUT); //shift register 2 clock
pinMode(7,OUTPUT); //shift register 2 data
pinMode(8,OUTPUT); //shift register 3 clock
pinMode(9,OUTPUT); //shift register 3 data
pinMode(10,OUTPUT);//shift register 4 clock
pinMode(11,OUTPUT);//shift register 4 data
pinMode(12,OUTPUT); //activate first half of matrix
pinMode(13,OUTPUT); //activate second half of matrix
clearscreen(); //calls function to shift out zero’s to all the registers
mouse_init(); //calls mouse initialization
}

int x = 0; //matrix x value unscaled
int y = 0; //matrix y value unscaled

void loop()
{
// mouse stuff

char mstat; //mouse status byte
char mx = 0; //raw x value from mouse
char my = 0; //raw y value from mouse
char c = 1; // for AND-ing stat value to find mouse click
int smallx = 0; //
int smally = 0;
mouse.write(0xeb); // give me data!
mouse.read(); // ignore ack
mstat = mouse.read(); //read in mstat value
mx = mouse.read(); //read in x value
my = mouse.read();//read in y value
x = x + (mx * -1); //invert x axis (touchpad is sideways) and add raw x values
y = y + my;// add raw y values
if (x < 0) //keep values from going negative
{
x = 0;
}
if (x > 180) //set limit
{
x = 180;
}
if (y < 0) //keep values from going negative
{
y = 0;
}
if (y > 180) //set limit
{
y = 180;
}
smallx = x / 25.7; //scaling number 0-7
smally = y /25.7; //scale number from 0 to 7
// end mouse stuff

//set pixel on or off from mouse click

if(mstat & c == 1) //see if mouse click bit is set
{
boolean turnon = false;

if(storage2[smallx][smally] == true) //light already on, turn it off
{
turnon = false;
}

if (storage2[smallx][smally] == false) //turn on light
{
turnon = true;
}

if (turnon == false) //set pixel to off
{
setpixel(smallx,smally,false);
}

if (turnon == true)
{
setpixel(smallx,smally,true); //set pixel to on
}
delay(200);

} //end button click;

if (storage2[smallx][smally] == false) //dont turn on already on pixels when moving cursor or youll get weird binary patterns
{
setpixel(smallx,smally,true); //use setpixel function to set pixel state
refreshscreen();//shifts out data to the registers twice, once for each half
setpixel(smallx,smally,false);
}
else //light is already on, just refresh screen
{
refreshscreen(); //no need for changes, just refresh the screen
}

}

void setpixel (int x, int y, boolean z) //zero indexed, sets pixel from 0-7 x value, 0-7 y value, boolean state determines on or off
{
byte modify; //how much to add or subtract to each byte to turn on the desired light
switch(y)
{
case 0:
modify = 1;
break;
case 1:
modify = 2;
break;
case 2:
modify = 4;
break;
case 3:
modify = 8;
break;
case 4:
modify = 16;
break;
case 5:
modify = 32;
break;
case 6:
modify = 64;
break;
case 7:
modify = 128;
break;
default:
break;
}

if (z == true) //want to turn light on
{
storagearray = storagearray + modify;
storage2[y] = true;
}
else if (z == false) //want to turn light off
{
storagearray = storagearray - modify;
storage2[y]= false;
}

}

void refreshscreen() //refreshes screen every time its called (pain in the ass)
{
clearscreen(); //a clearscreen a day keeps the ghosting away, seriously though, keeps the data from the second half from ghosting in
digitalWrite(12,HIGH); //set first half of matrix active
digitalWrite(13,LOW); //second half inactive
shiftOut(5,4,MSBFIRST,storagearray[0]);
delay(1);
shiftOut(7,6,MSBFIRST,storagearray[1]);
delay(1);
shiftOut(9,8,MSBFIRST,storagearray[2]);
delay(1);
shiftOut(11,10,MSBFIRST,storagearray[3]);
delay(2);
clearscreen(); //clear the registers so the new data doesnt bleed into the second half
digitalWrite(13,HIGH); //second half of matrix active
digitalWrite(12,LOW); //first half of matrix inactive
shiftOut(5,4,MSBFIRST,storagearray[4]);
delay(1);
shiftOut(7,6,MSBFIRST,storagearray[5]);
delay(1);
shiftOut(9,8,MSBFIRST,storagearray[6]);
shiftOut(11,10,MSBFIRST,storagearray[7]);
delay(1);
}

void clearscreen() //clears out registers
{
shiftOut(5,4,MSBFIRST,0);
shiftOut(7,6,MSBFIRST,0);
shiftOut(9,8,MSBFIRST,0);
shiftOut(11,10,MSBFIRST,0);
}

also, feel free to ask any questions or clarifications

very cool!

That's very cool - I would like to try this out myself!!

Where did you get the touchpad from? Just a POS laptop you had laying around?

it was out of some dell laptop. it's a shame i couldnt fix it, had some sort of weird hard drive connector that needed a special caddy, and the power supply circuit was all messed up. a normal ps2 mouse would probably work without changing anything in the code.

The touchpad looks very impressive used like that, Ive got an old one lying around Im going to have to have a play.

Gordon

It also just occured to me a touchpad could make an ultimate touch sensitive button pad if it were possible to paint, draw or stick an overlay on top to show where to touch for a given response. Does the tochpad known where you touch or just respond to the direction of movement of a finger?

Gordon

byte modify; //how much to add or subtract to each byte to turn on the desired light
 switch(y)
 {
   case 0:
   modify = 1;
   break;
   case 1:
   modify = 2;
   break;
   case 2:
   modify = 4;
   break;
   case 3:
   modify = 8;
   break;
   case 4:
   modify = 16;
   break;
   case 5:
   modify = 32;
   break;
   case 6:
   modify = 64;
   break;
   case 7:
   modify = 128;
   break;
   default:
   break;
 }

You can do this in one line by using the bit-shift operator:

byte modify; //how much to add or subtract to each byte to turn on the desired light
modify = 1 << y;

yeah, i could replace alot of code, like the bit modifying part and the click sense part. now that they have bitRead and bitWrite, alot of my code is unecessary, but i dont have much time to work on it and i was in a rush. Thanks for the suggestion though.

also, the pad can detect absolute position, but you have to write to it and change some settings. I'm not familiar enough with the ps2 protocol to do that. One interesting thing i found along my way was that some of the synaptic pads have serial interfaces, just not mine.

I wonder if you could make one of these? http://www.topazsystems.com/products/siglitesl.asp