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.
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 | ||
![]() 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.
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 |
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.
Last modified:Mon, Jan 23, 2023.