Hm, not sure I should post this here, not being arduino at all, but since you kinda requested it: Yeah, I did actually make one such "message wand" (why didn't I think of that name?) a good while ago, in 2001. I called it a flutter display, or simply "the stick".
Not sure if this is helpful at all though. Also I hope it is alright to post even if it isn't arduino-related.
Since I am borrowing a video camera atm, I uploaded it to youtube
- YouTube
(I know, terrible design, basically just "wirewrapped" to a stick)
This was basically a one-off thing I did back then, basically built with scrap parts I had at hand. Also since I had a 16C84 and a programmer. For direction change sensing I hacked a relay, soldered a somewhat heavy, stiff copper wire to the middle moving contact of the relay. It fitted through a hole in one of the other relay contacts, and I just coiled it at the end, so it wouldn't stick too far out. You can see it in the video how it works. Actually, this idea was the one that made me make this thing! Prior to that I had no real handle on how to sense the change-of-direction.
Oh, and it's not really finished
Will probably never be, though I might have an arduino go sometime in the undecided future.
I had in mind making the display work in both directions, but this one only displays while going one way. I had some trouble aligning the image both ways so I "temporarily" disabled it. I also made 2 rows of LED's, one red row and one green, with a possible future addition of a blue row, for colors. Except in this demo I only use the red row, displaying my old nick. I didn't bother to change it, as I would have to figure out how to program the thing again.
I build it on a piece of stripboard I had, so I never made any PCB or a layout of any kind. The only "schematics" is this one, which I actually found. It is of course not tidied up at all, its more of a back-of-napkin kind of drawing actually. Beware it seems to contain some errors, omissions and otherwise an unrelated pinout for a LM324 for some reason
Only showing 2 of the 8 LED's pr. row (red and green row), from the 74LS245.
I guess I can post my code too (with some spelling errors I just discovered). So my first exhibition is a non-arduino one ![]()
Seems I ran it on around 500 kHz (not 1,2 or 4 MHz as stated in the schematics). I didn't use a crystal, but made a RC oscillator with a schmitt-trigger NAND gate. The output of that is connected to the clock input I think.
Part #1 of 2 of the code:
;**********************************************************************
; *
; Program : "THE STICK" - display driver v1.00 *
; File Version : 1.12 *
; Dates : 2001.10.03 *
; 2001.10.04 *
; *
; (C) 2001 ARON *
; *
;**********************************************************************
; *
; Files required: p16C84.inc *
; *
; *
; *
;**********************************************************************
; *
; Notes: *
; *
;Clock mode is XT, because the clock is external osc. approx. 500 KHz *
; *
; *
;EEprom data used as 8* 64 display matrix. *
; *
; Port B is display output, LSB is lower LED, MSB is upper *
; *
; Port A: *
; (in) RA0 = Motion-LEFT sensor (1 = left movement begun) *
; (in) RA1 = Motion-RIGHT sensor (1 = right movement begun) *
; (out) RA2 = RED GND (1 = GND active, ie. RED LED's ON) *
; (out) RA3 = GREEN GND *
; (out) RA4 = UNUSED (Future: BLUE GND?) *
; *
; *
; Further notes: This version displays text ARON during left scan in *
; red LED's. right scan turned off because of alignment troble, *
; possibly in delay-part of scan-routines. *
; *
; Also, display data is longer than neccesary to compensate for a *
; bad delay-routine, filled with zero's.... *
; *
;**********************************************************************
list p=16C84 ; list directive to define processor
#include <p16C84.inc> ; processor specific variable definitions
__CONFIG _CP_OFF & _WDT_OFF & _PWRTE_ON & _XT_OSC
;**** Constants
MATRIX EQU 0x27 ; Set matrix size here, 1-64 / 0x01 - 0x40
FRAMETIME EQU 0xFF ; Arbitrarily choosen initial frame-scanning time
DELAYPIX EQU 0x08 ; Pixel-delay before/after display
;***** VARIABLE DEFINITIONS
scantime EQU 0x0C ; Measured time for last frame
rowtime EQU 0x0D ; timeslot for one row of display data
wait EQU 0x0E ; wait-variable for time-waste subroutine
matrixsize EQU 0x0F ; Size-of-matrix
value EQU 0x10 ; value to be divided by divident
divident EQU 0x11
subcounter EQU 0x12 ; Nr. of subtractions (answear of division)
delay EQU 0x13 ; Beg/end delay-time in matrix-pixels measurements
nextrtime EQU 0x14 ; When to display the next row
scanpos EQU 0x15 ; just a position counter
row EQU 0x16 ; display row index
totsize EQU 0x17 ; total display size (width) included delay
stopdisp EQU 0x18
; *** Declaring EEPROM data
ORG 0x2100 ; start dummy address of EEprom
de 0x1f,0x3f,0x68,0xc8,0xc8,0x68,0x3f,0x1f,0x00 ; A
de 0xff,0xff,0xc8,0xce,0x7b,0x31,0x00 ; R
de 0x3c,0x66,0xc3,0xc3,0x66,0x3c,0x00 ; O
de 0xff,0xff,0x60,0x18,0x06,0xff,0xff ; N
de 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 ;fillbytes for alignment cheating
;**********************************************************************
ORG 0x000 ; processor reset vector
init bcf INTCON,GIE ; Disable interrupts for my un-interuptable program
; --- init ports
clrf PORTB ; set portb = 00000000
clrf PORTA
bsf STATUS,RP0 ; select bank 1
movlw 0x00 ; All bits in portb = outputs
movwf TRISB ; set port b data direction register
movlw 0x03 ; bit #0 and #1 is inputs, the rest outputs in port A
movwf TRISA
movlw B'11000111' ; prescaler assigned to TMR0
movwf OPTION_REG
bcf STATUS,RP0 ; select bank 0
; --- other inits
movlw MATRIX
movwf matrixsize
movlw FRAMETIME
movwf scantime ; initial scan-time (approx guess)
movlw DELAYPIX
movwf delay
movf matrixsize,W
addwf delay,W
movwf stopdisp ; Display-scan-stop position in matrix-pixels
addwf delay,W ; W = matrix + 2 * delay
movwf totsize ; total "size" of matrix included display delay
; **** Blink all LED's initially
bsf PORTA,2 ; test-blink RED LEDs
bsf PORTA,3 ; no test-blink GREEN LEDs
movlw 0x80
movwf wait ; initial blinking time
blinkinit comf PORTB,F ; complement port B
call timerwait
movf PORTA,W ; W = portA
andlw 0x03 ; Is one of port A's lowest bits set??
btfsc STATUS,Z ; check Zero-flag, W>=1 => Z=0...
goto blinkinit
; **** Which direction to scan the display?
main
testleft btfsc PORTA,0 ; test if bit0 is set (left-scanning display)
goto lscaninit ; yes..
goto rscaninit ; no...
