Introduction: Arduino - Dot Matrix Screen Writing LED

About: design hacker

1. Objectives

Achieve a pen writing on dot-matrix screen.

2. Circuit analysis
Dot matrix screen handwriting consists of three main parts: the row scanning circuit, column scanning circuit shown, light pen detection circuit, block diagram below. Light pen used herein installed inside a light-sensitive sensor for detecting the state of the lattice points. As follows:

(1) Line scan In turn enable decoder Y0, Y1 ...... effective, while effective 74ls138 output is low, but we are using is common anode dot matrix screen, so it needs to be negated, the design uses PNP transistor negated. Every eight column scanning once scanning.

(2) Column scanning In turn enable decoder Y0, Y1 ...... effective, and the input PWM signal on OE1, when OE1 is high Y0 ~ Y7 are all high level, when OE1 is low, the output of the decoder ABC decided by the three pins. Elected in a row we checked in turn Y0, Y1 ......, and brightness of each LED lamp by OE1 regulation.

(3) Light pen The comparator inverting input of the reference voltage setting and light pen light received when the inverting input terminal of the input voltage is less than this value, when the light pen does not receive the light when the inverting input terminal of the input voltage is greater than this value when a certain value. When the light pen does not receive the light through the R3 current is very small, so the input to the comparator inverting input voltage close to the supply voltage, then the comparator output is high, when the light pen light received through the current will increase of R3 large, the voltage across R3 will increase, so the input to the comparator inverting input voltage is reduced, then the comparator output is low, then the microcontroller can capture this change and then make the appropriate treatment.

3. Program analysis

To detect the lattice point on we must illuminate the LED on the lattice, and it is in the micro-light state, when the stroke hit a point of light, put this point to highlight. So how do we know the coordinates of this point to light it? The principle is this: the LED is lit one by one, first the first line of the first, then the first line of the second, ......, first row to the last one and then go to the second line of the first, the cycle LED sequentially lit, and each LED set a status value, such as the value of zero indicates a micro-light, 1 representative highlighted. When the light hit the stroke of a point if it is not the turn of this LED is lit, the light does not detect the light pen light pen so the output is held high, the LED lights turn to when lit because the light emitted from the LED pen detected light, the output light pen from high to low, when the device detects this level change on entering the interrupt sequence, and get the current row, column values, and through the rows, columns, modify the value at this point the status value is 1, so that the next time it was when this little bit of light on this by judging the status value is set to highlight shape. state. When the scanning speed we saw the whole dot-matrix screen is lit up, and instead of one by one lit.

Reference procedure is as follows:

#define COL 1

#define ROW 2

int col = 0; //Mark the current Scanned row

int row = 0; //Mark the current Scanned column

int ledState[8][8]; //Mark the current LED status

/* haveUpdate used to eliminate Light pen jitter, when the acquired light pen signal falling edge when the data is updated, * and this flag is set to 1 indicates that the data has been updated, and then open the timer at the next climate jitter * Since the data has been updated to the neglect of jitter, when the regular time to time to re-set this flag is 0*/

int haveUpdate =0;

void setup()


memset(ledState, 0, sizeof(ledState)); //All status values are cleared.

initPort(); //Port initialization

TCCR2A = _BV(COM2A0) | _BV(COM2B1) | _BV(WGM21) | _BV(WGM20);

TCCR2B = _BV(WGM22) | _BV(CS20); //Undivided

OCR2A = 100;

OCR2B = 99; //Duty cycle of 99%

attachInterrupt(0, externInterrupt, FALLING );//Set the external interrupt falling edge interrupt

cli(); //Close all interrupts

TCCR1A=0; //Register A configured PWM , we'll just use the timer function

TCCR1B=(1< TCNT1=0xFE79; //Counter initial value, 25ms timer

TIMSK1 = 0; //Close Overflow

sei(); //Open global interrupt

} ISR(TIMER1_OVF_vect){ //Timer interrupt service routine

TIMSK1 = 0; //Close enable overflow interrupt

haveUpdate = 0; //Reset flag


void loop()


scan(); //Cyclic scan


void externInterrupt() //External interrupt service routine


if(haveUpdate == 0)


ledState[row][col] = 1; //According to the state of row and column labels that are currently detected point

haveUpdate = 1;

TCNT1=0xFE79; //Counter initial value, 25ms timer

TIMSK1 =(1< 0)

OCR2B = 1;


OCR2B = 98;


OCR2B = 98;




Boards from PCBWay, and more about electronics at