8*8 Led Matrix
Project Purpose
This project originated from a reddit post I saw on r/electricalengineering. The reddit user was building their own led matrix and had questions about the best transistors to use. I had nothing going on at the time, and not knowing how long it would take me, I thought: "I can do that." I had no real plans for it at the time. I just wanted to try to make it. As the project has progressed I have decided that I want to use it as a bed-side clock, but it was almost more fun not knowing where I was going with it in the beginning.
Design Process
It started off with a rough schematic drawn on my iPad. I had no idea what multiplexing or common cathode or shift register meant. I thought I would be able to just display the 8*8 image I wanted with one command.
I read a few guides online and realized that this was not going to be an easy project. I decided to have all the anodes connected in rows and the anodes connected in columns. This would allow me to light any individual led I wanted by connecting the corresponding row and column to 5v and gnd respectively.
The issue I soon ran into was lighting multiple leds at once. I was still under the impression that I would be able to light each individual led at the same time to display my final image, but as the first picture in the carousel below shows, I would have an issue with lighting leds in different rows and columns concurrently. Due to the nature of connected rows and columns, powering on row enables any led in that row to turn on when its column is grounded. If I wanted to light two leads diagonally from each other, I would end up lighting a square.
I talked with people in the Georgia Tech EE discord server and learned about multiplexing. Multiplexing is the process by which a display is updated row by row very fast to give the impression of all rows being on at once. The solution to my problem was lighting each row for a fraction of a second with a refresh rate of above 30 Hz to trick the human eye into thinking every row is always on. This is how all LCD displays work. Once I realized this I could get to designing actual logic.
I decided to choose my active row with a decoder/demux. To choose which leds in that row were going to be lit, I used an 8 bit serial in parallel out shift register to control the columns as shown in pictures 2 and 3 of the carousel above. resistor values were calculated to balance brightness and lifespan of the leds. The red leds I chose had a forward voltage of ~1.8v and a rated max current of 20 mA. I chose to run them all at around 12 mA because that provided a longer lifespan than running them at 100% brightness. Each row was connected in parallel so when a row was powered and leds turned on, there would be a constant 1.8 v draw and 12*n mA for n leds that would be lit up in the row.
Assembling Hardware
I bought a set of protoboards and resistors and went to a lab in Van Leer to grab the ICs and transistors I didn't already have and I went to work. I really enjoy soldering so that part went by easy. I used my myDaq from ECE 2020 to test the matrix and everything worked. I initially planned on having the less themselves powered off a usb-C port on the protoboard, and the IC be powered from the arduino's 5v rail. I encountered a problem with that because the usb-c female ports I had on hand were Power Delivery spec meaning that they could pull more than 5v. In my case they were pulling 8.7v. The transistors I am using are called BJT's and they are current controlled instead of voltage controlled like mosfets. When the less were allowed to pull 8+ volts instead of being locked at 5 volts, the transistors were all opening causing a ton of problems. I was unable to have one row on at a time. Every row and every column would open, because all the transistors were acting as closed circuits. I eventually realized that with such a small power draw from the less, I could run them off of the arduino's 5v rail as well which was locked at 5v. The power supply switch fixed my transistor issues and all I had to do then was code.
Current State
I currently have a working display and logic board. I am able to display any single 8*8 bit map or a set of bit maps to create a gif effect. I have an example coded of scrolling text that consists of 8 frames that last 100ms each. what I failed to account for was the arduino nano's lack of wifi connectivity. In order to have a clock, you would typically want to call a website like timeanddate.gov to pull the up to date and accurate time. With the Nano I am going to have to set an initial time and rely on the nano's internal clocks to keep up. After a bit of research, I have found that this is hardly accurate and can be off by seconds per day which over the course of a week or a month would add up.
My arduino code is messy, but achieves the basic functionality I need it to.
for(int i = 7; i>=0;i--) { //writing to shift per row
if(currScreen[j][i] == 1) {
digitalWrite(dataPin, HIGH);
}
else {
digitalWrite(dataPin, LOW);
}
digitalWrite(clockPin, HIGH);
digitalWrite(clockPin, LOW);
}
The core of the logic is this. I loop 8 times, once per column. for each column, I check the bitmap to see if I need to light the led or keep it off. If I need to light the led, I change my data line to a 1, and I send a rising edge to the shift register. In essence that is all my code does. It load 8 bits into the shift register, powers the row for 16/30 of a millisecond. Then does the same thing for the next row. This all happens so fast that you perceive the rows as all being on.