Open Display

The idea for this project was inspired by the article "Text at the Speed of Light" published by Steffen Sorge in Elektor Electronics 1/2007, p. 54-57. The device can be used for displaying short messages by using 7 rotating LEDs. At each time moment the LEDs display only one column of a message. If the rotation is fast enough, the eye gets an impression of permanently displayed text. The original design is based on an AVR microcontroller, we decided to do it with PIC. Furthermore, instead of displaying the text at the surface of a rotating cylinder we display it on the surface of rotating disk. This way the entire message can be read at once.

Hardware

The rotating part has a control circuit built around PIC16F648A. All used parts except of LEDs are SMD to decrease the weight. The PIC and LEDs are powered by a fixed voltage regulator 7805 in a DPAC case. This significantly reduces the incoming noise to the board form the power lines. The Hall effect sensor is used to start displaying the message at the beginning of each rotation. It flies above a small magnet mounted on the base board (we used 1/8" Rare Earth Super Magnet from RadioShack). The sensor output is connected to the external interrupt input of PIC. To balance the PCB we dropped some solder to its end opposite to the LEDs. Balancing is absolutely necessary to avoid noticeable shaking of the whole unit due to a fast rotation speed.

Although the motor is rated at 12VDC, it turns out that its rotating speed can be lowered without any flicker appearance. Without a load the motor rotates at approx. 1800 RPM. To slow it down we built a linear voltage regulator on LM317 which powers the motor at 8VDC. Moreover, this way the motor voltage is stabilized which is beneficial for getting a steady image on the display.

Schematic PCB Voltage regulator

The first challenge we had to resolve was to deliver the voltage to the rotating LEDs. For this purpose we built a construction similar to the one used in electric motors. Two brass brushes touch the motor axis and a small brass pipe attached to it. There is, of course, a plastic insulation between the pipe and the axis. The insulation is just a peace of a nylon 1/8" spacer available in Menards. Its outer diameter matches the one of the brass pipe which was found in a local Hobby store. To provide a good electric contact between the motor axis and the PCB, we used another 1/8" copper pipe attached to the motor axis so that we could solder a wire to it.

This solution requires a motor with a decent axis. We found a suitable one at AllElectronics.com that has a long axis of diameter 3mm (CAT# DCM-270). The motor is mounted on a wooden base and fixed by two bolts. The brushes are made of brass too and are mounted on nails. To guarantee a good electric contact between the brushes and the pipe/axis we used small springs. The red and blue round-ended nails are needed to provide a tension for the springs. The magnet is glued to a brass stand and is placed approx. 1.5 cm away from the motor axis. For a reliable sensor operation the distance between the magnet that we used and the sensor should not exceed 7-8mm.

Brushes Brushes Assembled unit

The motor panel is attached to another horizontal wooden panel. On the back side of this panel there is an L-shaped aluminum profile carrying the pot of the voltage regulator, DC power connector and a power swith. The pot can also be used to adjust the rotation speed in order to perfectly center the displaying message (see the video clip). All the other components of the voltage regulator are mounted directly on those parts. The LM317 itself is mounted on the L-shaped profile, which also serves as a heat sink. The unit is powered from a 12VDC walwart.

Front view Back view Video clip
clip
AVI ~8.8Mb

Unfortunately I did not succeed to make a good video clip. The photo above captured from the clip only shows a part of the displayed message "Welcome to CSCI 381", whereas the whole message is seen in reality. Also, the clip flickers because of a mismatch between the shooter speed of my camcorder, frame speed, and the unit rotation. There is no noticeable flickering observed in the reality.

Software

The message is displayed by using a 5x7 font which is loaded to the EEPROM at the time of programming. The code only reads it from the EEPROM afterwards. The EEPROM has place for storing only 256/5 = 51 characters. This includes digits, upper-case letters and some punctuation signs. Since the characters addresses in EEPROM are not ASCII-based, we need a special software tool for encoding the message to display. This tool outputs the message encoding which can be directly plugged into the corresponding assembly language routine. It also adds some spaces at the beginning and at the end of a message to center it on the display. Since the motor rotates counterclockwise (and it is impossible to change its direction), we need to display the message backwards. Furthermore, the columns of each character must be also displayed backwards (from right to left).

After a straightforward initialization of the I/O ports and used variables, the program enters the main loop. This loop displays the message character by character and each character column by column in an inner loop. First, the base address of the character is computed by multiplying its code by 5 (remember we use a 5x7 font). This is accomplished by adding the code to itself 4 times.

main_loop                        ; main loop 
        movf    charIndex, w
        call    getChar          ; get next string character in WREG
        movwf   address
        addwf   address, f       ; address*2
        addwf   address, f       ; address*3
        addwf   address, f       ; address*4
        addwf   address, f       ; address*5
        decf    address, f

The inner loop is controlled by the variable columnNo which goes from 5 down to 0 to display the character columns in the reversed order. At each iteration of this loop we add the column number to the base address of the character to get a byte address in EEPROM to display. Each character column is displayed for approx. 160μsec, which is provided by calling the colDelay routine.

        movlw   5
        movwf   columnNo         ; setup initial column number 
char_loop
        movf    address, w
        addwf   columnNo, w      ; w = character offset + column

        bsf     STATUS, RP0      ; switch to BANK 1
        movwf   EEADR            ; column address in EEPROM
        bsf     EECON1, RD       ; read request from EEPROM
        movf    EEDATA, w        ; returned data from EEPROM
        bcf     STATUS, RP0      ; back to BANK 0
        iorwf   PORTB, f         ; display next column
        call    colDelay
        movlw   1
        andwf   PORTB, f         ; clear display

        decfsz  columnNo, f      ; load new character?
         goto   char_loop        ; NO - proceed with another column

Upon displaying all 5 columns of a character the code checks if the entire string is displayed. If this is not the case, we jump back to the main loop. Otherwise, we dive to an infinite loop waiting a synchronizing interrupt provided by the Hall effect sensor in order to start displaying the message from a proper position again.

        call    charDelay         ; character separator
        incf    charIndex, f      ; proceed with the next character
        movf    stringLen, w
        subwf   charIndex, w      ; end of string?
        btfss   STATUS, Z
         goto   main_loop         ; NO - proceed
        goto    $                 ; wait for interrupt to start over

The interrupt service routine is trivial. It just clears the interrupt flag and re-enables the interrupts globally (during the interrupt processing all further interrupts are automatically disabled). A particularity of the ISR is that it does not return from interrupt by using the retie instruction. This is because we cannot predict the place in the code where the interrupt occurs. Instead, we just jump to the beginning of the main loop. Since the stack in PIC devices is organized as a circular buffer, we do not care on its overflow and the return addresses located in it by starting to display the message from scratch.

 ORG 4				  ; ISR
 	bcf	INTCON, INTF      ; clear interrupt flag
	bsf	INTCON, GIE	  ; enable interrupts globally
	goto	main_loop-1	  ; start displaying the message from scratch

Final thoughts

The brush and collector construction should be improved. The motor axis is 3mm in diameter and the available spacers and pipes we have are on the SAE system. This results in a slight mismatch between their diameters. We solved it by placing a Scotch film between the axis and the spacers/pipe, which created a small disbalance and lead to a noisy brush operation.

Use as bright LEDs as you can get. Otherwise, the message is not very good visible at the day light. This might require to increase the current through the LEDs over 25ma which is the maximum that PIC can handle. In this case I would add MOSFET driver transistors for each LED. If this is not desirable, consider sinking the current from LEDs by connecting the PIC's outputs to the LED's cathodes and conecting the LED resistors to +5V. This shlould improve driving the LEDs, since the logical 1 output voltage of the PIC is not quite 5V and depends in the output current, which is difficut to maintain.

The 10K pull-up resistor at the output of the Hall effect sensor can be eliminated by enabling the internal PIC pull-up at RB0 pin.

Consider building a switching motor voltage regulator. This will significantly decreas the amount of heat dissipating by the circuit.

Downloads


Last modified:Mon, Jan 23, 2023.

01945