Hello,
I would greatly appreciate some advice on a Bi-Color LED Matrix project I put together where there is some ghosting.
The project consists of the following:
- Common Cathode Bi-Color LED Matrix
- 4017B Decade Counter
- 8 2N7000 Transistors
The 8 Green and Red Column Pins from the LED Matrix plug directly into the Arduino.
The Decade Counter outputs pins Q1 to Q8 through a 2N7000 transistor (one for each output) to the Bi-Color LED Matrix.
Now, my understanding of how a Common Cathode LED Matrix works is that setting a column to LOW disables the column. Setting a row to HIGH disables the row.
What you then do is that you start at row 1 then you repeat the following.
START REPEAT
You apply a pattern to the green columns. A column set to HIGH causes the green LED to light up.
You apply a pattern to the red columns. A column set to HIGH causes the red LED to light up.
You set the current row to LOW to enable the row.
After a delay you set the current row to HIGH
You then move onto the next row
END REPEAT
Now, the decade counter does this quite effectively.
However, I read somewhere that the above process can cause ghosting and the way to avoid it is that each time you move onto a new row and set it to LOW to enable it, you don't just set the previous row back from LOW to HIGH to disable it, you set every row to HIGH and then the current row to LOW.
The ghosting that is appearing on the Bi-Color LED Matrix is that where we want an LED to be off, it instead has a faint colour where the LED immediately below it in the next row (but same column) is lit. So, with (row,column), if (2,2) is set to off and (2,3) is lit, (2,2) has a faint colouring matching (2,3) whether it be red, green or yellow.
If the fact that I am not setting all rows to HIGH each time I move onto the next row and set it to LOW to enable it is the cause of the ghosting then I'm not sure how to fix it using a decade counter and my code. I'd be wasting a lot of clock cycles with the decade counter going through all 8 rows each time I move onto the next row and preceded setting it to LOW by setting all other rows to HIGH.
I'm wondering if someone can tell me whether I can get the decade counter to work with my below code (or something similar) and remove the ghosting.
If I do need to set all rows to HIGH prior to setting each new row to LOW, I'm wondering if I should use a shift register instead of a decade counter so that I can do a ShiftOut of B11111111 to set all rows to HIGH and then do a ShiftOut with the bit representing the row I want to enable set to 0 (e.g. B11101111 to enable the fourth row).
Any advice would be greatly appreciated.
Below is the code I'm using. Incidentally, I tried playing around with the delayMicroseconds values but the only way I could get rid of the ghosting was at the cost of the display flickering noticeably.
/* Bi-Color LED Array using Decade Counter and set of eight 2N7000 Transistors */
void refresh();
void pulse(int pin);
const int clockPin = 18; /* A4 */
const int resetPin = 19; /* A5 */
const int greenPins[8] = {2, 3, 4, 5, 6, 7, 8, 9};
const int redPins[8] = {10, 11, 12, 13, 14, 15, 16, 17}; /* 14 is A0, 15 is A1, 16 is A2, 17 is A3 */
// colors off = 0, green = 1, red = 2, orange = 3
const unsigned char PROGMEM pixels1[8][8] = {
{0, 2, 0, 0, 0, 0, 1, 0},
{0, 2, 0, 0, 0, 0, 1, 0},
{0, 0, 2, 0, 0, 1, 0, 0},
{0, 0, 0, 3, 3, 0, 0, 0},
{0, 0, 0, 3, 3, 0, 0, 0},
{0, 0, 1, 0, 0, 2, 0, 0},
{0, 1, 0, 0, 0, 0, 2, 0},
{0, 1, 0, 0, 0, 0, 2, 0}
};
byte pixels[8][8];
/* -------------- */
/* Setup Function */
/* -------------- */
void setup()
{
pinMode(clockPin, OUTPUT);
pinMode(resetPin, OUTPUT);
for (int i = 0; i < 8; i++)
{
pinMode(greenPins[i], OUTPUT);
pinMode(redPins[i], OUTPUT);
}
for (int i = 0; i < 8; i++) {
for (int j = 0; j < 8; j++) {
pixels[i][j] = pgm_read_byte(&pixels1[i][j]);
}
}
}
/* ------------- */
/* Loop Function */
/* ------------- */
void loop()
{
refresh();
}
/* ---------------- */
/* Refresh Function */
/* ---------------- */
void refresh()
{
pulse(resetPin);
delayMicroseconds(2000);
for (int row = 0; row < 8; row++)
{
for (int col = 0; col < 8; col++)
{
int redPixel = pixels[row][col] & 2;
int greenPixel = pixels[row][col] & 1;
digitalWrite(greenPins[col], greenPixel);
digitalWrite(redPins[col], redPixel);
}
pulse(clockPin);
delayMicroseconds(1500);
}
}
/* -------------- */
/* Pulse Function */
/* -------------- */
void pulse(int pin)
{
delayMicroseconds(20);
digitalWrite(pin, HIGH);
delayMicroseconds(50);
digitalWrite(pin, LOW);
delayMicroseconds(50);
}