[Request] Has anyone made a "Message Wand"?

Its a single row of leds made in a "wand" shape and when you wave it back and forth preprogrammed text or shapes appear in the air. I think that could be a interesting project I'd like to build, but is beyond my skill.

you are looking for a wand type POV device.

Google arduino POV and you should find a few.
There is a kit you can buy as well but I can't remember who makes it.

Mowcius

There is a kit you can buy as well but I can't remember who makes it.

It's Adafruit's "Mini POV":

Thanks guys, these are great. Is there one in color with more leds?

Thanks guys, these are great. Is there one in color with more leds?

Short answer: No.
If you want to make your own however, you might want to look at this:

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 :slight_smile: - 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 :stuck_out_tongue: 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 :stuck_out_tongue: 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 :stuck_out_tongue:
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...

Part #2 of 2 of the code (the same file)

; ***** RIGHT SCANNING DISPLAY
; --- blank display and check for direction change from left to right

waitforright      clrf      PORTB            ; blank display after stop-pos
            btfss      PORTA,1            ; check if right-swing is registered
            goto      waitforright
endlscan      movf      TMR0,W
            movwf      scantime      ; new scantime (or rather, the one just finished..)

rscaninit      clrf      TMR0            ; clear timer
            clrf      PORTB            ; Initially clear display
            clrf      scanpos
            clrf      row
            clrf      nextrtime

; TEST *****
            bcf      PORTA,2
            bcf      PORTA,3            ;Set / Clear display during this scan

            movf      totsize,W
            movwf      divident
            movf      scantime,W
            movwf      value
            call      divide            ; subcounter = scantime / totsize
            movf      subcounter,W
            movwf      rowtime            ; find time allowed pr. row
            movwf      nextrtime      ; set initial delay


rscan            movf      nextrtime,W
            subwf      TMR0,W            ; W = TMR0 - nextrtime
            btfsc      STATUS,C      ; skip if nextrtime < TMR0
            goto      rrowdisp
            btfss      PORTA,0            ; check if left-swing is registered (END R-SCAN)
            goto      rscan
            goto      endrscan

rrowdisp      incf      scanpos,F      ; next row abs. position
            movf      rowtime,W
            addwf      nextrtime,F      ; next row time-start in TMR0-steps

            movf      delay,W
            subwf      scanpos,W      ; W = scanpos - delay
            btfss      STATUS,C      ; skip if scanpos > delay
            goto      rscan

            movf      stopdisp,W
            subwf      scanpos,W      ; W = scanpos - stopdisp
            btfsc      STATUS,C      ; skip if stopdisp > scanpos
            goto      waitforleft

;-- read EEPROM
            bcf      STATUS,RP0
            movf      row,W
            movwf      EEADR
            bsf      STATUS,RP0
            bsf      EECON1,RD      ;initiate read
            bcf      STATUS,RP0
            movf      EEDATA,W
            movwf      PORTB            ; Display it..
;--
            incf      row,F            ; next row pointer
            goto      rscan




; ***** LEFT SCANNING DISPLAY
; --- blank display and check for direction change from right to left

waitforleft      clrf      PORTB            ; blank display after stop-pos
            btfss      PORTA,0            ; check if left-swing is registered
            goto      waitforleft
endrscan      movf      TMR0,W            ; Direction-change detected
            movwf      scantime      ; new scantime (or rather, the one just finished..)

lscaninit      clrf      TMR0            ; clear timer
            clrf      PORTB            ; Initially clear display
            clrf      nextrtime
            clrf      scanpos

; TEST *****
            bsf      PORTA,2
            bcf      PORTA,3            ;Set / Clear display during this scan


            movf      matrixsize,W
            movwf      row
            decf      row,F            ; initial row-nr backwards 

            movf      totsize,W
            movwf      divident
            movf      scantime,W
            movwf      value
            call      divide            ; scantime / totsize
            movf      subcounter,W
            movwf      rowtime            ; find time allowed pr. row
            movwf      nextrtime      ; set initial delay


lscan            movf      nextrtime,W
            subwf      TMR0,W            ; W = TMR0 - nextrtime
            btfsc      STATUS,C      ; skip if nextrtime < TMR0
            goto      lrowdisp
            btfss      PORTA,1            ; check if right-swing is registered (END L-SCAN)
            goto      lscan
            goto      endlscan

lrowdisp      incf      scanpos,F      ; next row abs. position
            movf      rowtime,W
            addwf      nextrtime,F      ; next row time-start in TMR0-steps

            movf      delay,W
            subwf      scanpos,W      ; W = scanpos - delay
            btfss      STATUS,C      ; skip if scanpos > delay
            goto      lscan

            movf      stopdisp,W
            subwf      scanpos,W      ; W = scanpos - stopdisp
            btfsc      STATUS,C      ; skip if stopdisp > scanpos
            goto      waitforright

;-- read EEPROM
            bcf      STATUS,RP0
            movf      row,W
            movwf      EEADR
            bsf      STATUS,RP0
            bsf      EECON1,RD      ;initiate read
            bcf      STATUS,RP0
            movf      EEDATA,W
            movwf      PORTB            ; Display it..
;--
            decf      row,F            ; next row pointer backwards
            goto      lscan








; ********************** SUB ROUTINES ********************************


; --- un-accurate division, answear is within + 1 / - 0 or something
;      of correct answear, all integers if course...

divide            movlw      0x00
            movwf      subcounter      ;clear answear

            movf      divident,W
            btfsc      STATUS,Z      ;check for divide-by-zero
            goto      divideby0

subloop            movf      divident,W
            subwf      value,W            ; W = value - divident
            btfss      STATUS,C      ; did a borrow occur?
            RETURN                  ; yes, value < divident, answear is OK..
            movwf      value
            incf      subcounter,F
            goto      subloop

divideby0      incf      subcounter,F      ; here, div-by-zero equals 1 :-)
            RETURN                  ; dont know why, but it feels good




; --- Time-waist routine

timerwait      movlw      0x00
            movwf      TMR0            ; clear timer

tloop            movf      TMR0,W
            subwf      wait,W            ; W = wait - timer
            btfss      STATUS,Z      ; W = 0 ?
            goto      tloop            ; no,  wait more
            RETURN




            END                     ; directive 'end of program'

I made one too, it's really easy to do with the Arduino. Hope you can get enough resources to build your own, it's a fun project. (mine was slower than a normal POV so I could write in longer exposure photographs, but you can easily change the delay to make it faster/slower as you want). If you want code I can post it

http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1242879841

Makezine recently just featured one such project (http://blog.makezine.com/archive/2010/05/new_in_the_maker_shed_povard_pov_ki.html) and if you want the kit, you can get from them.

LOL i just attempted to make one on a breadboard. All the jumper wires keep jumping out and it's too early for me to do something about i need to go to bed xD.

The first POV I ever saw was at a science fair many years ago. It was a vertical strip of leds mounted on the wall and when you walked past them you would see a random image out of the corner of your eye and when you turned to look it disappeared. It was amusing to watch people with puzzled looks turning their heads back and forth.

I'd like to reproduce that effect... I downloaded some POV code but not sure how to use it. The leds flash for a couple seconds and then stop.

#include <avr/power.h>
#include <avr/sleep.h>

[color=#CC6600]int[/color] ledpin[] = {12,11,10,9,4,3,8,7,6,5};
[color=#CC6600]int[/color] dotTime = 1;

[color=#CC6600]int[/color] _[] = {0b0000000000,
          0b0000000000,
          0b0000000000,
          0b0000000000,
          0b0000000000};
[color=#CC6600]int[/color] A[] = {0b1111111100,
          0b0000010010,
          0b0000010001,
          0b0000010010,
          0b1111111100};
[color=#CC6600]int[/color] B[] = {0b1111111111,
          0b1000010001,
          0b1000010001,
          0b0100101010,
          0b0011000100};
[color=#CC6600]int[/color] C[] = {0b0011111100,
          0b0100000010,
          0b1000000001,
          0b0100000010,
          0b0011001100};
[color=#CC6600]int[/color] D[] = {0b1111111111,
          0b1000000001,
          0b1000000001,
          0b0100000010,
          0b0011111100};
[color=#CC6600]int[/color] E[] = {0b1111111111,
          0b1000010001,
          0b1000010001,
          0b1000010001,
          0b1000000001};
[color=#CC6600]int[/color] F[] = {0b1111111111,
          0b0000010001,
          0b0000010001,
          0b0000010001,
          0b0000000001};
[color=#CC6600]int[/color] G[] = {0b0011111100,
          0b0100000010,
          0b1001000001,
          0b0101000010,
          0b1111001100};
[color=#CC6600]int[/color] H[] = {0b1111111111,
          0b0000010000,
          0b0000010000,
          0b0000010000,
          0b1111111111};
[color=#CC6600]int[/color] I[] = {0b0000000000,
          0b1000000001,
          0b1111111111,
          0b1000000001,
          0b0000000000};
[color=#CC6600]int[/color] J[] = {0b0011111111,
          0b0100000001,
          0b1000000001,
          0b0100000000,
          0b0011000000};
[color=#CC6600]int[/color] K[] = {0b1111111111,
          0b0000010000,
          0b0000101000,
          0b0001000100,
          0b1110000011};
[color=#CC6600]int[/color] L[] = {0b1111111111,
          0b1000000000,
          0b1000000000,
          0b1000000000,
          0b1000000000};
[color=#CC6600]int[/color] M[] = {0b1111111100,
          0b0000000011,
          0b0000001100,
          0b0000000011,
          0b1111111100};
[color=#CC6600]int[/color] N[] = {0b1111111111,
          0b0000000110,
          0b0000011000,
          0b0001100000,
          0b1111111100};
[color=#CC6600]int[/color] O[] = {0b0011111100,
          0b0100000010,
          0b1000000001,
          0b0100000010,
          0b0011111100};
[color=#CC6600]int[/color] P[] = {0b1111111111,
          0b0000010001,
          0b0000010001,
          0b0000001010,
          0b0000000100};
[color=#CC6600]int[/color] Q[] = {0b0011111100,
          0b0100000010,
          0b1000000001,
          0b0100000010,
          0b1011111100};
[color=#CC6600]int[/color] R[] = {0b1111111111,
          0b0000010001,
          0b0000010001,
          0b0000101010,
          0b1111000100};
[color=#CC6600]int[/color] S[] = {0b0011000100,
          0b0100001010,
          0b1000010001,
          0b0100100010,
          0b0011001100};
[color=#CC6600]int[/color] T[] = {0b0000000001,
          0b0000000001,
          0b1111111111,
          0b0000000001,
          0b0000000001};
[color=#CC6600]int[/color] U[] = {0b0111111111,
          0b1000000000,
          0b1000000000,
          0b1000000000,
          0b0111111111};
[color=#CC6600]int[/color] V[] = {0b0000011111,
          0b0011100000,
          0b1100000000,
          0b0011100000,
          0b0000011111};
[color=#CC6600]int[/color] W[] = {0b0011111111,
          0b1100000000,
          0b0011000000,
          0b1100000000,
          0b0011111111};
[color=#CC6600]int[/color] X[] = {0b1100000011,
          0b0011001100,
          0b0000110000,
          0b0011001100,
          0b1100000011};
[color=#CC6600]int[/color] Y[] = {0b0000000011,
          0b0000001100,
          0b1111110000,
          0b0000001100,
          0b0000000011};
[color=#CC6600]int[/color] Z[] = {0b1100000001,
          0b1011000001,
          0b1000110001,
          0b1000001101,
          0b1000000011};


[color=#CC6600]void[/color] [color=#CC6600][b]setup[/b][/color]() {
 [color=#CC6600][b]Serial[/b][/color].[color=#CC6600]begin[/color](9600);
 [color=#CC6600]for[/color] ([color=#CC6600]int[/color] i = 0; i < 10; i++) {
   [color=#CC6600]pinMode[/color](ledpin[i], [color=#006699]OUTPUT[/color]);
 }
 [color=#CC6600]pinMode[/color](2, [color=#006699]INPUT[/color]);
 [color=#CC6600]digitalWrite[/color](2, 1);
 [color=#CC6600]digitalWrite[/color](13, 1);
}

[color=#CC6600]int[/color] pow([color=#CC6600]int[/color] num, [color=#CC6600]int[/color] power) {
 [color=#CC6600]return[/color] [color=#CC6600]round[/color](pow(([color=#CC6600]double[/color])num, ([color=#CC6600]double[/color])power));
}

[color=#CC6600]void[/color] printLetter([color=#CC6600]int[/color] letter[]) {
 [color=#CC6600]delay[/color](dotTime);
 [color=#CC6600]for[/color] ([color=#CC6600]int[/color] i = 0; i < 5; i++) {
   [color=#CC6600]for[/color] ([color=#CC6600]int[/color] j = 0; j < 10; j++) {
     [color=#CC6600]digitalWrite[/color](ledpin[j], (letter[i] & pow(2, j)) ? [color=#006699]HIGH[/color] : [color=#006699]LOW[/color]);
     [color=#CC6600][b]Serial[/b][/color].[color=#CC6600]print[/color]((letter[i] & pow(2, j)) ? [color=#006699]"O"[/color] : [color=#006699]" "[/color]);
   }
   [color=#CC6600][b]Serial[/b][/color].[color=#CC6600]print[/color]([color=#006699]"|\n"[/color]);
   [color=#CC6600]delay[/color](dotTime);
 }
 [color=#CC6600][b]Serial[/b][/color].[color=#CC6600]print[/color]([color=#006699]"\n"[/color]);
 [color=#CC6600]for[/color] ([color=#CC6600]int[/color] i = 0; i < 10; i++)
   [color=#CC6600]digitalWrite[/color](ledpin[i], 0);
 [color=#CC6600]delay[/color](dotTime);
}

[color=#CC6600]void[/color] wake() {}

[color=#CC6600]void[/color] [color=#CC6600][b]loop[/b][/color]() {
 [color=#CC6600]delay[/color](1);
 printLetter(H);
 printLetter(E);
 printLetter(L);
 printLetter(L);
 printLetter(O);
 printLetter(_);
 
 [color=#CC6600]attachInterrupt[/color](0, wake, [color=#006699]LOW[/color]);
 [color=#CC6600]delay[/color](1);
 set_sleep_mode(SLEEP_MODE_PWR_DOWN);
 sleep_enable();
 sleep_mode();
 sleep_disable();
 [color=#CC6600]detachInterrupt[/color](0);
}

I think if I can make it repeat it would work.

I made one too, it's really easy to do with the Arduino. Hope you can get enough resources to build your own, it's a fun project. (mine was slower than a normal POV so I could write in longer exposure photographs, but you can easily change the delay to make it faster/slower as you want). If you want code I can post it

k2pek2 - Liked your project... I would like to see your code if your willing?

The code is poorly annotated and I don't have time now to go through and annotate it all, but if you take a long look at it you should be able to figure it out. it's pretty basic. If you have any specific questions, I'll be happy to help.

  //These are arrays that contain the individual letters that may be written.
int _[] = {
  0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,};
int A[] = {
  1,1,1,1,1,1,1,1,0,0,0,0, 0,0,0,0,0,0,1,0,1,1,0,0, 0,0,0,0,0,0,1,0,0,0,1,0, 0,0,0,0,0,0,1,0,0,0,0,1, 0,0,0,0,0,0,1,0,0,0,1,0, 0,0,0,0,0,0,1,0,1,1,0,0, 1,1,1,1,1,1,1,1,0,0,0,0,};
int B[] = {
  1,1,1,1,1,1,1,1,1,1,1,1, 1,0,0,0,0,0,0,1,0,0,0,1, 1,0,0,0,0,0,0,1,0,0,0,1, 1,0,0,0,0,0,0,1,0,0,0,1, 1,0,0,0,0,0,1,0,0,0,0,1, 0,1,0,0,1,1,0,1,0,0,1,0, 0,0,1,1,0,0,0,0,1,1,0,0,};
int C[] = {
  0,0,0,1,1,1,1,1,0,0,0,0, 0,1,1,0,0,0,0,0,1,1,0,0, 1,0,0,0,0,0,0,0,0,0,1,0, 1,0,0,0,0,0,0,0,0,0,0,1, 1,0,0,0,0,0,0,0,0,0,0,1, 0,1,0,0,0,0,0,0,0,0,1,0, 0,0,1,1,0,0,0,0,1,1,0,0,};
int D[] = {
  1,1,1,1,1,1,1,1,1,1,1,1, 1,0,0,0,0,0,0,0,0,0,0,1, 1,0,0,0,0,0,0,0,0,0,0,1, 1,0,0,0,0,0,0,0,0,0,0,1, 0,1,0,0,0,0,0,0,0,0,1,0, 0,0,1,1,0,0,0,0,1,1,0,0, 0,0,0,0,1,1,1,1,0,0,0,0,};
int E[] = {
  1,1,1,1,1,1,1,1,1,1,1,1, 1,0,0,0,0,0,1,0,0,0,0,1, 1,0,0,0,0,0,1,0,0,0,0,1, 1,0,0,0,0,0,1,0,0,0,0,1, 1,0,0,0,0,0,1,0,0,0,0,1, 1,0,0,0,0,0,0,0,0,0,0,1, 1,0,0,0,0,0,0,0,0,0,0,1,};
int F[] = {
  1,1,1,1,1,1,1,1,1,1,1,1, 0,0,0,0,0,0,0,1,0,0,0,1, 0,0,0,0,0,0,0,1,0,0,0,1, 0,0,0,0,0,0,0,1,0,0,0,1, 0,0,0,0,0,0,0,1,0,0,0,1, 0,0,0,0,0,0,0,0,0,0,0,1, 0,0,0,0,0,0,0,0,0,0,0,1,};
int G[] = {
  0,0,0,0,1,1,1,1,1,0,0,0, 0,0,1,1,0,0,0,0,0,1,1,0, 0,0,1,0,0,0,0,0,0,0,0,1, 1,0,0,0,0,0,0,0,0,0,0,1, 1,0,0,0,1,0,0,0,0,0,0,1, 0,1,1,0,1,0,0,0,0,0,1,0, 0,0,0,1,1,0,0,0,0,1,0,0,};
int H[] = {
  1,1,1,1,1,1,1,1,1,1,1,1, 0,0,0,0,0,0,1,0,0,0,0,0, 0,0,0,0,0,0,1,0,0,0,0,0, 0,0,0,0,0,0,1,0,0,0,0,0, 0,0,0,0,0,0,1,0,0,0,0,0, 0,0,0,0,0,0,1,0,0,0,0,0, 1,1,1,1,1,1,1,1,1,1,1,1,};
int I[] = {
  1,0,0,0,0,0,0,0,0,0,0,1, 1,0,0,0,0,0,0,0,0,0,0,1, 1,0,0,0,0,0,0,0,0,0,0,1, 1,1,1,1,1,1,1,1,1,1,1,1, 1,0,0,0,0,0,0,0,0,0,0,1, 1,0,0,0,0,0,0,0,0,0,0,1, 1,0,0,0,0,0,0,0,0,0,0,1,};
int J[] = {
  0,1,1,0,0,0,0,0,0,0,0,1, 1,0,0,0,0,0,0,0,0,0,0,1, 1,0,0,0,0,0,0,0,0,0,0,1, 0,1,1,1,1,1,1,1,1,1,1,1, 0,0,0,0,0,0,0,0,0,0,0,1, 0,0,0,0,0,0,0,0,0,0,0,1, 0,0,0,0,0,0,0,0,0,0,0,1,};
int K[] = {
  1,1,1,1,1,1,1,1,1,1,1,1, 0,0,0,0,0,1,1,0,0,0,0,0, 0,0,0,0,1,0,0,1,0,0,0,0, 0,0,0,1,0,0,0,0,1,0,0,0, 0,0,1,0,0,0,0,0,0,1,0,0, 0,1,0,0,0,0,0,0,0,0,1,0, 1,0,0,0,0,0,0,0,0,0,0,1,};
int L[] = {
  1,1,1,1,1,1,1,1,1,1,1,1, 1,0,0,0,0,0,0,0,0,0,0,0, 1,0,0,0,0,0,0,0,0,0,0,0, 1,0,0,0,0,0,0,0,0,0,0,0, 1,0,0,0,0,0,0,0,0,0,0,0, 1,0,0,0,0,0,0,0,0,0,0,0, 1,0,0,0,0,0,0,0,0,0,0,0,};
int M[] = {
  1,1,1,1,1,1,1,1,1,1,1,1, 0,0,0,0,0,0,0,0,0,1,1,0, 0,0,0,0,0,0,0,1,1,0,0,0, 0,0,0,0,0,1,1,0,0,0,0,0, 0,0,0,0,0,0,0,1,1,0,0,0, 0,0,0,0,0,0,0,0,0,1,1,0, 1,1,1,1,1,1,1,1,1,1,1,1,};
int N[] = {
  1,1,1,1,1,1,1,1,1,1,1,1, 0,0,0,0,0,0,0,0,0,1,1,0, 0,0,0,0,0,0,0,1,1,0,0,0, 0,0,0,0,0,1,1,0,0,0,0,0, 0,0,0,1,1,0,0,0,0,0,0,0, 0,1,1,0,0,0,0,0,0,0,0,0, 1,1,1,1,1,1,1,1,1,1,1,1,};
int O[] = {
  0,0,0,1,1,1,1,1,1,0,0,0, 0,1,1,0,0,0,0,0,0,1,1,0, 1,0,0,0,0,0,0,0,0,0,0,1, 1,0,0,0,0,0,0,0,0,0,0,1, 1,0,0,0,0,0,0,0,0,0,0,1, 0,1,1,0,0,0,0,0,0,1,1,0, 0,0,0,1,1,1,1,1,1,0,0,0,};
int P[] = {
  1,1,1,1,1,1,1,1,1,1,1,1, 0,0,0,0,0,0,1,0,0,0,0,1, 0,0,0,0,0,0,1,0,0,0,0,1, 0,0,0,0,0,0,1,0,0,0,0,1, 0,0,0,0,0,0,1,0,0,0,0,1, 0,0,0,0,0,0,0,1,0,0,1,0, 0,0,0,0,0,0,0,0,1,1,0,0,};
int Q[] = {
  0,0,0,1,1,1,1,1,1,0,0,0, 0,1,1,0,0,0,0,0,0,1,1,0, 1,0,0,0,0,0,0,0,0,0,0,1, 1,0,0,0,1,0,0,0,0,0,0,1, 1,0,0,1,0,0,0,0,0,0,0,1, 0,1,1,0,0,0,0,0,0,1,1,0, 1,1,0,1,1,1,1,1,1,0,0,0,};
int R[] = {
  1,1,1,1,1,1,1,1,1,1,1,1, 0,0,0,0,0,1,1,0,0,0,0,1, 0,0,0,0,1,0,1,0,0,0,0,1, 0,0,0,1,0,0,1,0,0,0,0,1, 0,0,1,0,0,0,1,0,0,0,0,1, 0,1,0,0,0,0,0,1,0,0,1,0, 1,0,0,0,0,0,0,0,1,1,0,0,};
int S[] = {
  0,0,1,1,0,0,0,1,1,1,0,0, 0,1,0,0,0,0,1,0,0,0,1,0, 1,0,0,0,0,0,1,0,0,0,0,1, 1,0,0,0,0,1,1,0,0,0,0,1, 1,0,0,0,0,1,0,0,0,0,0,1, 0,1,0,0,0,1,0,0,0,0,1,0, 0,0,1,1,1,0,0,0,1,1,0,0,};
int T[] = {
  0,0,0,0,0,0,0,0,0,0,0,1, 0,0,0,0,0,0,0,0,0,0,0,1, 0,0,0,0,0,0,0,0,0,0,0,1, 1,1,1,1,1,1,1,1,1,1,1,1, 0,0,0,0,0,0,0,0,0,0,0,1, 0,0,0,0,0,0,0,0,0,0,0,1, 0,0,0,0,0,0,0,0,0,0,0,1,};
int U[] = {
  0,0,1,1,1,1,1,1,1,1,1,1, 0,1,0,0,0,0,0,0,0,0,0,0, 1,0,0,0,0,0,0,0,0,0,0,0, 1,0,0,0,0,0,0,0,0,0,0,0, 1,0,0,0,0,0,0,0,0,0,0,0, 0,1,0,0,0,0,0,0,0,0,0,0, 0,0,1,1,1,1,1,1,1,1,1,1,};
int V[] = {
  0,0,0,0,0,0,0,1,1,1,1,1, 0,0,0,0,1,1,1,0,0,0,0,0, 0,0,1,1,0,0,0,0,0,0,0,0, 1,1,0,0,0,0,0,0,0,0,0,0, 0,0,1,1,0,0,0,0,0,0,0,0, 0,0,0,0,1,1,1,0,0,0,0,0, 0,0,0,0,0,0,0,1,1,1,1,1,};
int W[] = {
  1,1,1,1,1,1,1,1,1,1,1,1, 0,1,1,0,0,0,0,0,0,0,0,0, 0,0,0,1,1,0,0,0,0,0,0,0, 0,0,0,0,0,1,1,0,0,0,0,0, 0,0,0,1,1,0,0,0,0,0,0,0, 0,1,1,0,0,0,0,0,0,0,0,0, 1,1,1,1,1,1,1,1,1,1,1,1,};
int X[] = {
  1,1,0,0,0,0,0,0,0,0,1,1, 0,0,1,1,0,0,0,0,1,1,0,0, 0,0,0,0,1,0,0,1,0,0,0,0, 0,0,0,0,0,1,1,0,0,0,0,0, 0,0,0,0,1,0,0,1,0,0,0,0, 0,0,1,1,0,0,0,0,1,1,0,0, 1,1,0,0,0,0,0,0,0,0,1,1,};
int Y[] = {
  0,0,0,0,0,0,0,0,0,0,1,1, 0,0,0,0,0,0,0,0,1,1,0,0, 0,0,0,0,0,0,0,1,0,0,0,0, 1,1,1,1,1,1,1,0,0,0,0,0, 0,0,0,0,0,0,0,1,0,0,0,0, 0,0,0,0,0,0,0,0,1,1,0,0, 0,0,0,0,0,0,0,0,0,0,1,1,};
int Z[] = {
  1,1,1,0,0,0,0,0,0,0,0,1, 1,0,0,1,0,0,0,0,0,0,0,1, 1,0,0,0,1,0,0,0,0,0,0,1, 1,0,0,0,0,1,1,0,0,0,0,1, 1,0,0,0,0,0,0,1,0,0,0,1, 1,0,0,0,0,0,0,0,1,0,0,1, 1,0,0,0,0,0,0,0,0,1,1,1,};
int Dot[] = {
  0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0, 1,1,1,0,0,0,0,0,0,0,0,0, 1,1,1,0,0,0,0,0,0,0,0,0, 1,1,1,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,};
int Ex[] = {
  0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0, 1,1,1,0,0,1,1,1,1,1,1,1, 1,1,1,0,0,1,1,1,1,1,1,1, 1,1,1,0,0,1,1,1,1,1,1,1, 0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,};
int Qu[] = {
  0,0,0,0,0,0,0,1,1,1,0,0, 0,0,0,0,0,0,0,0,0,0,1,0, 0,0,0,0,0,0,0,0,0,0,0,1, 1,1,0,1,1,0,0,0,0,0,0,1, 0,0,0,0,0,1,0,0,0,0,0,1, 0,0,0,0,0,0,1,0,0,0,1,0, 0,0,0,0,0,0,0,1,1,1,0,0,};
int Heart[] = {
  0,0,0,0,0,0,0,1,1,1,0,0, 0,0,0,0,0,0,1,1,1,1,1,0, 0,0,0,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,0,0,0,0, 0,0,0,1,1,1,1,1,1,1,1,1, 0,0,0,0,0,0,1,1,1,1,1,0, 0,0,0,0,0,0,0,1,1,1,0,0,};
int letterpause = 30;  //Time between letters
int columntime = 15;  //Time between the parts of the letters
int buttonIn = 1;
int pressed = 0;

void setup()
{
  pinMode(2, OUTPUT);
  pinMode(3, OUTPUT);
  pinMode(4, OUTPUT);
  pinMode(5, OUTPUT);
  pinMode(6, OUTPUT);  
  pinMode(7, OUTPUT);
  pinMode(8, OUTPUT);
  pinMode(9, OUTPUT);
  pinMode(10, OUTPUT);
  pinMode(11, OUTPUT);
  pinMode(12, OUTPUT);
  pinMode(13, OUTPUT);
}

void writeletter(int letter[])  //Create a function that displays the current letter
{
  int i;
  for (i=0; i<12; i++)  //Go through the individual bits of the letter one at a time to display the first part of the letter
  {
    digitalWrite(i+2, letter[i]);  
  }
  delay(columntime);
  for (i=0; i<12; i++)
  {
    digitalWrite(i+2, letter[i+12]);    //Go through the next part of the letter, and keep going until the letter is complete
  }
  delay(columntime);
  for (i=0; i<12; i++)
  {
    digitalWrite(i+2, letter[i+24]);
  }
  delay(columntime);

  for (i=0; i<12; i++)
  {
    digitalWrite(i+2, letter[i+36]);
  }
  delay(columntime);

  for (i=0; i<12; i++)
  {
    digitalWrite(i+2, letter[i+48]);
  }
  delay(columntime);

  for (i=0; i<12; i++)
  {
    digitalWrite(i+2, letter[i+60]);
  }
  delay(columntime);

  for (i=0; i<12; i++)
  {
    digitalWrite(i+2, letter[i+72]);
  }
  delay(columntime);
  for (i=0; i<12; i++)
  {
    digitalWrite(i+2, 0);
  }
  delay(letterpause);
}

void loop(){
    writeletter(I);    //Go through the letters you want to write
    writeletter(_);
    writeletter(L);
    writeletter(O);
    writeletter(V);
    writeletter(E);
    writeletter(_);
    writeletter(A);
    writeletter(R);
    writeletter(D);
    writeletter(U);
    writeletter(I);
    writeletter(N);
    writeletter(O);
    writeletter(Ex);
    delay(100000);
 }

k2pek2 - I must be doing something wrong (Complete Newb). I can upload your code ok but nothing seems to happen except the first led stays lit.

Okay, can you tell me your current setup? i have it all being controlled from pins 2-13, with an LED and a resistor going from the digital output pin to ground. The LED's are all to be arranged in the same order as the output pins. Pictures or a description of the problem?

Also, try shortening the message. I noticed that longer messages can mess up the code (anyone know why?) and it won't run.

Also, try shortening the message. I noticed that longer messages can mess up the code (anyone know why?) and it won't run.

Ah, that was it... thanks.

Yeah I've been trying to re-code it so that it will accept longer messages, but I haven't gotten it right yet. I don't know exactly what's going on, because in theory it should work, but something funky is happening on the ATMega's side of the process. If you or anyone else can figure it out i'd be appreciative