You are on page 1of 6

KS Project Manual eFY aPril 2009

Microcontroller-Based Moving-Message display

ED-based moving-message displays are becoming popular for transmitting information to large groups of people quickly. These can be used indoors or outdoors. We can find such displays in areas like railway platforms, banks, public offices, hotels, training institutes, nightclubs and shops. Compared to LEDs, liquid-crystal displays (LCDs) are easy to interface with a microcontroller for displaying information as these have many built-in functions. But these cant be observed from a distance and largesize LCDs are very costly. LED-based displays can be of two types: dot-matrix and segmental. If you implement a moving-message display with multiplexed dot-matrix LEDs, it will be very costly for displaying 16 characters or more at a time. Moreover, programming will require a lot of data memory or program memory space. An external RAM may be needed to complement a microcontroller like AT89C51. However, if you use alphanumeric (16-segment LED) displays for the above purpose, programming burden is reduced and also it becomes highly cost-effective. You can make your own display panel consisting of 16 alphanumeric characters at a much lower cost. The circuit presented here uses 16 common-anode, single-digit, alphanumeric displays to show 16 characters at a time. Moreover, programming has been done to make the characters move in a beautiful manner. A message appears on the panel from the right side, stays for a few seconds when the first character reaches the leftmost place and then goes out from the left side. It displays 16 different messages to depict different occasions, which can be selected by the user through a DIP switch.

circuit description
Fig. 1 shows the circuit of the microcontroller-based moving-message display. It comprises microcontroller AT89C51, three-to-eight decoder 74LS138, common anode alphanumeric displays, regulator 7805 and a few discrete components. At the heart of the moving-message display is Atmel AT89C51 microcontroller (IC1). It is a low-power, high-performance, 8-bit microcontroller with 4 kB of flash programmable and erasable read-only memory (PEROM) used as on-chip program memory, 128 bytes of RAM used as internal data memory, 32 individually programmable input/output (I/O) lines divided into four 8-bit ports, two 16-bit programmable timers/counters, a five-vector two-level interrupt architecture, on-chip oscillator and clock circuitry. Parts List
Semiconductors: IC1 - AT89C51 microcontroller IC2, IC3 - 74LS138 3-to-8 decoder IC4 - 7805 5V regulator T1-T16 - BC558 pnp transistor D1-D4 - 1N4007 rectifier diode DIS1-DIS16 - KLA51 common-anode alphanumeric display LED1 - 5mm LED Resistors (all -watt, 5% carbon): R1-R16 - 2.2-kilo-ohm R17-R32 - 120-ohm R33-R37 - 10-kilo-ohm R38 - 220-ohm Capacitors: C1, C2 C3 C4 C5 C6 33pF ceramic disk 2200F, 25V electrolytic 1F, 16V electrolytic 10F, 16V electrolytic 0.1F ceramic disk

Ports P0 and P2 of the microcontroller have been configured to act as a common data bus for all the 16 alphanumeric displays whose corresponding data pins have been tied together to make a common 16-bit data bus. Port-2 provides the higher byte of data, while port-0 provides the lower one to light up a character on the display. Port pins P1.2-P1.4 and P1.5-P1.7 of the microcontroller have been used as address inputs for decoder IC3 and IC4 (74LS138) to enable one of the fourteen alphanumeric displays (DIS3 through DIS16) at a time, respectively. However, displays DIS1 and DIS2 are enabled or disabled directly by port pins P1.0 and P1.1. Pins 4 and 5 are grounded and pin 6 is made high to enable decoder 74LS138. Fig. 2 shows the pin configuration of the common-anode alphanumeric display. All the corresponding data pins DIS1 through DIS16 of alphanumeric displays have been tied together,

List of Messages Which can be Selected


S3S2S1S0 0000 0001 0010 0011 0100 0101 0110 0111 1000 1001 1010 1011 1100 1101 1110 1111 Message selected Happy Birthday Happy New Year *Happy Diwali* Merry Christmas *Happy Holi* *Eid Mubarak* Happy Dashehra Happy Wedding Happy Janmashtmi *Happy Rakhi* *Happy Pongal* Happy Mothers Day *Happy Ramjan* *Happy Lohri* *Happy Easter* Welcome to All

Miscellaneous: X1 - 220V AC primary to 9V, 500mA secondary transformer XTAL - 11.0592MHz crystal S0-S3 - 4-pin DIP switch S4 - Push-to-on switch

KS Project Manual eFY aPril 2009

Fig. 1: Circuit for microcontroller-based moving-message display

KS Project Manual eFY aPril 2009

Fig. 2: Pin configuration of alphanumeric display

while the common anode of each display is separately powered via a BC558 transistor which switches on or off as required, through outputs of 74LS138 ICs and pins P1.0 and P1.1 of IC1. The higher nibble of port P3 (P3.4 through P3.7) is used as a selection bus to select one of the 16 previously stored messages using the 4-bit binary value present on these pins. This value can be changed through a 4-pin DIP switch (S0 through S3). Selection pins P3.4 through P3.7 are pulled high via resistors R36 through R33, respectively. When the switch connected to a given pin is open the value is high (1), and when it is closed the pin is held low and the value becomes 0. In this way, by using a 4-bit number you can select any of the 16 messages shown in the Table. Capacitor C5 and resistor R37 form the power-on reset circuit, while a push-to-connect switch has been used for manual reset. An 11.0592MHz crystal generates the basic clock frequency for the microcontroller. To change the message being displayed while the circuit is working, first change the number present at the selection bus, then press reset key. The 220V AC mains is stepped down by transformer X1 to deliver the secondary output of 9V, 500 mA. The output of the transformer is rectified by a full-wave bridge rectifier comprising diodes D1 through D4, filtered by capacitor C3 and then regulated by IC 7805 (IC4). Capacitor C4 bypasses any ripple present in the

Fig. 3: Actual-size, single-side PCB for the microcontroller-based moving-message display circuit, except alphanumeric display and associated components

Fig. 4: Component layout for the PCB shown in Fig. 3

regulated power supply. LED1 acts as the power-on indicator.

construction
Fig. 3 shows an actual-size, singleside PCB layout for the microcontroller-based moving-message display circuit, except displays DIS1 through DIS16, transistors T1 through T16 and resistors R17 through R32. Component layout for this PCB is shown in Fig. 4.

Fig. 5 shows the PCB for displays DIS1 through DIS8, transistors T1 through T8 and resistors R17 through R24. Component layout for this PCB is shown in Fig. 6. You need to use an additional PCB as shown in Fig. 5 for DIS9 through DIS16, so as to configure 16 alphanumeric displays. For this PCB, the corresponding components will be transistors T9 through T16 and resistors R25 through R32 in addition to displays DIS9 through DIS16. Cor-

KS Project Manual eFY aPril 2009

Fig. 5: Actual-size, single-side PCB for alphanumeric display

Fig. 6: Component layout for the PCB shown in Fig. 5

responding connector are provided to make a proper connection. Connectors CON2, CON4 and CON6 of Fig. 3 are connected to CON2, CON4 and CON6 of Fig. 5, respectively, through external wires to interface DIS1 through DIS9. Connectors CON3, CON5 and CON7 of Fig. 3 are connected to CON2, CON4 and CON6 of Fig. 5, respectively, through external cable to interface DIS9 through DIS16.

software and its working


The source code movmsg.asm is written in Assembly language and assembled using cross-compiler. It is wellcommented and easy to understand. Timer 1 has been used to generate a delay of around 1 ms for the switching gap between two consecutive displays. Thus, each display is enabled for 1 ms while displaying a message. The length of this cycle depends upon the length of the message string. The cycle repeats after a 0 is encountered at the end of

each message stored in the look-up table at the end of the program. Each time, to display a character at a given display, first two bytes (16 bits) of data are sent to Port-2 and Port-0, then the desired display is enabled by sending its address to Port-1. Thereafter, a delay of 1 ms (slightly more than that) is generated by timer 1. Upon timer overflow, the entire display panel is refreshed by passing FFFFH to the data bus. Then the next character at the next display is passed in the similar manner. The cycle frequency is variable (depending upon the length of the message) but always high enough so that the message appears continuous to the human eye. Timer 0, with its interrupt enabled, is used to change the starting address of the message in cyclic manner so that the characters scroll from left to right with a proper gap between each shift. Meanwhile, the interrupt service sub-routine also checks for the

starting address of DIS16 (right-most display). As soon as the first character reaches DIS16, the message stays for a longer time so that the entire message (message length not longer than 16 characters) can be easily read. Thereafter, characters again start scrolling rightwards, so the entire message goes out and disappears after a while to reappear from left side. All the messages are stored in the form of a look-up table in the program memory (ROM) itself. When the circuit is switched on (or reset), the monitoring program first checks for the binary number present at the selection bus and according to that, the ROM address of the starting character of the selected message is loaded into the data-pointer. Thereafter, on-chip ROM reading is used to read the entire message over there. Note that each character is represented in the look-up table of the source code by two bytes. For exam-

KS Project Manual eFY aPril 2009


ple, S is represented by Sh and Sl separated by a comma. In addition to the alphabets, Arabic numerals and a few special characters have been defined in the program. For instance, a blank space is represented by bsh, bsl. Thus, it is very easy to modify the program. Suppose you want to display HOUSE NO 401-H in place of message 0. First, open the source code in the editor. Delete the old string and write the new string as below:
msg0: db Hh, Hl, Oh, Ol, Uh, Ul, Sh, Sl, Eh, El, bsh, bsl, Nh, Nl, Oh, Ol, bsh, bsl, fourh, fourl, zeroh,

zerol, oneh, onel, msh, msl, Hh, Hl, 0

(Please note that the assembler is case-insensitive. Still, upper and lower cases have been used for clarity.)

Future enhancements
Many more messages would be possible if complete Port-3 is used for message selection. Pins RxD, TxD, INT0 and INT1 have been

kept free, so that these can be used for interfacing with the serial port of the PC. Also, interrupt pins can be used to display some message and sound an alarm in the case of an emergency. For example, a fire sensor can be connected to INT0 and a vibration detector to INT1. These pins can also be used to send signals to synchronise a similar system that displays another related message at the same time, so a 16-character, twoline display is made possible.

movmsg.asm
$mod51 DBH equ p2 Bus DBL equ p0 ; ADB equ p1 ; input equ p3 ; ; Higher byte of Data Lower byte of Data Bus Address Bus message select input Fl equ 0e8h GH equ 1bh Gl equ 0e8h Hh equ 0c3h Hl equ 0ebh Ih equ 0ffh Il equ 9fh Jh equ 17h Jl equ 0ffh Kh equ 0ech Kl equ 0ebh Lh equ 3fh Ll equ 0ebh Mh equ 0d5h Ml equ 0e3h Nh equ 0d6h Nl equ 0e3h Oh equ 17h Ol equ 0e8h Ph equ 0e3h Pl equ 0e8h Qh equ 06h Ql equ 0e8h Rh equ 0e2h Rlw equ 0e8h Sh equ 0bh Sl equ 0f8h Th equ 0ffh Tl equ 9ch Uh equ 17h Ul equ 0ebh Vh equ 0fdh Vl equ 6bh Wh equ 17h Wl equ 0abh Xh equ 0fch Xl equ 77h Yh equ 0e3h Yl equ 0bbh Zh equ 3dh Zl equ 7ch ;** codes for few special characters: strh terisk) strl plsh plsl mnsh mnsl _h _l bsh bsl pieh piel mueh muel equ 0e8h ;for star sign (asequ 17h equ 0ebh ;for + sign equ 9fh equ 0ebh ;minus sign equ 0ffh equ 3fh ;underscore sign equ 0ffh equ 0ffh ;blank space equ 0ffh equ 0eah ;for pie equ 7fh equ 0e3h ;for micro (mu) equ 0ebh

;** codes for decimal digits are given below: ; (h refers to higher byte, l to lower one) zeroh equ 17h zerol equ 0e8h oneh onel twoh twol equ 0d7h equ 0ffh equ 23h equ 0ech

threeh equ 2bh threel equ 0fch fourh fourl fiveh fivel sixh sixl equ 0c3h equ 0fbh equ 0bh equ 0f8h equ 0bh equ 0e8h

org 0000h sjmp main org 000bh ;timer0 interrupt vector address clr tr0 ;clear timer0 run bit mov tl0,#00h mov th0,#00h ;reload timer0 with initial count djnz r7,a1 mov r7,#46 cjne r1,#60h,a5 ;check to again start entering from left-side sjmp a4 a5: cjne r1,#50h,a2 ;check for display to stay on reaching display-16 sjmp a3 a2: inc r1 sjmp a1 a3: djnz r6,a1 inc r1 sjmp a1 a4: mov r6,#10 mov r1,#41h a1: setb tr0 ;set timer0 run bit reti ;return from timer0 ISR and clear tf0 main: mov ie,#00h setb ea interrupt bit setb et0 ;set global ;enable

sevenh equ 0d7h sevenl equ 0fch eighth equ 03h eightl equ 0e8h nineh ninel equ 03h equ 0f8h

;** codes for alphabets are given below: Ah equ 0c3h Al equ 0e8h Bh equ 0bh Bl equ 0ebh Ch equ 3fh Cl equ 0e8h Dh equ 03h Dl equ 0efh Eh equ 2bh El equ 0e8h Fh equ 0ebh

KS Project Manual eFY aPril 2009


timer0 interrupt mov tmod,#01h figured in mode 1 mov tcon,#00h mov tl0,#00h mov th0,#00h count to 0000H mov r7,#46 between each shift mov r6,#10 ;timer0 conchk2: cjne a,#2fh,chk3 mov dptr,#msg2 sjmp read chk3: cjne a,#3fh,chk4 mov dptr,#msg3 sjmp read chk4: cjne a,#4fh,chk5 mov dptr,#msg4 sjmp read chk5: cjne a,#5fh,chk6 mov dptr,#msg5 sjmp read chk6: cjne a,#6fh,chk7 mov dptr,#msg6 sjmp read chk7: cjne a,#7fh,chk8 mov dptr,#msg7 sjmp read chk8: cjne a,#8fh,chk9 mov dptr,#msg8 sjmp read chk9: cjne a,#9fh,chk10 mov dptr,#msg9 sjmp read chk10: cjne a,#0afh,chk11 mov dptr,#msg10 sjmp read chk11: cjne a,#0bfh,chk12 mov dptr,#msg11 sjmp read chk12: cjne a,#0cfh,chk13 mov dptr,#msg12 sjmp read chk13: cjne a,#0dfh,chk14 mov dptr,#msg13 sjmp read chk14: mov dptr,#msg14 sjmp read read: mov r3,dph mov r2,dpl setb tr0 rd1: mov r0,01h rd2: clr a movc a,@a+dptr jz down mov DBH,a clr a inc dptr movc a,@a+dptr mov DBL,a mov ADB,@r0 acall timer dec r0 inc dptr sjmp rd2 down: mov dph,r3 ;reload dph mov dpl,r2 ;reload dpl sjmp rd1 timer: mov tmod,#10h ;set mode 1 for timer1 mov th1,#0fch ;FC66H will generate a delay of 1ms with 11.0592MHz Xtal mov tl1,#66h setb tr1 jnb tf1,$ ;wait until timer1 overflows clr tr1 clr tf1 mov DBH,#0ffh mov DBL,#0ffh ret ;** look-up table starts from here: msg0: db Hh,Hl,Ah,Al,Ph,Pl,Ph,Pl,Yh ,Yl,bsh,bsl,Bh,Bl,Ih,Il,Rh,Rlw,Th,Tl,Hh ,Hl,bsh,bsl,Dh,Dl,Ah,Al,Yh,Yl,0 msg1: db Hh,Hl,Ah,Al,Ph,Pl,Ph,Pl,Y h,Yl,bsh,bsl,Nh,Nl,Eh,El,Wh,Wl,bsh,bsl, Yh,Yl,Eh,El,Ah,Al,Rh,Rlw,0 msg2: db strh,strl,bsh,bsl,Hh,Hl, Ah,Al,Ph,Pl,Ph,Pl,Yh,Yl,bsh,bsl,Dh,Dl, Ih,Il,Wh,Wl,Ah,Al,Lh,Ll,Ih,Il,bsh,bsl, strh,strl,0 msg3: db Mh,Ml,Eh,El,Rh,Rlw,Rh,Rlw, Yh,Yl,bsh,bsl,Ch,Cl,Hh,Hl,Rh,Rlw,Ih,Il, Sh,Sl,Th,Tl,Mh,Ml,Ah,Al,Sh,Sl,0 msg4: db strh,strl,bsh,bsl,Hh,Hl,Ah ,Al,Ph,Pl,Ph,Pl,Yh,Yl,bsh,bsl,Hh,Hl,Oh,O l,Lh,Ll,Ih,Il,bsh,bsl,strh,strl,0 msg5: db strh,strl,bsh,bsl,Eh,El, Ih,Il,Dh,Dl,bsh,bsl,Mh,Ml,Uh,Ul,Bh,Bl, Ah,Al,Rh,Rlw,Ah,Al,Kh,Kl,bsh,bsl,strh, strl,0 msg6: db Hh,Hl,Ah,Al,Ph,Pl,Ph,Pl,Y h,Yl,bsh,bsl,Dh,Dl,Ah,Al,Sh,Sl,Hh,Hl,Eh ,El,Hh,Hl,Rh,Rlw,Ah,Al,0 msg7: db Hh,Hl,Ah,Al,Ph,Pl,Ph,Pl,Y h,Yl,bsh,bsl,Wh,Wl,Eh,El,Dh,Dl,Dh,Dl,Ih ,Il,Nh,Nl,Gh,Gl,0 msg8: db Hh,Hl,Ah,Al,Ph,Pl,Ph,Pl,Yh ,Yl,bsh,bsl,Jh,Jl,Ah,Al,Nh,Nl,Mh,Ml,Ah,A l,Sh,Sl,Hh,Hl,Th,Tl,Mh,Ml,Ih,Il,0 msg9: db strh,strl,bsh,bsl,Hh,Hl, Ah,Al,Ph,Pl,Ph,Pl,Yh,Yl,bsh,bsl,Rh,Rlw ,Ah,Al,Kh,Kl,Hh,Hl,Ih,Il,bsh,bsl,strh, strl,0 msg10: db strh,strl,bsh,bsl,Hh,Hl, Ah,Al,Ph,Pl,Ph,Pl,Yh,Yl,bsh,bsl,Ph,Pl, Oh,Ol,Nh,Nl,Gh,Gl,Ah,Al,Lh,Ll,bsh,bsl, strh,strl,0 msg11: db Hh,Hl,Ah,Al,Ph,Pl,Ph,Pl,Yh ,Yl,bsh,bsl,Mh,Ml,Oh,Ol,Th,Tl,Hh,Hl,Eh,E l,Rh,Rlw,Sh,Sl,Dh,Dl,Ah,Al,Yh,Yl,0 msg12: db strh,strl,bsh,bsl,Hh,Hl, Ah,Al,Ph,Pl,Ph,Pl,Yh,Yl,bsh,bsl,Rh,Rlw ,Ah,Al,Mh,Ml,Jh,Jl,Ah,Al,Nh,Nl,bsh,bsl ,strh,strl,0 msg13: db strh,strl,bsh,bsl,Hh,Hl, Ah,Al,Ph,Pl,Ph,Pl,Yh,Yl,bsh,bsl,Lh,Ll, Oh,Ol,Hh,Hl,Rh,Rlw,Ih,Il,bsh,bsl,strh, strl,0 msg14: db strh,strl,bsh,bsl,Hh,Hl, Ah,Al,Ph,Pl,Ph,Pl,Yh,Yl,bsh,bsl,Eh,El, Ah,Al,Sh,Sl,Th,Tl,Eh,El,Rh,Rlw,bsh,bsl ,strh,strl,0 default: db Wh,Wl,Eh,El,Lh,Ll,Ch,Cl,O h,Ol,Mh,Ml,Eh,El,bsh,bsl,Th,Tl,Oh,Ol,bs h,bsl,Ah,Al,Lh,Ll,Lh,Ll,0 end

;set initial ;provides gap ;

mov r0,#60h blank: mov @r0,#0ffh ;initialize the pointed location by null address dec r0 cjne r0,#2fh,blank mov r1,#41h ;load addresspointer with initial address mov 50h,#0dfh Display (rightmost) mov 4fh,#0bfh Display mov 4eh,#9fh Display mov 4dh,#7fh Display mov 4ch,#5fh Display mov 4bh,#3fh Display mov 4ah,#1fh Display mov 49h,#0fbh Display mov 48h,#0f7h Display mov 47h,#0f3h Display mov 46h,#0efh Display mov 45h,#0ebh Display mov 44h,#0e7h Display mov 43h,#0e3h Display mov 42h,#0fdh Display mov 41h,#0feh Display (leftmost) ;address for 16th ;address for 15th ;address for 14th ;address for 13th ;address for 12th ;address for 11th ;address for 10th ;address for 9th ;address for 8th ;address for 7th ;address for 6th ;address for 5th ;address for 4th ;address for 3rd ;address for 2nd ;address for 1st

chk: mov a,input ;load accumulator with value at P3 orl a,#0fh ;mask lower nible to get selection bus value cjne a,#0ffh,chk0 mov dptr,#default ;load dptr with starting address of defalt message sjmp read ; now start reading chk0: cjne a,#0fh,chk1 mov dptr,#msg0 ;load dptr with starting address of msg0 sjmp read ; now start reading chk1: cjne a,#1fh,chk2 mov dptr,#msg1 sjmp read

You might also like