In: Electrical Engineering
Project Description:
Utilizing the 8x8 dot matrix display the smile face and then rotate the face 90 degrees at a time until the face is back to the original position. The face can be rotated clockwise or counter clockwise. Place a 1 second delay for each 90 degree rotation.
Provide pictures of the smile in each position
Provide the following:
Code listing.
Electronic Parts used:
8x8 dot matrix
Resistors (recommended but optional)
Electronic pictures of your setup.
Schematic of circuit.
d. Hand in project both electronically and hard copy.
Step 1: Things Required
for this project you will require -:
1. 1 LED matrix
2. 8 resistors 1k ohm
3. 8 557 transistors
4. 1 ULN2803 IC
5 Arduino
6. 2 74HC595 shift register
7. 2 Bread board
8. Connecting Wires
Step 2: Working
Dot matrix units typically come in either a 5x7 or 8x8 matrix of LEDs. The LEDs are wired in the
matrix such that either the anode or cathode of each LED is common in each row. In other words, in a
common anode LED dot matrix unit, each row of LEDs would have all of their anodes in that row wired
together. The cathodes of the LEDs would all be wired together in each column. The reason for this will
become apparent soon.
A typical single color 8x8 dot matrix unit will have 16 pins, 8 for each row and 8 for each column.
The reason the rows and columns are all wired together is to minimize the number of pins required.
If this were not the case, a single color 8x8 dot matrix unit would need 65 pins, one for each LED and a
common anode or cathode connector. By wiring the rows and columns together, only 16 pins are
required.
However, this now poses a problem if you want a particular LED to light in a certain position. If, for
example, you had a common anode unit and wanted to light the LED at X, Y position 5, 3 (5th column,
3rd row), then you would apply a current to the 3rd Row and ground the 5th column pin.
The LED in the 5th column and 3rd row would now light.
Now let’s imagine that you want to also light the LED at column 3, row 6. So you apply a current to
the 6th row and ground the 3rd column pin. The LED at column 3, row 6 now illuminates. But wait…the
LEDs at column 3, row 6 and column 5, row 6 have also lit up.
This is because you are applying power to row 3 and 6 and grounding columns 3 and 5. You can’t
turn off the unwanted LEDs without turning off the ones you want on. It would appear that there is no
way you can light just the two required LEDs with the rows and columns wired together as they are. The
only way this would work would be to have a separate pinout for each LED, meaning the number of pins
would jump from 16 to 65. A 65-pin dot matrix unit would be very hard to wire up and control because
you’d need a microcontroller with at least 64 digital outputs.
Is there a way to get around this problem? Yes there is, and it is called multiplexing (or muxing).
Multiplexing is the technique of switching one row of the display on at a time. By selecting the column
that contains the row that contains the LED that you want to be lit, and then turning the power to that
row on (or the other way round for common cathode displays), the chosen LEDs in that row will
illuminate. That row is then turned off and the next row is turned on, again with the appropriate
columns chosen and the LEDs in the second row will now illuminate. Repeat with each row till you get to
the bottom and then start again at the top.
If this is done fast enough (at more than 100Hz, or 100 times per second) then the phenomenon of
persistence of vision (where an afterimage remains on the retina for approx 1/25th of a second) will mean
that the display will appear to be steady, even though each row is turned on and off in sequence.
By using this technique, you get around the problem of displaying individual LEDs without the
other LEDs in the same column or row also being lit.
By scanning down the rows and illuminating the respective LEDs in each column of that row and
doing this very fast (more than 100Hz) the human eye will perceive the image as steady and the image of
the heart will be recognizable in the LED pattern.
You are using this multiplexing technique in the Project's code. That’s how you’re to display the
heart animation without also displaying extraneous LEDs.
Step 3:
you have to calculate the value of the resistors you can use
You should first get some specs on your LEDs, you should know their forward voltage and forward current, you can get this info from the datasheet. The circuit operates on 5V so your Source voltage is 5V which can be obtained from a 5v adapter
#define ROW_1 2
#define ROW_2 3
#define ROW_3 4
#define ROW_4 5
#define ROW_5 6
#define ROW_6 7
#define ROW_7 8
#define ROW_8 9
#define COL_1 10
#define COL_2 11
#define COL_3 12
#define COL_4 13
#define COL_5 A0
#define COL_6 A1
#define COL_7 A2
#define COL_8 A3
const byte rows[] = {
ROW_1, ROW_2, ROW_3, ROW_4, ROW_5, ROW_6, ROW_7, ROW_8
};
// The display buffer
// It's prefilled with a smiling face (1 = ON, 0 = OFF)
byte TODOS[] = {B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111};
byte EX[] = {B00000000,B00010000,B00010000,B00010000,B00010000,B00000000,B00010000,B00000000};
byte A[] = {B00000000,B00011000,B00100100,B00100100,B00111100,B00100100,B00100100,B00000000};
byte B[] = {B01111000,B01001000,B01001000,B01110000,B01001000,B01000100,B01000100,B01111100};
byte C[] = {B00000000,B00011110,B00100000,B01000000,B01000000,B01000000,B00100000,B00011110};
byte D[] = {B00000000,B00111000,B00100100,B00100010,B00100010,B00100100,B00111000,B00000000};
byte E[] = {B00000000,B00111100,B00100000,B00111000,B00100000,B00100000,B00111100,B00000000};
byte F[] = {B00000000,B00111100,B00100000,B00111000,B00100000,B00100000,B00100000,B00000000};
byte G[] = {B00000000,B00111110,B00100000,B00100000,B00101110,B00100010,B00111110,B00000000};
byte H[] = {B00000000,B00100100,B00100100,B00111100,B00100100,B00100100,B00100100,B00000000};
byte I[] = {B00000000,B00111000,B00010000,B00010000,B00010000,B00010000,B00111000,B00000000};
byte J[] = {B00000000,B00011100,B00001000,B00001000,B00001000,B00101000,B00111000,B00000000};
byte K[] = {B00000000,B00100100,B00101000,B00110000,B00101000,B00100100,B00100100,B00000000};
byte L[] = {B00000000,B00100000,B00100000,B00100000,B00100000,B00100000,B00111100,B00000000};
byte M[] = {B00000000,B00000000,B01000100,B10101010,B10010010,B10000010,B10000010,B00000000};
byte N[] = {B00000000,B00100010,B00110010,B00101010,B00100110,B00100010,B00000000,B00000000};
byte O[] = {B00000000,B00111100,B01000010,B01000010,B01000010,B01000010,B00111100,B00000000};
byte P[] = {B00000000,B00111000,B00100100,B00100100,B00111000,B00100000,B00100000,B00000000};
byte Q[] = {B00000000,B00111100,B01000010,B01000010,B01000010,B01000110,B00111110,B00000001};
byte R[] = {B00000000,B00111000,B00100100,B00100100,B00111000,B00100100,B00100100,B00000000};
byte S[] = {B00000000,B00111100,B00100000,B00111100,B00000100,B00000100,B00111100,B00000000};
byte T[] = {B00000000,B01111100,B00010000,B00010000,B00010000,B00010000,B00010000,B00000000};
byte U[] = {B00000000,B01000010,B01000010,B01000010,B01000010,B00100100,B00011000,B00000000};
byte V[] = {B00000000,B00100010,B00100010,B00100010,B00010100,B00010100,B00001000,B00000000};
byte W[] = {B00000000,B10000010,B10010010,B01010100,B01010100,B00101000,B00000000,B00000000};
byte X[] = {B00000000,B01000010,B00100100,B00011000,B00011000,B00100100,B01000010,B00000000};
byte Y[] = {B00000000,B01000100,B00101000,B00010000,B00010000,B00010000,B00010000,B00000000};
byte Z[] = {B00000000,B00111100,B00000100,B00001000,B00010000,B00100000,B00111100,B00000000};
float timeCount = 0;
void setup() {
// Open serial port
Serial.begin(9600);
// Set all used pins to OUTPUT
// This is very important! If the pins are set to input
// the display will be very dim.
for (byte i = 2; i <= 13; i++)
pinMode(i, OUTPUT);
pinMode(A0, OUTPUT);
pinMode(A1, OUTPUT);
pinMode(A2, OUTPUT);
pinMode(A3, OUTPUT);
}
void loop() {
// This could be rewritten to not use a delay, which would make it appear brighter
delay(5);
timeCount += 1;
if(timeCount < 70) {
drawScreen(A);
} else if (timeCount < 1) {
// do nothing
} else if (timeCount < 150) {
drawScreen(R);
} else if (timeCount < 1) {
// nothing
} else if (timeCount < 270) {
drawScreen(D);
} else if (timeCount < 1) {
// nothing
} else if (timeCount < 350) {
drawScreen(U);
} else if (timeCount < 1) {
// nothing
} else if (timeCount < 430) {
drawScreen(I);
} else if (timeCount < 1) {
// nothing
} else if (timeCount < 510) {
drawScreen(N);
} else if (timeCount < 1) {
} else if (timeCount < 550) {
drawScreen(O);
} else if (timeCount < 1) {
// do nothing
} else if (timeCount < 590) {
drawScreen(EX);
} else if (timeCount < 1) {
// nothing
} else if (timeCount < 630) {
drawScreen(EX);
} else if (timeCount < 1) {
//} else if (timeCount < 670) {
//drawScreen(A);
//} else if (timeCount < 1) {
//} else if (timeCount < 710) {
//drawScreen(R);
//} else if (timeCount < 1) {
//} else if (timeCount < 750) {
//drawScreen(D);
//} else if (timeCount < 1) {
//} else if (timeCount < 790) {
//drawScreen(U);
//} else if (timeCount < 1) {
//} else if (timeCount < 830) {
//drawScreen(I);
//} else if (timeCount < 1) {
//} else if (timeCount < 870) {
//} else if (timeCount < 1) {
//} else if (timeCount < 910) {
// drawScreen(O);
//} else if (timeCount < 1) {
} else {
// back to the start
timeCount = 0;
}
}
void drawScreen(byte buffer2[]){
// Turn on each row in series
for (byte i = 0; i < 8; i++) {
setColumns(buffer2[i]); // Set columns for this specific row
digitalWrite(rows[i], HIGH);
delay(2); // Set this to 50 or 100 if you want to see the multiplexing effect!
digitalWrite(rows[i], LOW);
}
}
void setColumns(byte b) {
digitalWrite(COL_1, (~b >> 0) & 0x01); // Get the 1st bit: 10000000
digitalWrite(COL_2, (~b >> 1) & 0x01); // Get the 2nd bit: 01000000
digitalWrite(COL_3, (~b >> 2) & 0x01); // Get the 3rd bit: 00100000
digitalWrite(COL_4, (~b >> 3) & 0x01); // Get the 4th bit: 00010000
digitalWrite(COL_5, (~b >> 4) & 0x01); // Get the 5th bit: 00001000
digitalWrite(COL_6, (~b >> 5) & 0x01); // Get the 6th bit: 00000100
digitalWrite(COL_7, (~b >> 6) & 0x01); // Get the 7th bit: 00000010
digitalWrite(COL_8, (~b >> 7) & 0x01); // Get the 8th bit: 00000001
// If the polarity of your matrix is the opposite of mine
// remove all the '~' above.
}