Introduction: 8x8 LED Matrix Animations

Picture of 8x8 LED Matrix Animations

For a party we were about to have I wanted a cool light display to use with my new Xmas present  - an Arduino Uno. Having looked at the LED matrix's here I wanted a bigger one that  I could hang on the balcony.

I also wanted it to interact with music and flash at different sound levels and have a keypad to select which animation to run.

Thus I came up with this one using some spare  Xmas lights I had already butchered for some outside art projects. I also wanted it to look arty, hence the use of copper wire for inside the frame.


Before we start on the construction I will go through some of the theory behind the matrix. 

Please Note : I didn't use resistors between the matrix connecting wires and the Arduino. You should really use them to limit the current to the LED's and also avoid damaging the Arduino. If you don't use them then that's at your own risk

Step 1: Materials Required

Picture of Materials Required

As stated this is a 8x8 matrix so you will need 64 LEDS. I had some spare 25 LED xmas light strings, so I used these as my source for the LEDS.

Timber for making the frame.  This frame used approx 3.6m of 45mmx18mm of timber. 

Arduino Uno

Power Supply (I used a 9v battery)

Copper Wire for the wiring inside the frame. This copper wire has a coating on it which is not conductive so is ideal for this. The type used in motor windings is ideal. I got this from the local metal scrapman.  Need about 19m of this. The thicker the wire the better.

Cat 5 (network) cabling so the matrix pins can be connected to the microcontroller.

Screws and/or wood glue to build the frame.

Keypad, Microphone, Resistors, Capacitor's and op-amps required for the hardware add-ons. Please see those steps for the links to the other instructables that list the required components.


Tools Required

Saw for cutting the timber
Staple gun for attaching the copper wire to the frame
Soldering Iron and solder
Multimeter
Pliers
Electric Drill + drill bits
Computer to program the Arduino along with the correct USB cable.
Sharp knife - Stanley knife or similar.


Step 2: Theory of Operation

Picture of Theory of Operation

Trying to light up 64 LEDS in an controlled manner such that you can turn on individual LED's to create shapes or animations, would normally require all 64 LEDS's to be connected individually to some kind of controller. 

The Arduino Uno only has 18 connections (pins) that can be utilised for this type of behaviour. Therefore no good for this type of application. But that can be changed by multiplexing the LED's connection using a matrix. 

What is this you ask. Well its a method of connecting a large number of LED's to a controller with a limited number of pins. For this project we would only need 16 pins on the microcontroller to control the 64 LEDS. 

Please note that the explanation below are meant in their basic terms without getting to technical. 

First we need to understand how LEDS work. LEDS are basically diodes. i.e. they only allow voltage to flow in one direction.  If were to connect a diode and a light bulb to a battery then the bulb will light if the diode is used in the right direction. If reversed then the bulb will not light.  Same with a LED (light emitting diode). If connect directly to a 3v battery then it will only light when connected the right way round. That is the anode (longest lead) being connected to the + of the battery and the cathode (shortest lead) connected to the - of the battery.  This is important for the operation of the matrix.

 Therefore we can use this theory of LED's in the matrix below. If we connect Col 1 to ground and Row 1 to a + voltage then the LED where these two lines meet will light up. No other LED's will light up due to no voltage flowing to them. If we reverse the voltage on just one of the lines then that LED will turn off.

If you want two LED's to appear to be on then you turn the first one on and then off. Then really quickly you turn the other one one on and off. If you repeat this cycle really fast then to the person watching they will appear to both be on. This is called persistence of vision (http://en.wikipedia.org/wiki/Persistence_of_vision ) and is very useful for these type of projects.

Using this theory means that we only need 16 input pins on the Arduino rather then then the 64 pins to drive each LED. 



Step 3: Constructing the Frame.

Picture of Constructing the Frame.

As the matrix is 8 LED's wide and 8 LED's high I made the frame to make each LED be 100mm apart in both directions. I also wanted the thicker part of the timber to be the side that I threaded the copper wire through. Use the wood in any orientation you require but change the lengths below to suit.

Hence I needed a frame that would be 900mm x 900mm on the inside measurements. Hence I cut two pieces of the timber to be 900mm wide and another two to be 900mm+ thickness of the timber wide). In my case the thickness is 18mm so the timber should be 936mm long.

I then measured and marked every 100mm along the shortest timber pieces so I knew where to drill the holes to thread the copper wire through.

For the longer pieces you need to the same, but don't forget to  start measuring at 18mm in from one end. This is to take into account the construction of the frame. This part can also be done once the frame is constructed.

Once the holes are marked then drill a hole in each one. Select a drill bit just larger then the diameter of the copper wire you are using. Sand the holes drilled so everything is smooth and no sharp edges exist.

Then you need to put the frame together. I just screwed and glued the frame where they met. Don't forget to make the shorter pieces the inside pieces of the frame. See the sketch to see what I mean.

I then sanded the frame so make it all smooth and get rid of the pencil marks I had made on it. You could paint or stain it at this point if you want to make it look nicer. I didn't and wish I had. But I can remove the copper wires fairly easily and do it later if I really wanted to.


Step 4: Copper Wire Matrix

Picture of Copper Wire Matrix

Once the frame has been assembled and has dried if painting it you can create the copper wire matrix.

Choose which side you wish to be non-connected side and which side to be connected to the wires that go to the microcontroller

The wire I used was 19m long and in one long piece. 

First we pushed the wire through the top hole on one side of the wooden frame.  Leaving a short piece sticking out (about 30mm) Then pass it through the corresponding hole on the other side. At one end staple the wire to the frame. We did this with the wire going one way and then pulled it back over the hole and stapled it again. 

At the other end that has the rest of the wire, pull the wire taunt and staple this as above into place.  Then cut this leaving about 40 - 50mm of wire exposed. Repeat for all 8 holes along one side. Make sure the longest pieces left are all on the same side.

For the 8 holes in the other direction repeat as above but when you do this weave the copper wire around the existing copper wires going in the other direction. This will create some strength in the matrix. 

We used insulated copper wire so I knew that I could cross the copper wire without creating shorts. If yours is not insulated then use something that is not conductive to insulate the wires where they cross.

At the sides of the frame where you left the longer pieces of copper wire, scrape the coating off using a sharp knife. Then using a multimeter in check continuity mode, check that none of the wires are electrically touching each other. Hopefully your multimeter shouldn't sound when you check each wire against another. Read your multimeter manual on how to use your multimeter in this mode.






Step 5: The Fun Part - the LED's

Picture of The Fun Part - the LED's

Once the frame has been assembled and the copper matrix has been tested we need to attach the LEDS. 

I used a string of Xmas lights as my source for the LED's. I cut each LED off so that I had about 80mm of insulated cable with each LED. As the lights are usually wrapped in insulation I didnt know what was the anode (+) and which was the cathode (-). I found this out by connecting one to a battery and noting which way round it had to be in order to light up. Luckily on these lights one wire had a white stripe along it, which also happened to be the anode (+) wire.

Put the frame in the orientation you want. i.e. top at the top, left at the left.

Once you have the 64 LEDS cut off the string then we need to attach them to the copper wire matrix.  To do this I just split the insulated cable into two insulated wires and then tied the LED to where the two copper wires crossed. Making sure that all LED's ended up on the same side and the knots behind. You could glue them on if you wished or use tie-wraps to attach them. Use any method you wish.

Then I cut the wires left on the LED's after the knot tying to be about 20 - 25mm long. Strip about 7mm of insulation from the wires and twist the copper strands in the LED wire so they are together.

 With the frame in the correct orientation, I decided to make the vertical (up-down) copper wires the anode wires and the horizontal (left-right) wires the cathodes. Work out where you will solder the wires to the frame and scrape the coating away from the copper wire at this point. Then wrap the correct LED wire to this point and solder it in place. Remember the anodes of the LED are connected to the vertical copper wire and the cathodes to the horizontal copper wire.

Repeat for each of the 64 wire crossing points. This will take a while to do. I recommend taking a break every so often due to the solder fumes.


Step 6: Solder the Connecting Wires.

Picture of Solder the Connecting Wires.

Now we need to solder the network cable wires to the frame which will then connect it to the microcontroller. 

I used a 6m network cable which I cut in half and remove the cut the plugs off both cables. I removed  the outer insulation from the bundle of twisted cables. Each bundle will have 8 wires in it.

Remove 7mm of insulation from each wire and then wrap this around the longer wires in the copper frame and solder them on. To make it easier to identify each pin, I solder the same colour wires to pin 0 in the horizontal and vertical orientation on the frame.

Then strip 7mm of insulation from the other end of the network cables.

Step 7: Testing the Matrix

Picture of Testing the Matrix

There are two ways to test the matrix once you have done all the soldering

First Way

Take the cathode wire for row 1 and connect it to the - side of a 3V battery.
Take the anode wire for column 1 and connect it to the + side of the 3V battery. The LED in position 1 should light up.

If not then check your connections are round teh right way and that the solder connections are good.

Repeat this test for every combination of cathode and anode wires. They should all light up ok.

But this way is time consuming and boring. We have a Arduino to connect to anyway so why not use this to test the matrix.

Second Way

Connect the wire attached to the anode column 1 and plug into pin 2 on the Arduino
Take wire connected to anode column 2 and plug into pin 3 into pin 3 on the Arduino
Take wire connected to anode column 3 and plug into pin 3 into pin 4 on the Arduino
Take wire connected to anode column 4 and plug into pin 3 into pin 5 on the Arduino
Take wire connected to anode column 5 and plug into pin 3 into pin 6 on the Arduino
Take wire connected to anode column 6 and plug into pin 3 into pin 7 on the Arduino
Take wire connected to anode column 7 and plug into pin 3 into pin 8 on the Arduino
Take wire connected to anode column 8 and plug into pin 3 into pin 9 on the Arduino

Connect the wire attached to the cathode row 1 and plug into pin 10 on the Arduino
Take wire connected to cathode row 2 and plug into pin 3 into pin 11 on the Arduino
Take wire connected to cathode row 3 and plug into pin 3 into pin 12 on the Arduino
Take wire connected to cathode row 4 and plug into pin 3 into pin 13 on the Arduino
Take wire connected to cathode row 5 and plug into pin 3 into pin A5 on the Arduino
Take wire connected to cathode row 6 and plug into pin 3 into pin A3 on the Arduino
Take wire connected to cathode row 7 and plug into pin 3 into pin A2 on the Arduino
Take wire connected to cathode row 8 and plug into pin 3 into pin A1 on the Arduino

On the computer, load the Arduino programming environment. Download the test sketch below and upload it to your wired up Arduino. The LED's should then all flash together. 

If any don't light up then check your solder connections and that they are wired around the correct way.




Step 8: Programming the Sketch

Picture of Programming the Sketch

In the previous step we tested all the LEDS using the arduino. 

This is how the sketch works. If unsure on the programming principles used, please search the web on how these work.

At the top we setup the array of pins that are connected to the LED matrix.
We create two arrays one called row[] and col[]. row[] is the list of cathodes and col[] is the list of the anodes.

Next in the setup function (void Setup) we set the Arduino up to control the matrix.
First it sets all the pins to be OUTPUT. This is done in the for loop, which just iterates through all the pins listed in the arrays and sets them to OUTPUT. It also sets the cathodes to HIGH.

This activates the pins so when we set them to HIGH a voltage is sent out on that pin, and if sent to LOW then the pin is connected to ground. In the setup we set all cathodes to high so all LEDS will be off, irrespective of the anode state (high or low). This is probably the easiest way to make sure that an LED is off without having to check the anode state.

So if we send a row to LOW and a column to HIGH then where these two meet the LED will light up. If we send both row and col to either HIGH or LOW then the LED will not light up as there is no flow of voltage around the circuit.

The loop function is run automatically by the arduino. When it gets to the end of the loop function then it runs again. so we can use this behaviour to turn on each LED.
First the for loop, goes through all the pins in the arrays and turns all rows to LOW and all columns to HIGH
Then a delay of 500 milliseconds is called. If you want the lights to flash slower then increase this number. To speed up the flash then decrease this number
Then it will  turn them all off, by setting the rows to HIGH and the columns to LOW
Then a delay of 500 milliseconds is called so the lights will flash.

This code is fine for just the simple test, but in the next step we will improve the code to help draw animations and different effects.



Step 9: Changing the Code

This is my version of optimising what I have done. There are probably better ways of doing it, but this works for me and allows me to quickly write new effects. 

In the previous code I ran code to turn on each row and column one at a time. This is fine for a quick test and shows beginners how the arduino operates. But as you get more complex then its not very efficient and the program size will be to big to fit onto an arduino.

To make it easier to use and expand later we will create some new functions.

The first function is called resetLEDS() When this is called then will turn off all LEDS at once. This is the same as the setup routine, but we just dont have to setup the pins as OUTPUTS. This for loop just iterates through the arrays and turns off all  the LEDS.

void resetLEDS() {
  for (int thisPin = 0; thisPin < 8; thisPin++) {
               digitalWrite(col[thisPin], LOW); // Turn off LEDs
               digitalWrite(row[thisPin], HIGH);


The next function we will create is turn on a single LED. It will wait for a determined time and then turns it off First we need to add a new variable above the array definitions.  Add the following line 

int delayPin 1;  // This delays the code before it turns the led off

Then we add two new functions

void resetLEDS() {
   for (int thisPin = 0; thisPin < 8; thisPin++) {
    digitalWrite(row[thisPin], HIGH); 
    digitalWrite(col[thisPin], LOW); 
  }

}

void onLED(int colnum,int rownum) {
  digitalWrite(col[colnum], HIGH);
  digitalWrite(row[rownum], LOW);
  delay(delaypin);
  digitalWrite(col[colnum], LOW);
  digitalWrite(row[rownum], HIGH);
}

The first function just goes through every LED and turns them all off

The second function works by taking a col and row number that is passed to it by the main program code. The code then turns the required column (anode) to HIGH and the required row (cathode) to LOW which will light a particular LED. A delay is then called and then the LED is turned off by reversing the states above.

With this function we can then change the loop code to read like this

  onLED(0,0);
  onLED(1,1);
  onLED(0,1);
  onLED(1,0);
  onLED(6,0);
  onLED(7,1);
  onLED(6,1);
  onLED(7,0);
  onLED(3,3);
  onLED(4,3);
  onLED(3,2);
  onLED(4,2);
  onLED(0,5);
  onLED(1,6);
  onLED(2,7);
  onLED(3,7);
  onLED(4,7);
  onLED(5,7);
  onLED(6,6);
  onLED(7,5);


This should give you a smiley face pattern on the matrix. As this loop runs quickly the LEDS will appear to be all permanently on due to the brain thinking it sees all of the LEDS on at the same time. 

To make the LEDs appear to flash then you can change the loop function to read this
for (int x = 0;x <  500;x++); {
   onLED(0,0);
  onLED(1,1);
  onLED(0,1);
  onLED(1,0);
  onLED(6,0);
  onLED(7,1);
  onLED(6,1);
  onLED(7,0);
  onLED(3,3);
  onLED(4,3);
  onLED(3,2);
  onLED(4,2);
  onLED(0,5);
  onLED(1,6);
  onLED(2,7);
  onLED(3,7);
  onLED(4,7);
  onLED(5,7);
  onLED(6,6);
  onLED(7,5);
}

resetLEDS();
delay(500);

Download the sketch (ChangedLEDTestFlash) below to see the changes.


Step 10: Creating Animated Effects

Picture of Creating Animated Effects

In the previous step we created one effect called smiley face. with each effect I like to put them into their own function. so continuing the sketch we have been building, add the following three functions. This will create our first animated effect.

void drawSmileyFace() {
  onLED(0,0);
  onLED(1,1);
  onLED(0,1);
  onLED(1,0);
  onLED(6,0);
  onLED(7,1);
  onLED(6,1);
  onLED(7,0);
  onLED(3,3);
  onLED(4,3);
  onLED(3,2);
  onLED(4,2);
  onLED(0,5);
  onLED(1,6);
  onLED(2,7);
  onLED(3,7);
  onLED(4,7);
  onLED(5,7);
  onLED(6,6);
  onLED(7,5);
}

void drawSmileyFaceWink() {
  onLED(0,0);
  onLED(1,1);
  onLED(0,1);
  onLED(1,0);
  onLED(3,3);
  onLED(4,3);
  onLED(3,2);
  onLED(4,2);
  onLED(0,5);
  onLED(1,6);
  onLED(2,7);
  onLED(3,7);
  onLED(4,7);
  onLED(5,7);
  onLED(6,6);
  onLED(7,5);

}

void MakewinkingFace() {
  for (int x=0;x<40;x++) {
  drawSmileyFace();
  delay(1);
  }

  for (int x=0;x<40;x++) {
  drawSmileyFaceWink();
  delay(1);
    } 
}

The first two functions that we just created create the two effects. One a smiley face and the other a smiley face with the right eye not drawn. The third function calls the two functions in a for loop to create the effect of a winking smiley face.

We can test this by changing the void loop to read like this. 

void loop() {
    MakewinkingFace();
}

Using these methods we can then create any effect we want and then use for loops in a sperate function to create moving animations.  

Use the same theory above to create your own animations. Put them into separate functions beneath the existing code and them call them in the void loop function. You can put multiple functions in here so it will run the different animations you have created. When you call the different animations put them into a for loop like below to that they will run for a few seconds before the next one runs.

for (int x=0;x<500;x++) {
    animation1
}
for (int x=0;x<500;x++) {
    animation2
}
......

In the next step will see how to randomise which animation to run.

To work out which LED's need to be turned on, create 8x8 grids and colour in which squares you want to be on. This makes it easier to work out which column and row needs to be switched on.

Any one remember those days of sprite programming on the Spectrum 48k ????

Step 11: Randomise the Animation to Play

Hopefully you have now created your own animations and have quite a few to run. This looks fantastic when each animation runs, but can quite boring as it runs them in the same order everytime.

This change will run them in random order.

at the beginning of the sketch under the array of pins we need to add a new array definition

void (*funcAnimate[2])();

This sets up a pointer called funcAnimate. Without going to its actual working details it basically sets up an array of functions that we can call in the loop function. We can call a random array element from this array and then that function will run. This allows us to run 3 random animations. If you have more then 3 then change the number in the square brackets. Remember it must be one less then the total number of animations. (Due to array's starting counting at 0)

Then in the setup function we need to define which animation is linked to which funcAnimate array element. Add the following two lines and change animate1 and animate2 to the actual names of your animation functions

funcAnimate[0] = animate1;
funcAnimate[1] = animate2;

Then in the loop function we need to change the code to randomly call an array element from the funcAnimate array.

void loop() {
int randnumber = 0;
randnumber = random(0,1);
for (int x=0;x<2;x++) {
  (*funcAnimate[randnumber])();
  delay(1);
}
}

In the loop, a random number is selected between 0 and 2 (i.e. 0 or 1). Then the loop will call the animation that is in that position in the array. If you have more then 2 animations then change the random number from 2 to the number of effects you have.

The code below so far should give you an idea of how to create animations and show them on the LED matrix. 

Step 12: Hardware Add-on 1 - Keypad

Picture of Hardware Add-on 1 - Keypad

I liked the random animations I could call, but for the party I wanted to override this and put on a certain animation only and not change it. Hence the first add-on - a keypad to allow a certain animation to be selected.

Problem with this is that we only have 3 inputs left on the Arduino so using a keypad in its normal way wont work. So after some research here and on the internet, I found a solution to only use one input to detect which button has been pressed.

Read this excellent instructable  https://www.instructables.com/id/Arduino-3-wire-Matrix-Keypad/  on how to detect the pins on your keypad and howto wire it up to only use one input. Once I had build the resistor matrix, I connected the keypad output to pin A2. I used a breadboard whilst testing this hardware. I also soldered header pins to the keypad so I can disconnect it to and from the breadboard easier. also when I build the final circuit everything is modular and can be plugged in easily.

Hence I added the following three declarations just under the array definitions
int keyboardPin = A2; 
int keyboardValue = 0;
int keypressed = 0; 

Then I added the following function to allow me to read in which key has been pressed on the keypad. Note my values are different from the instructable above as I used different resistor values.

void readkeyboard(){
   keypressed = 0;
   keyboardValue = analogRead(keyboardPin); 
   if (keyboardValue <25) {keypressed = -1;} 
   if ((keyboardValue >25) && (keyboardValue < 45)) {keypressed = 1;}
   if ((keyboardValue >45) && (keyboardValue < 80)) {keypressed = 2;}
   if ((keyboardValue >80) && (keyboardValue < 160)) {keypressed = 3;}
   if ((keyboardValue >162) && (keyboardValue < 253)){keypressed = 4;}
   if ((keyboardValue >253) && (keyboardValue < 361)){keypressed = 5;}
   if ((keyboardValue >361) && (keyboardValue < 479)){keypressed = 6;}
   if ((keyboardValue >479) && (keyboardValue < 585)){keypressed = 7;}
   if ((keyboardValue >585) && (keyboardValue < 715)){keypressed = 8;}
   if ((keyboardValue >715) && (keyboardValue < 760)){keypressed = 9;}
   if ((keyboardValue >839) && (keyboardValue < 880)){keypressed = 10;} 
   if ((keyboardValue >760) && (keyboardValue < 839)){keypressed = 11;}
   if ((keyboardValue >880) && (keyboardValue < 1000)){keypressed = 12;} 
   delay(50);
}


This function works by detecting which key has been pressed based upon the value on the keyboard input pin and then setting the global variable keypressed to a number that corresponds to this.  

The loop function is then changed to read like this

void loop() {
   int randnumber = 0;
   readkeyboard();
  if (keypressed > 0 && keypressed < 12) {
    manualEffect = 1;
    prevKeyPressed = keypressed;
    for (int x=0;x<2;x++) {
      (*funcAnimate[keypressed])();
      delay(1);
    }
  } else if (keypressed = 12) {
    manualEffect = 0;
    // Let the loop run through again and the final else statement will then run a random effect
    // as the manualEffect has been reset
  } else if (manualEffect = 1) {
      for (int x=0;x<2;x++) {
        (*funcAnimate[prevKeyPressed])();
        delay(1);
      }
  } else {
      randnumber = random(0,2);
      for (int x=0;x<2;x++) {
         (*funcAnimate[randnumber])();
         delay(1);
      }
  }

This works by reading the keyboard value.

Then an if statement checks to see if a key has been pressed between 0 and 11
If this is true then it sets manualeffect to be 1 and then runs the chosen effect.
If the # key has been pressed then it will set manualeffect to 0, so the next time loop is run as no key will be pressed and manualeffect is set to 0 so then a random effect is run
Then the If statement checks if manualeffect is equal to 1. This happens if a key has been pressed previously and started running a manual effect. This allows us to continue playing the previously chosen manual effect.  This manual effect will continue running until another key is pressed
The final else statement will run if manualeffect is set to 0, which will happen when the unit is turned on or when the random key is pressed. Then a random effect will run.

The final adjustment to the sketch is to add the following function

void dummy() {}

Then to the array of functions change to read like this

  funcAnimate[0] = dummy;
  funcAnimate[1] = MakeSadSmileFace;
  funcAnimate[2] = MakewinkingFace;

Then change the randNumber = random(0,2); to randnumber = random(1,3);

These changes mean that when the keypad is pressed the function at array position 0 is never run due to the variable assignments. So we just add a dummy function there that does nothing. We also changed the randNumber being assigned a random number to start from 1, again so array position 0 is never run.

The full sketch is below.





Step 13: Hardware Add-on 2 - Sound Level

Picture of Hardware Add-on 2 - Sound Level


The final part to this matrix I wanted, is some animations to react to sound levels. I wanted the LED's to flash to the level of the sound.

I found this instructable which seemed to fit my requirements https://www.instructables.com/id/A-wearable-sound-to-light-display-without-a-micro/  I used the first half of his circuit and too the output of the first op-amp and connected that to the last remaining input pin on the Arduino. The second op-amp circuit can be ignored. The only change I made was to substitute the 470K across the output and input pin of the first op-amp with a potentiometer valued at 0 - 500K.  This allowed me to adjust the sensitivity of the circuit. 

Once you built the circuit, plug it into the remaining input pin left on the Arduino. Pin A1 in my case. I tested the circuit before integrating it into the main LED matrix sketch by creating a new sketch and adding the following code

int sensorPin = A1;

void steup() {
  Serial.begin(9600);
}

void loop() {
int soundValue = 0;
soundValue = analogRead(sensorPin); 
if (soundValue > 500) {
           Serial.println(soundValue);
}


This code reads the analogue value on the input pin A1. run this sketch and load the serial monitor. When you play music you should see the values being printed in the serial monitor.

I found that music at a reasonable level always produced a value above 500. If you don't get anything printed on the serial monitor then change this value to a lower one until you get some values being printed. for the animation I wanted the LED's to flash at the different volumes within the song. So make a note of the levels that are being printed during the louder parts of the song. 

To the main LED matrix sketch I added the following variables beneath the array declarations

int sensorPin = A1;
int soundValue = 0;
int delayOn = 30;

I then added the following function

void loopReadSoundLevel() {
   int soundValue = 0;
   soundValue = analogRead(sensorPin); // read the pot value
   if (soundValue > 500 && soundValue < 510) {
     DrawBox1On();
     delay(delayOn);
    resetLEDS();
   } else if (soundValue > 500 && soundValue < 510) {
     DrawBox2On();
     delay(delayOn);
     resetLEDS();
   } else if (soundValue > 510 && soundValue < 520) {
     DrawBox3On();
     delay(delayOn);
     resetLEDS();
   } else if (soundValue > 520 ) {
     DrawAllOn();
     delay(delayOn);
     resetLEDS();
   }
   delay(100); // wait 100 milliseconds before the next loop
 }

This function reads the analogue value from the circuit.
Then depending on the value received it will display the effect that I want. See the attached sketch for the code for these effect declarations. 

Using the potentiometer in the circuit you can adjust the sensitivity of the circuit to change the volume when these effects are displayed. You can also change the values in the function. I found this circuit and code made the LED's flash in the mid level of the music. The treble and bass don't really effect when the light flash.

To get this sound animation to run you will need to add the function to the array of functions declared earlier. In the sketch below I have added all the code and assigned it to key 3, so it will run constantly. 





Step 14: Putting It All Together

Picture of Putting It All Together

Once I had all the hardware add-ons working I then transferred the circuits to a stripboard and soldered the components in. I also soldered the wires from the matrix to this stripboard.

I then added header pins so I could plug this board into the Arduino. I also added header pins so I could attach the keypad to the strip board as well. Using the header pins also allows me to keep the Arduino separate and used in other projects.

As you can see from the photos I scraped the copper tracks away where the circuit should be broken. 

I then put the completed circuits into an empty margarine tub which I covered in paper. The keypad I cable tied into the tub. I cut out a rectangle that the keypad could fit into from underneath. Then I put a hole in each corner and threaded the cable tie through the tub and each hole underneath. Then pulled them tight. Held the keypad in securely enough for me.

 I then connected a 9V battery to the Arduino so I could run it away form the computer for the party...

I also cable tied the cables to the frame. I wish I had painted it before I finished, but the party day was approaching and I didn't get time to do this. 


Comments

Snehil1101 (author)2015-11-09

Hey Frnd! I made the matrix hurray!!!! I also learned how the program(s) works..But i want to make a scrolling text program and i dont have and plot on it....I went on many other instructables but none seem to explain how to make one without the use of any ic. Every one use the 4017....But im a beginner to arduino and i dont want to make the circuits messy...Plz help with a program that can scroll any text I give it.....

ShioriToshiko (author)2015-10-11

So I thought I typed the code right... but I got an error message that said "a function-definition is not allowed here before ' { ' token."

djsadeepa made it! (author)2015-01-10

Hey i was able to create the smaller version of this matrix, thank you.

it worked fine. https://www.instructables.com/id/Make-a-8-x-8-LED-Matrix-Cheap-and-Simple

rsmg_14 (author)2012-07-27

hi ndsit! so im building a "Yet Another Daft Punk Table" (https://www.instructables.com/id/Yet-Another-Daft-Punk-Coffee-TableDisplay/)
and im using your sketches and code as reference to make my animations. i find it really easy how you did it, thanx! :) .... quick question, i notice that when i upload your "all LEDs blink On and Off" Sketch, i find that the LEDs are way brighter than within any other animation i create. i know that as a whole it looks that way because the entire matrix is on at "once" (POV) but still i find that individually they have more intensity when they blink than with other animations. can you tell me why and what can i do to have the same brightness throughout my whole sketch. sorry if this sounds confusing :s....

triodo (author)2011-08-28

se ve cheverisimo los led

fostersfriend (author)2011-07-04

You should really use hex code saves alot of memory

arodri35 (author)2011-05-24

I'm curious on how you managed to drive that mmany leds with the current limit on the arduino. I'm trying to drive 25 in the same way.

ndsit (author)arodri352011-05-25

The LED's appear to be all on at the same time, but they are actually rapidly turning themselves on and off one at a time, so the current draw is not that bad. This is the persistence of vision effect I described. I should have used resistors to stop damaging the microprocessor with the current draw, but so far its been ok. hope that helps

arodri35 (author)ndsit2011-05-25

haha i feel dumb i knew that. where exactly would you place the resistors. would you give each led its own or would you just put it right before the pin. so in the test leds file you turn them on and off rapidly?

ndsit (author)arodri352011-05-25

Put the resistor between the pin and the LED. Yes in the code it turns the LED on and off very quickly. AFAIK there is no need to use a npn transistor at each pin.

arodri35 (author)ndsit2011-05-25

oh ok i just figured it might make it a little less current for the arduino, i've heard they're not very fond of current, going in or out so i thought that could be used as a precaution. as far as the resistors go thanks i thought that's how it was supposed to go thanks for the help. im making what essentially might be a touch screen using the arduino capsense and your matrix. if the capsense doesn't go well ill just make it a mini display haha thanks again

ndsit (author)arodri352011-05-26

Good luck with your project and hope to see it posted on instructables soon

arodri35 (author)ndsit2011-05-25

also, would it be smart to use a 2n222 npn transistor at each pin ????

phanna (author)2011-05-01

Excuse me! could you tell me what components that you use in this project? and what program you generate this code?

jschuster (author)2011-04-06

I try uploading the test code to my uno and i get

Binary sketch size: 1178 bytes (of a 32256 byte maximum)
avrdude: stk500_getsync(): not in sync: resp=0x30
avrdude: stk500_disable(): protocol error, expect=0x14, resp=0x51

I have loaded the Arduino environment and I'm not sure what id doing wrong. Do you have any suggestions

ndsit (author)jschuster2011-04-06

Try the arduino forums on their main website for help, they are best suited to helping you.

jschuster (author)2011-03-23

Do you have to go to the strip board or can you go straight to the arduino?

ndsit (author)jschuster2011-03-31

You can goto the arduino direct, its just I was using some custom circuits for controlling some effects and also using the keypad, so the stripboard was just an easier route to follow.

jdanderson1 (author)2011-02-20

when you build this check the programming it uses A0, A3,A4,A5 in the Arduino program. The instructions don't reflect this they use different address lines so if you have a problem check your outputs.

Otherwise i really like this still in the process of building one.

raikoug (author)2011-02-06

Hi, i really love your work, and I thank you very much.. but.. (maybe is a n00b question) the copper wire... doesn't touch each other right? do you use the cover of the wire led to separate the crossing? that's amazing if i'm right (you see? this is a very noob question becouse i shiould really know if + and - should touch each other, and I'm pretty sure they don't have to, but maybe ... dunno :P)
thanks anyway for the big work ^^

ndsit (author)raikoug2011-02-06

The copper wire does touch each other, but it has a thin plastic layer covering the whole wire. Its polyester enamelled copper wire, normally used in electric motors.

Hence it does does touch physically but not electronically as they are insulated from each other. I actually have to scrape the covering off so I can solder the LED wires to the cable. Hope that makes sense

raikoug (author)ndsit2011-02-07

Oh... that's funny.. thanks a lot!!

bluumax (author)2011-02-06

Great job!!
If you can PWM the outputs you can do without resistors.
I used wrapping wire for a tiny Christmas tree project using 0603 size LEDs. & a PIC http://www.bluumax.com/Tree.html
It's kind of a trick for electronics people, how do you get + & - with only bare wire?

mal511 (author)2011-02-06

I think the expression "nit picking" is appropriate, don't you tigerbomb8..?

BWChronos (author)2011-02-04

Awesome LED matrix, but you couldn't have asked your mom to move for like five minutes when you filmed this?

In all seriousness: this is awesome man, keep up the good work!

member02 (author)2011-02-03

I see no current limiting resistors. To prevent damage to the arduino/LEDs you should add resistors.

take note, V=IR, Volts=Amps*Resistance

so blue LEDs have about 3-3.2 voltage drop across them, the arduino sends them 5volts. to achieve a 3.2v connection to the LED you need a 100ohm resistor in series with the LED. See, LEDs at 5v will try to draw well over 80mA, chances are the arduino can't supply much more than 50mA per pin, as per their spec sheet. This obviously causes stress on the system you have.

I normally don't care to help people that make this routine mistake, but this was featured and it is nice looking, so fix it!

omnibot (author)2011-02-03

Sweet! That's some LED-display. Any ideas for implementing a frequency analyzer och similar?

ndsit (author)omnibot2011-02-03

I intend to in the future switch to use shift registers or something to free up some inputs on the Arduino so I can do better analysis of sounds and add other inputs

mrtimklein (author)2011-02-03

Love it. I'm working on a similar project -- wearable light show for a "techno" dance. I'm struggling with software, have you made any progress on mic input and possibly even beat detection?

ndsit (author)mrtimklein2011-02-03

I have the mic input already, see the hardware add-on steps. The even beat detection I haven't made any progress on, but I think for a better detection you will need to split the signal into its bass,mid and treble and then detect on these levels. Sadly I don't have enough inputs to do this at the moment.

shabaki (author)2011-02-03

while i understand it would take just over 512 leds it would be amazing to make an 8 by 8 cube and rig it up to some overly complex ai system with interactive sensors ( such as voice sensors or stuff like light sensors) and program it so the ai had an avatar "head that floated in the cube with different expression based on "emotions" in its coding so that you had a fully functioning ai bot; rig it to your comp, tv or entertainment system and you have a diy jarvis from iron man :P

tigerbomb8 (author)2011-02-03

leds are basically diodes
wrong leds ARE diodes