loading

Yet Another Daft Punk Coffee Table (5x5 LED Matrix)

FeaturedContest Winner
Picture of Yet Another Daft Punk Coffee Table (5x5 LED Matrix)
dp4.jpg
dp.jpg
Yes, I know this has been done before, but I wanted to build my own, using as few parts as possible.  I built this as a table top or wall mount model, but it can be scaled up to make a coffee table.  I built it as a study for a more ambitious project, which will be an 8x8 RGB coffee table.  In designing this project, I wanted to keep the part count and cost as low as possible, and also to design the software for speed and minimal memory usage.

The code I used in the Arduino sketch demonstrates direct port manipulation, which is a fast and powerful alternative to digitalWrite().

Update 3/10/2011 : Finished adding the Music Synchronization section of this Instructable.
Update 3/20/2011:  I decided to build Lampduino instead of the coffee table.

Note that the flickering in the video below was caused by my video camera. When viewed with the naked eye, no scanning is perceived, and the lights do not flicker.

Music Sync Mode:
Arvid "Try (fenomenon remix)"


Syncing to Daft Punk's "Around the World:
 

 

Free-running mode (without music synchronization):













 
Remove these adsRemove these ads by Signing Up

Step 1: Acquire the Parts

Picture of Acquire the Parts
Parts List

25 LED's - I used warm white 5mm LED's purchased on eBay
5 resistors - I used 100 ohm, but the exact value will depend on what LED's you use. I will explain how to calculate in the Wiring step. 
NOTE: You may need also need 10 diodes and different resistors, especially if you are using white LED's... please the Troubleshooting section in step 3 for details.
Arduino - I used a Duemilanove clone - in Step 7, I switch to a much cheaper alternative.
wire
white foam board
.005" thick matte drafting film - I bought a sheet from a local artist's supply store.  The smallest sheet they had was way more than I needed - 24x36"

If you want to implement music synchronization capabilities, you will also need some more parts, as discussed in the Music Synchronization step.

Tools Needed

hot glue gun
mat knife
soldering iron
solder
pliers/wire cutters

The LED's I used were point source water clear.  If you don't want to deal with hotspots in your display, diffused would be better.  I had to put blobs of hot glue on mine to diffuse them.  The photo below only shows bits of the foam board, because I forgot to photograph the parts before I started.  The piece I used was about 16x20" to start with.

Step 2: Build the Display

Picture of Build the Display
ledtest2.jpg
I used foam board, which was recycled from one of my kids' science fair projects. It is a sandwich of white paper with a foam core, 3/16" thick. The overall size is approximately of our project is approximately 10x10x2".  I cut the parts with a mat knife, and hot glued it together.

To make the grid, cut 8 identical 2x10" pieces.  Then cut 4 equally spaced slits into each one.  The slits should be 1" deep,  the same width as the foam board.  Interlock the pieces to create the 5x5 grid.

Next, cut a 10x10" piece of foam for the back.  Hot glue it to the 5x5 grid.

Cut 2 more 2x10" pieces to form the sides, and glue them on.

Finally, cut the 2 (10 3/8)x2" pieces for the top and bottom.  My foam was 3/16" thick, so I had to add 3/8" to the length to make them long enough to cover the sides.  Hot glue them on.

Note that in the photo below which includes the top & bottom & sides, the LED's are already installed and wired up.  This is because I didn't attach the top/bottom/sides until I was in the testing phase, but it's easier to deal with if you glue them on earlier in the process.

Step 3: Wire it up

Picture of Wire it up
daftpunkcircuit2.jpg
daftpunkcircuit3.jpg
ledplacement.jpg
ledwiring.jpg
daftpunkcktrevised.jpg
Cut small diagonal slits in the center of each cell, and insert one LED in each cell. Make sure to orient them the same way in each cell. This will make it less confusing when wiring it up. I laid mine out w/ the flat side (cathode) facing the bottom right corner. Using diagonal slits for the pins makes it easier to wire it up without shorting the wires, since we are going to wire
it as a crossbar.

While one can use any of the I/O pins on the Arduino, I chose the pins specifically to allow me to use very compact code to turn on the columns. This will be explained in detail later.

To drive our 5x5 LED matrix, we directly drive the LED's using 10 digital I/O pins on the Arduino.
The anodes are connected to pins.  Some existing designs, such as the one in the Arduino Playground  don't bother to use current limiting resistors.  This is not a good design practice, and can result in burned out LED's, or worse yet, a burned out Arduino.  Each I/O pin on the Arduino can source or sink up to 40mA of current.  The LED's which I used have the following electrical characteristics:

  Forward Voltage  = 3.2 ~ 3.4V
  Max Continuous Forward Current = 20mA

So if we want to drive the LED's for maximum brightness, we need to target 20mA of current.
To calculate the proper resistor value, we use Ohm's Law:

   R = (Vcc - Vf) / If

where

  R = resistor value in ohms
  Vcc = supply voltage = 5V for the Arduino Duemilanove
  Vf = LED forward voltage.  I used the average, 3.3V
  If = LED current in amperes = .020A

Plugging in the values, we get R = (5 - 3.3) / .02 = 85 ohms.  The nearest available standard resistor value is 100 ohms.  Always round up instead of down, because if you round down, you will exceed the maximum allowable current.

Notice that we only use 5 resistors.  We don't have to put one at each LED, because we will only be driving one row, a maximum of 5 LED's at a time.  I said above that each I/O pin can drive 40mA of continuous current, so why can't we drive the whole LED array at once?  It's because another constraint is that the total drive current summed up across all the pins can't exceed 200mA.  If we turn on all 25 LED's at once, then 25*20mA = 500mA flow, which is way over spec.

So maybe we can turn on 1 row at a time, and scan the rows, like the way a CRT works?   If we turn on a whole row of LED's at once, the current is 20mA * 5 = 100mA.  This, at first, appears to be OK, because each column (anode) pin is only sourcing 20mA, and we're below the Atmega368P's total 200mA current limit.  However, upon more analysis, we can't even drive 5 LED's at once.  Why?  Because the cathodes of all 5 LED's in a row are connected together into a single I/O pin, and we're not allowed to sink more than 40mA per pin.  Therefore, we will write our software so that no more than 2 LED's are turned on at a time, so the row (cathode) pins will sink a maximum of 40mA each.  Now, even though we're at the allowable continuous current limit, it's generally not good practice to run a device at its maximum limits.  However, since we're going to pulse each LED briefly, and let persistence of vision create the illusion that they're all on at once, it's OK.

Note:  I tried running mine w/ 5 LED's lit per row for several hours, and it worked fine, but it's always best to design your circuits within specifications, to ensure long term reliability.

The circuit diagram is below.  To summarize the connections:

  LED Columns (anodes)
  col 0 connects to digital pin 12 (via a 100 ohm resistor)
  col 1 connects to digital pin 11 (via a 100 ohm resistor)
  col 2 connects to digital pin 10 (via a 100 ohm resistor)
  col 3 connects to digital pin 9 (via a 100 ohm resistor)
  col 4 connects to digital pin 8 (via a 100 ohm resistor)

LED Rows (cathodes) 
  row 0 connects to digital pin 7
  row 1 connects to digital pin 6
  row 2 connects to digital pin 5
  row 3 connects to digital pin 4
  row 4 connects to digital pin 3

I used simple point to point wiring, fastened with hot melt glue to the back of the display.  I know it's messy looking, but it won't be seen, anyway.

Troubleshooting

If your matrix doesn't function properly, first, you should double check your wiring.   The sketch also has a testing mode, which cycles through the LED's one by one slowly enough that you can see it.  You can enable it by uncommenting the following line in the sketch:

  //#define TESTMODE // continuously sequence thru the LED's

by removing the leading //.

One potential mistake is accidentally swapping the columns and rows.  If your matrix looks like this video http://www.youtube.com/watch?v=JpLgLbWMrWo in TESTMODE, then you've made this error, and need to swap the row and column connections to your Arduino.  Thanks to Instructables user 303_addict for posting the video.

If your wiring is correct, and you are getting more than one LED at a time lighting up, you might be one of the unlucky ones who has LED's that have a high leakage current when reverse biased.  White LED's are particulary susceptible to this problem.  If this is the case, you will need to add series blocking diodes on the inputs to all the columns, as well as on all the row outputs.  So you will need 10 diodes.  Any small signal diode will work, such as 1N4001, 1N914, 1N4148, etc.  You will also need to adjust the resistor values, because  two series diodes will add ~1.4V voltage drop.  So in my equation above, use 3.6 for VCC.  For my 3.3V LED's you end up with R = (5-1.4-3.3V)/20mA = 15 ohms.  I didn't have any 15 ohm resistors handy, so I substituted 10 ohms instead, and using an ammeter, measured 19.5mA .. still within spec.  See the last attached image.

Step 4: Diffusing the LED's

Picture of Diffusing the LED's
leddiffused.jpg
diffuseddp.jpg
dp3.jpg
I used point source LED's, because that's what I had in my parts bin.  This caused hot spots in the display.  If you like it that way, you don't have modify them.  I wanted more even lighting. The two most common ways of converting point source LED's to diffused is to either sand them or just encase them in hot melt glue.  I decided to use hot melt glue.  Just put a big blob of hot glue on each LED.  I found that it looks more even if you can keep the glue blob smooth.  The shape doesn't have to be perfectly round, but if you apply it in layers, the edges between the layers tend to cause variations in the brightness.  In the photo below, the LED in the top right cell has hot glue on it, while the rest are bare.  Note that it does a decent job of evening out the light.

At first, I used white copier paper to cover the LED's.  It darkened the display to bit too much, and looked grainy.  Then I went to an art store, and found .005" thick matte drafting film.  It looks a lot better.  I cut a 10 3/8 x 10 3/8" piece and glued it to the front.

Step 5: Code

Picture of Code
The Arduino sketch draws the screen scanning row by row from top to bottom, much like a CRT-based TV screen.  It has the added complexity that in order to keep our current within the limits that the Atmega328P can handle, we can only light at most 2 LED's at a time.   Therefore, we also scan from left to right.  Even though only 2 LED's at a time are lit, to our eye, they appear to all be lit at the same time due to a phenomenon called persistence of vision.

The display code is interrupt driven, and uses the Timer1 library .  Timer1 isn't bundled in the Arduino software installation.  Therefore, to install it, you must download TimerOne.zip , and unzip its contents into your sketchbook/libraries/TimerOne.

A Frame is a screenful of data. A very straightforward and common way of storing the data would be to use a byte for each LED.  This would use 25 bytes per frame.   To save memory, we define it as an array of 5 bytes.  Each byte represents an entire row of our display.  Since a byte is composed of 8 bits, and we only have 5 LED's per row, we only use the bottom 5 bits, and the top 3 bits are ignored.  There are 5 bytes because we have 5 rows.  We could save another byte by packing 25 bits into 4 bytes, but that complicates the code unnecessarily, and makes it impossible to graphically view the frame declarations in frames.h.

  #define DIM 5 // x/y dimension - 5x5 matrix
  typedef byte Frame[DIM];


The column LED pins are defined in the cols array.

  int cols[DIM] = {12,11,10,9,8};


The row LED pins are defined in the rows array.

  int rows[DIM] = {7,6,5,4,3};

To turn on a particular LED, we set its cols pin HIGH and its rows pin LOW.  This causes current to flow through the selected LED.  The most straightforward way to do this would be to use the digitalWrite() function on each LED in sequence.  So to turn on the top left LED, we could use

  digitalWrite(cols[0],HIGH);
  digitalWrite(rows[0],LOW);

and do that for each LED.  However, that's not very efficient.   Instead we use direct port manipulation to turn on the columns.  The PORTB register corresponds to digital pins 8 to 13.
Note the ordering which we used in our declaration of the cols array above:  12,11,10,9,8.  This way, bit0 of PORTB corresponds to the far right column, bit1 corresponds to the next column to the left, until bit4, which corresponds to the far left column.  If we set a particular bit to 1, it's the same as calling digitalWrite() with HIGH, and setting a bit to 0 is equivalent to calling digitalWrite() with LOW.   Therefore, we could theoretically replace calling digitalWrite() 5 times to set all 5 columns with one write to PORTB.  But since we are allowed to turn on at most only 2 LED's at a time, we have to loop 3 times for each column, scanning 2 bits at a time.

// Interrupt routine
// each time display() is called, it turns off the previous row
// and turns on the next row
byte bitMask = B00000011;
void display() {
  digitalWrite(rows[row], HIGH); // Turn whole previous row off

  if (bitMask == B00010000) {
    bitMask = B00000011; // light the right 2 columns (pins 9,8)
    // increment row and wrap if necessary
    if (++row == DIM) {
      row = 0;
    }
  }
  else if (bitMask == B00000011) {
    bitMask = B00001100; // light the middle 2 columns (pins 11,10)
  }
  else { // bitMaskIdx == B00001100
    bitMask = B00010000; // light the leftmost column (pin 12)
  }

  // direct port manipulation.
  // PORTB is a pseudo variable for digital pins 8 to 13 The two high bits (6 & 7) map to the crystal pins and are not usable
  // the bottom 5 bits are our columns. We don't want to change the other bits,
  // so we first mask the bits we ignore, and then set the bits we want to light
  PORTB &= B11100000;
  PORTB |= curFrame[row] & bitMask;

  digitalWrite(rows[row], LOW); // turn on the row
}

Note that our comment above says that display() is an interrupt routine.  This is because instead of handling the scanning in our loop() function, we call it in the background via the Timer1 library.

  // interrupt interval in uSec
  // this determines how long to keep each row turned on
  // so if we have 5 rows, we redraw the whole screen
  // once every 5 rows * 3 cycles per row * 1000 usec = .015 sec -> 66.67Hz
  // if you perceive flickering you can decrease to 500 for a 133.33Hz rate
  Timer1.initialize(1000); // fire the interrupt every 1000 microseconds
  Timer1.attachInterrupt(display); // call display() at every interrupt.

The main loop simply steps through all of our animation frames.

  void loop() {
    // increment the frame index and wrap if necessary
    if (++curFrameIdx == FRAMECNT) {
      curFrameIdx = 0;
    }

    // select frame for display
    setFrame(curFrameIdx);

    delay(400); // wait time between frames in ms - reduce this value to speed up the animation, increase it to slow it down
  }

The entire sketch is attached below.
 

Step 6: Animation Design

Picture of Animation Design
framesh.jpg
ledtest1.jpg
The animations are stored in frames.h.

   #define FRAMECNT 117

specifies how many frames are contained in your animation.
A frame is just a full screen of data.  The default animation that I put in it contains 117 frames.

You can specify frames by just typing them in one by one.   For instance, a capital 'Z' could look like:

{ B00011111,
  B00000010,
  B00000100,
  B00001000,
  B00011111}

The bottom 5 bits of each byte correspond to the pixels of each row.  Any bit which is set to 1 is lit, and 0 is off.  The top 3 bits are ignored.  This manual process can get rather cumbersome if you want to make complex animations

Ian was kind enough to share the code for his Internet Graffiti Wall . (Thanks, Ian!) I hacked it up to generate code for frames.h.  To create your own animations, simply load daftpunkanimationbuilder.html into any java-enabled web browser.  Follow the instructions on the screen to create your own animation.  When you're satisfied with it, click the Generate button, and copy the code from the text box, and paste it into frames.h, replacing its entire contents.

If you want to save your animation for editing later, check native fmt before clicking Generate, and then copy and paste the contents of the text box into a text file.  You can later load your saved animation back into the animation builder by pasting it into the Restore from sequence code text box, and then clicking Add before current frame.

Please send me any cool animations which you are particularly proud of, and I'll add them to this Instructable for others to download.

Step 7: Music Synchronization

Picture of Music Synchronization
lpmixer133hz.jpg
lpfilter.jpg

Circuit Modifications

To allow our LED matrix to synchronize the animations to music, we need to interface it to an audio source. The ATmega328 MCU conveniently contains A/D converters which we can use for this purpose. Although there are various designs for color organs, which work with various frequency bands, I prefer syncing with the bass track.

We could use an analog pin to sample music, and then do frequency analysis on the Arduino, but this would introduce a delay, and still require us to build an antialiasing filter. Since we need to build a filter, we might as well keep things simple. I built an analog low pass filter, fed its output into an analog input in, and then simply tested the amplitude against a threshold.  I started with a the simplest possible filter, a first order low pass RC filter.  Much to my surprise, it worked fairly well.  To design the filter, I first needed to figure out what cutoff frequency to use.  The cutoff frequency, Fc,  of a filter is the frequency where the power is cut in half.  After playing around with graphic equalizers in Winamp while playing music with thumpy bass tracks, I settled on Fc = 100Hz.  I didn't have the proper resistor handy, so I used the closest value I had, which resulted in Fc = 133Hz.  Here is the circuit:

Parts Needed:
(1) 10uF electrolytic capacitor
(1) 120 ohm resistor
(1) 1/8"  TRS jack



The output connects to analog pin 0 on the Arduino.  Connect its input to an audio source, such as the headphone jack of a stereo, or an MP3 player.  DO NOT CONNECT IT TO SPEAKER LEVEL OUTPUTS FROM AN AMPLIFIER UNLESS YOU'RE SURE IT OUTPUTS <= 5V.  Any audio source designed to drive headphones should be safe.  Since I use the headphone jack on a stereo, I can still hear the music even when the circuit is plugged in.  If you're using something with only one output, such as an MP3 player, you can hook up two TRS jacks in parallel, and then feed the audio from the 2nd jack to a set of powered speakers or headphones.

Note that the circuit above only monitors one channel of audio, which works with most songs, since the bass is generally approximately equal amplitude in both channels.  It works OK, but I found that in order to get a high enough input for the Arduino to respond nicely, I have to turn the volume up a bit too high for my tastes.  Therefore, I also built the alternate circuit below:

Parts needed:
(1) 10uF electrolytic capacitor
(1) 120 ohm resistor
(3) 10K ohm resistor
(1) 100K ohm resistor
(1) 1/8" stereo TRS jack
(1) TLC272CP op amp IC



UPDATE: Sorry, the schematic diagram above is wrong.  There should be a third 10K resistor, R5, which connects between pin 2 (- input of opamp) and GND.  The gain of the amp is R4 / R5.

You can substitute any suitable op amp. I used the TLC272CP because that happens to be what I had on hand, and it has the particularly nice characteristic that it doesn't mind running on a single-ended power supply of only 5V, so I could just hook it up to the Arduino's power.  The circuit above mixes the left and right audio channels, and has a gain of 10.  Just hook it up to your stereo audio source, and connect the output to analog pin 0, as before.  The 5V and GND also connect to your Arduino.

If you prefer to use a microphone rather than direct wiring, pepehdes has posted an alternate circuit using an electret mic in Step 1's comments, which he says works well.  Note that it is an all-pass design so it will trigger on all frequencies, not just bass.  I didn't use a microphone, because my design tracks the bass which might not be picked up very well via small speakers and a microphone.
 
Sketch Revisions

Next, we need to modify the sketch to read the audio input, and trigger the next animation frame when a threshold is exceeded.  The new sketch, daftPunkSyncV2.zip, is attached below.  You can switch the sketch between music sync and free-running by modifying
 

   // musicSync =1= sync to music
   //                      =0= use timer
   int musicSync = 1;

 

You will need to manually tune the threshold variable:

   // trigger next frame when music amplitude > threshold
   // increase threshold to decrease sensitivity
   // decrease threshold to increase sensitivity
   int threshold = 5;

The next frame will be triggered when the input read from analog pin 0 exceeds threshold.  If you're running the sketch on a real arduino that has an LED on digital pin 13, it is helpful to uncomment the following line:

   #define BLINKY // blink LED on pin 13

by removing the leading // characters.  This will cause the LED to blink when threshold is exceeded.  I have it turned off in the sketch by default, because I'm using my tiny breadboard instead of an Arduino now, and it doesn't have an LED.  Finally, you may want to experiment a bit with minBeatInterval:

  // debouncing - filter out consecutive triggers that are too close
  // together to slow down the animation. decrease this value
  // to make it more sensitive to shorter beat intervals
  int minBeatInterval = 1000;

Note that this variable is unit-less.  It simply defines how many consecutive loops after the input exceeds our threshold before the sketch is allowed to trigger the next frame.  I found that in many songs, bass beats are actually composed of several very closely spaced peaks.  If we don't filter them out, then the display will advance several frames for each beat.  You might actually like this effect, because it makes the display more lively.  Play around with it, and see what setting you prefer.
 

Step 8: Costing Down

Picture of Costing Down
usbtinyisp.jpg
mini board.jpg
usbcharger.JPG
While using an Arduino is convenient for development/prototyping, it's not a very cost effective way to go once your project is done.  Also, the board is rather bulky.  After initial development, I swapped out the Arduino Duemilanove for a tiny ATmega pcb kit from allgaiershops for $2.99, and a bare ATmega328P from Sparkfun for $4.30.   This board is fully Arduino compatible if you have a USB->Serial converter cable or a hardware AVR programmer.  I have a clone of Adafruit's USBtinyISP.

To program this board using the Arduino IDE, plug your programmer into the ICSP header.  The USBtinyISP supplies 5V power, so not other connection is needed to program and test it.  You will need to make some minor tweaks to your Arduino IDE in order to make it play nicely with the USBtinyISP.  I have posted detailed instructions on my blog:  How to Use the Arduino IDE with an External Programmer.

The next complication is that you need to figure out which pins on your ATmega328P MCU map to the digital pins on the Arduino.  The pin mappings can be found on the Arduino website:  ATmega8-Arduino Pin Mapping
Someone also made a PDF which you can use to print labels to attach directly to your ATmega328P here: Arduino Breadboard Labels .  Here is the specific pin mapping we need for our project:

Arduino Digital Pin  -> ATmega328P pin:
digital pin 12 -> ATmega pin 18
digital pin 11 -> ATmega pin 17
digital pin 10 -> ATmega pin 16
digital pin 9 -> ATmega pin 15
digital pin 8 -> ATmega pin 14
digital pin 7 -> ATmega pin 13
digital pin 6 -> ATmega pin 12
digital pin 5 -> ATmega pin 11
digital pin 4 -> ATmega pin 6
digital pin 3 ->ATmega pin 5
analog pin 0->ATmega pin 23

So take the pin that was connected to digital pin 12 on the Arduino, and connect it to pin 18 on the breadboard, and so on.

A cheap way to power the project once you're done building it is to buy a cheap USB wall wart, such as is used to charge various devices.  You can get them on eBay, or if you're lucky, your local 99 cent store may carry them. Just cut off the USB connector, and solder the power wires to VCC (pin 7) and GND (pin 8) on the ATmega (MAKE SURE TO CHECK THE POLARITY WITH A METER FIRST.  VCC is the positive lead, GND is the negative one). If you solder a USB power supply to your board, make sure to remove the PWR jumper from your USBtinyISP, or unplug your charger from the wall before programming it.



1-40 of 155Next »
syedtanzeem4 months ago

guys i'm getting this.. any idea how to fix this ?

In file included from daftpunk.ino:1:0:

C:\Users\Tanzeem\Documents\Arduino\libraries\TimerOne/TimerOne.h:19:7: error: previous definition of 'class TimerOne'

class TimerOne

^

Error compiling.

alahamm5 months ago

Thanks for this,lincomatic. Ive read and understand almost everthing but as Im still new to Arduino, I cant figure out how to run this onArduino IDE.

I dont see any .pde .ino files. Can somebody HELP, please.

awagenhurst7 months ago
I already changed them in the code. Your cols looks like this
int cols[DIM] = {12,11,10,9,8};
Mine is:
int cols[DIM] = {13,12,11,10,9};

Your rows
int rows[DIM] = {7,6,5,4,3};
Mine
int rows[DIM] = {8,7,6,4,3};

I got your other message about replacing the "// direct port manipulation" I apologize I don't really know what that means.
lincomatic (author)  awagenhurst7 months ago
Look at the code in the article. There is a section:

// direct port manipulation.
// PORTB is a pseudo variable for digital pins 8 to 13 The two high bits (6 & 7) map to the crystal pins and are not usable
// the bottom 5 bits are our columns. We don't want to change the other bits,
// so we first mask the bits we ignore, and then set the bits we want to light
PORTB &= B11100000;
PORTB |= curFrame[row] & bitMask;

replace the two PORTB lines with

digitalWrite(cols[0],HIGH);
digitalWrite(rows[0],LOW);

The code will run slower, though. My code was optimized for the pins that I used. There's no way to optimize for random pins.
awagenhurst7 months ago

I made the 5x5 led matrix but I'm having a hard time with the code. Instead of your pins I used the ones that was the easiest to get to for the atmega328 for and anodes I used pins 13,12,11,10,9 and for the cathodes I used 3,4,6,7,8. I changed them in the code but nothing comes out of pin 13 but when I do the test it works fine. I create a design I like put it seems it shifts to the right What do I need to do to the code so it all works.

lincomatic (author)  awagenhurst7 months ago
Change the numbers in the rows[] and cols[] arrays
lincomatic (author)  lincomatic7 months ago
also, as I explained in the instructable, you need to replace

// direct port manipulation.
// PORTB is a pseudo variable for digital pins 8 to 13 The two high bits (6 & 7) map to the crystal pins and are not usable
// the bottom 5 bits are our columns. We don't want to change the other bits,
// so we first mask the bits we ignore, and then set the bits we want to light
PORTB &= B11100000;
PORTB |= curFrame[row] & bitMask;

with

digitalWrite(cols[0],HIGH);
digitalWrite(rows[0],LOW);
erero79 months ago
jmaxado1 year ago
Hello
I plan to do this project using 3w leds, so I know I need to place some transistores in the circuit. But using transistores for all pins I need to change the code right.
In you case to turn a certain led on you would put one port high and another low, but using transistors I need to put both ports on.
I am thinking correctly ?
If yes where do I change the code in order to be able to use transistors ?
Thanks

José

http://www.instructables.com/id/Yet-Another-Daft-P...

The daft punk is a great instrucatble. I saw you had the same question as mine. Were you able to solve it. If yes, I am curious to know how you did it.

I have been planning to do the same thing with 3W LED's. How shall I go about it. I do know that I would perhaps need transistors for them.

What I do not know as of now is how would the circuit look like once I have made the required changes. The transistors would only be placed where you have the current limiting resistors placed ?

I am having a feeling I need 5 circuits similar to diagram #5 in http://www.instructables.com/id/Circuits-for-using...

Do you think the same ? I just want to be sure I do not burn my UNO in the process

Thanks in advance

lincomatic (author)  jmaxado1 year ago
It's been a while since I wrote this code, but I think all you have to do is change the line at the top of display() from
digitalWrite(rows[row], HIGH); // Turn whole previous row off
to
digitalWrite(rows[row], LOW); // Turn whole previous row off

and the bottom line from
digitalWrite(rows[row], LOW); // Turn whole row on at once (for equal lighting times)
to
digitalWrite(rows[row], HIGH); // Turn whole row on at once (for equal lighting times)

Also, you don't need to light only 2 LED's at a time like I did, since you'll be able to handle the current of a whole row at a time. So your display() function should look like this:

// Interrupt routine
// each time display() is called, it turns off the previous row
// and turns on the next row
byte bitMask = B00011111;
void display() {
digitalWrite(rows[row], LOW); // Turn whole previous row off

// increment row and wrap if necessary
if (++row == DIM) {
row = 0;
}

// direct port manipulation.
// PORTB is a pseudo variable for digital pins 8 to 13 The two high bits (6 & 7) map to the crystal pins and are not usable
// the bottom 5 bits are our columns. We don't want to change the other bits,
// so we first mask the bits we ignore, and then set the bits we want to light
PORTB &= B11100000;
PORTB |= curFrame[row] & bitMask;

digitalWrite(rows[row], HIGH); // Turn whole row on at once (for equal lighting times)
}

Thanks for your reply.
regarding the transistor do you have any sugestion ?
Yesterday I got some BUZ12 but I dont think it will do the trick.

José
lincomatic (author)  jmaxado1 year ago
I think it will work OK w/ your BUZ12. It handles 12A and you only need to sink about 5A per row.
I need the buz12 to control both the cathods and anoths.
I did some testing and it seams to work with only one of them.
Only when I put the negativ trough the buz12 works, if I change it it stays always on.
What the hell am I doing wrong ?

José

This is a great instructable. I am done with the sort of LEDs you have described and looks just awesome.

I have been planning to do the same thing with 3W LED's. How shall I go about it. I do know that I would perhaps need transistors for them.

What I do not know as of now is how would the circuit look like once I have made the required changes. The transistors would only be placed where you have the current limiting resistors placed ?

It would be great if you could give me the right pointers on the same. I could also see that some of the other guys also had the same query as well.

Thanks in advance

ABCreates1 year ago

Hey, I have been following your instructions, i've got the matrix to work, and all the frames play out without music sync. However when I try to use the music sync with adafruits eletrect mic all i get is the LEDs (Col 0, Row 0) and (Col 4, Row 4) constantly on. Any idea why this is happening? *Disclaimer* Newby Alert**

typomaniac3 years ago
Hey : )

i built your table with some large blue leds but they did not make bright enough light so i went for straw hat leds which seemed to be fine. For testing purposes i put one of them on a cr2032 battery with 3 V and it worked fine. I replaced one of the leds in my arduino driven matrix with one of the new red leds and was disappointed: It seems that it does only glow with much less intensity than it did before on the battery. Did i do something wrong or does the matrix work this way and there is not enough power for the maximum brightness of the leds?

thank you so much,
tm
p.S: I currently use a 91 Ohm resistor which should be even lower than the one it would need for the red ones
lincomatic (author)  typomaniac3 years ago
In order to keep the current within the alllowed levels on the Arduino, the current is limited. If you want to drive your LED's with more current, you will have to either use transistors, or add a driver IC
thank you for your answer! Oh thats bad. I have no idea how to do this. Do you know an instructable or other tutorial for a 5x5 arduino matrix like yours withh drivers or transistors? maybe i can upgrade my matrix..

thank you very much
tm
Did you ever figured out how to do this project with transistors ?
jmaxado1 year ago
Hello
I plan to do this project using 3w leds, so I know I need to place some transistores in the circuit. But using transistores for all pins I need to change the code right.
In you case to turn a certain led on you would put one port high and another low, but using transistors I need to put both ports on.
I am thinking correctly ?
If yes where do I change the code in order to be able to use transistors ?
Thanks

José
evilman2101 year ago
Hey is the TRS jack here male or female? It looks like like a female trs jack in the photo you posted but you linked male phone audio connectors in the comment below this.
lincomatic (author)  evilman2101 year ago
female
mehring2 years ago
Hey There,
I have built a 5x5 matrix and it seems to be working great in test mode. The LEDs are bright and fill the 2" squares they are in. However, when I leave test mode and go into the animation frames the brightness of the LEDs greatly diminishes. Is this due to the current limitation on the Arduino or is there something else going on within the code that does this? Any help or insight anyone could provide would be much appreciated.
Thanks.
inna255432 years ago
is the trs jack an auxillary wire? can you post a picture of it? (i would really appreciate it if you replied to this ASAP because we are doing this for school)
lincomatic (author)  inna255432 years ago
have you heard of google?
http://en.wikipedia.org/wiki/Phone_connector_(audio)
dtaylorl2 years ago
Great Instructable. I've wired it up and it is working great in test mode. As soon as I turn off test mode however, none of my LEDs will light up. I have installed TimerOne in the correct location, and the compiler does not indicate any errors, so I don't think the issue lies there. Any other ideas where I should be looking for the issue?
lincomatic (author)  dtaylorl2 years ago
It sounds like the timer isn't working. Are you using one of the newer Arduinos like the Leonardo? If so, I'm not sure if Timer1 will work.
I'm using an Uno. A problem with Timer1 makes sense since test mode works. I'm not getting any code errors though, which I get if I remove the library. Would the IDE version matter at all? I'm using 1.0.
I did a little more digging and discovered that Timer1 only works with certain pins. I had been using 3-7 for anodes and 8-12 for cathodes. Reversing this fixed the issue. Working great now, thanks again!
leandro_gs2 years ago
I really don't understand what this piece of code does. I'm trying to make a 3x3 matrix but the first column is on all the time.

if (bitMask == B00010000) {
    bitMask = B00000011; // light the right 2 columns (pins 9,8)
    // increment row and wrap if necessary
    if (++row == DIM) {
      row = 0;
    }
  }
  else if (bitMask == B00000011) {
    bitMask = B00001100; // light the middle 2 columns (pins 11,10)
  }
  else { // bitMaskIdx == B00001100
    bitMask = B00010000; // light the leftmost column (pin 12)
  }

what do i have to do to fade the leds instead blink them?
lincomatic (author)  leandro_gs2 years ago
the bits that are set to one are the columns that will light. since this is 5x5 the 5th bit is the leftmost column.
If you need to figure out what's going on w/ a column staying on all the time, try TESTMODE... it will light up the LED's in sequence. You might have a wiring error.

You have to use PWM to fade them. I don't have time to write the code for you
skeplin2 years ago
First off - thanks for the awesome Instructable! I've managed to build the display and get it running.

I'm working on a version that uses random numbers instead of pre-defined values in frames.h. However, I'm running into a snag and perhaps you can help me to figure out why.

Whenever I call random(), the display freaks out and flickers. Everything works find when that statement is REM'd. Is this a problem with the random number generator used in conjunction with the interrupt library?

Thanks!
lincomatic (author)  skeplin2 years ago
I don't know. You shouldn't call random() from withing the ISR. Maybe it's taking too long. Try to find a simple random number generator that doesn't use floats. You don't need anything fancy to just pick random frames.
Thanks for the tip! I've found an example that uses an analogRead on a pin with nothing attached to get a 0 or 1. Seems to work Ok. I've also found that I can call random() from inside the main loop() but when I call it from a function, it's too slow.
I'm building this as a table for an engineering project. I put all three files (frames, daftpunk, and timerone) into my sketchbook but when I try to upload it to my board it says "Timer1 was not declared in this scope." Help?
lincomatic (author)  TylerLjungberg2 years ago
it goes into sketchbook\libraries\TimerOne, not sketchbook\TimerOne
I asked my professor and he said the same, thanks! Also, if I want to make my LEDs brighter, how bad of an idea is it to add another 120ohm resistor to each existing resistor in parallel to only have 60ohms of resistance? How much chance am I taking as far as burning my LEDs out?
lincomatic (author)  TylerLjungberg2 years ago
You really need to figure out how much current your LEDs are rated for, and set the resistance accordingly. The main problem with brightness is the limitation on how much current the Arduino can dissipate without getting burned out, since for simplicity, the LED's are being driven directly by the Arduino. If you change the circuit to use transistors to drive the LED's instead, you can put more current through. And then you can change my sketch to drive a whole row at a time, which will increase the duty cycle so the LED's will be brighter.
DrHossa3 years ago
hi there,
i want to built the 5x5-matrix too, but first i wanted to try the animationbuilder, unfortunately the link doesn't work. can anyone tell me, if i can download it elsewehere. would be really nice to have it. thanks in advance!

and great tutorial!!! after this i'll maybe try the lampduino ;).

1-40 of 155Next »