persistence of vision (POV) Code?

Hello guys and girls, am building a 8 led POV, but Im a little stuck when it comes to the programming.

any chance someone can point me in the right direction for a idiots guide?
(this is my first project with the Arduino so please go slow on me! :-*)

Really, no ones going to help a girl out......?

Im I even asking in the right section?

Well, saying you're "a little stuck" isn't much of a clue as to how much you understand programming in general. Have you done the usual tutorials, such as Blink and AnalogInput? Do you know how to hook up multiple LEDs to multiple outputs? Do you do any programming on non-Arduino devices or computers? Do you understand how numbers are encoded into binary bits? Have you seen the non-Arduino POV kits, such as those that LadyAda sells, so you're familiar with the concepts?

For POV, the general idea is to store your "image" into a sequence of columns, and each column should be stored in such a way as to efficiently send them to a column of LEDs all at once. Finally, the main loop of your program should just start pushing out your image, one column at a time, through the whole pattern.

........    B00000000    0x00
.****...    B01111000    0x78
...*.*..    B00010100    0x14
...*..*. -> B00010010    0x12
...*.*..    B00010100    0x14
.****...    B01111000    0x78
........    B00000000    0x00

Can you see the "A"? Do you see the "A" in the binary bits also?

Well, saying you're "a little stuck" isn't much of a clue as to how much you understand programming in general. Have you done the usual tutorials, such as Blink and AnalogInput?

Yes, i have done a few of them like the blink and the "Knight Rider" loop

]Do you know how to hook up multiple LEDs to multiple outputs?

Yes i believe so....i designed this schematic based on the RBB and "Knight Rider" to work as a stand alone POV (but it may well be very floored)

Do you do any programming on non-Arduino devices or computers?

only HTML

Do you understand how numbers are encoded into binary bits?

is this BCD? as in:
0=0000
1=0001
2=0010
3=0011
4=0100
5=0101

if so I am aware of the theory, but have have 0 experience with application.

]Have you seen the non-Arduino POV kits, such as those that LadyAda sells, so you're familiar with the concepts?

Yes im familiar with the concept and electronics, its just the issue of the code im totally out of my depth with.

For POV, the general idea is to store your "image" into a sequence of columns, and each column should be stored in such a way as to efficiently send them to a column of LEDs all at once. Finally, the main loop of your program should just start pushing out your image, one column at a time, through the whole pattern.

........    B00000000    0x00
.****...    B01111000    0x78
...*.*..    B00010100    0x14
...*..*. -> B00010010    0x12
...*.*..     B00010100    0x14
.****...    B01111000    0x78
........    B00000000    0x00

Can you see the "A"? Do you see the "A" in the binary bits also?

:slight_smile: yes i see the A :)........so B would be

. . . . . . . . B00000000
******** B11111111
*. . . *. . * B10001001
*. . . *. . * B10001001
*. . . *. . * B10001001
. *** . **. B01110110
. . . . . . . . B00000000

but what are the 0x00, 0x78, 0x14 ect. and how would the above code for A or B fit into the sketch, and is it possible to code a full alphabet onto the sketch, but have a command line that you can just quickly adjust to tell it what word to spell?

thank you :slight_smile:

I found this font (stored in font.h) in the internet, it uses 7 leds.... after i finished mine half.... arg

const byte font[][5] = {
            {0x00,0x00,0x00,0x00,0x00},   //   0x20 32
            {0x00,0x00,0x6f,0x00,0x00},   // ! 0x21 33
            {0x00,0x07,0x00,0x07,0x00},   // " 0x22 34
            {0x14,0x7f,0x14,0x7f,0x14},   // # 0x23 35
            {0x00,0x07,0x04,0x1e,0x00},   // $ 0x24 36
            {0x23,0x13,0x08,0x64,0x62},   // % 0x25 37
            {0x36,0x49,0x56,0x20,0x50},   // & 0x26 38
            {0x00,0x00,0x07,0x00,0x00},   // ' 0x27 39
            {0x00,0x1c,0x22,0x41,0x00},   // ( 0x28 40
            {0x00,0x41,0x22,0x1c,0x00},   // ) 0x29 41
            {0x14,0x08,0x3e,0x08,0x14},   // * 0x2a 42
            {0x08,0x08,0x3e,0x08,0x08},   // + 0x2b 43
            {0x00,0x50,0x30,0x00,0x00},   // , 0x2c 44
            {0x08,0x08,0x08,0x08,0x08},   // - 0x2d 45
            {0x00,0x60,0x60,0x00,0x00},   // . 0x2e 46
            {0x20,0x10,0x08,0x04,0x02},   // / 0x2f 47
            {0x3e,0x51,0x49,0x45,0x3e},   // 0 0x30 48
            {0x00,0x42,0x7f,0x40,0x00},   // 1 0x31 49
            {0x42,0x61,0x51,0x49,0x46},   // 2 0x32 50
            {0x21,0x41,0x45,0x4b,0x31},   // 3 0x33 51
            {0x18,0x14,0x12,0x7f,0x10},   // 4 0x34 52
            {0x27,0x45,0x45,0x45,0x39},   // 5 0x35 53
            {0x3c,0x4a,0x49,0x49,0x30},   // 6 0x36 54
            {0x01,0x71,0x09,0x05,0x03},   // 7 0x37 55
            {0x36,0x49,0x49,0x49,0x36},   // 8 0x38 56
            {0x06,0x49,0x49,0x29,0x1e},   // 9 0x39 57
            {0x00,0x36,0x36,0x00,0x00},   // : 0x3a 58
            {0x00,0x56,0x36,0x00,0x00},   // ; 0x3b 59
            {0x08,0x14,0x22,0x41,0x00},   // < 0x3c 60
            {0x14,0x14,0x14,0x14,0x14},   // = 0x3d 61
            {0x00,0x41,0x22,0x14,0x08},   // > 0x3e 62
            {0x02,0x01,0x51,0x09,0x06},   // ? 0x3f 63
            {0x3e,0x41,0x5d,0x49,0x4e},   // @ 0x40 64
            {0x7e,0x09,0x09,0x09,0x7e},   // A 0x41 65
            {0x7f,0x49,0x49,0x49,0x36},   // B 0x42 66
            {0x3e,0x41,0x41,0x41,0x22},   // C 0x43 67
            {0x7f,0x41,0x41,0x41,0x3e},   // D 0x44 68
            {0x7f,0x49,0x49,0x49,0x41},   // E 0x45 69
            {0x7f,0x09,0x09,0x09,0x01},   // F 0x46 70
            {0x3e,0x41,0x49,0x49,0x7a},   // G 0x47 71
            {0x7f,0x08,0x08,0x08,0x7f},   // H 0x48 72
            {0x00,0x41,0x7f,0x41,0x00},   // I 0x49 73
            {0x20,0x40,0x41,0x3f,0x01},   // J 0x4a 74
            {0x7f,0x08,0x14,0x22,0x41},   // K 0x4b 75
            {0x7f,0x40,0x40,0x40,0x40},   // L 0x4c 76
            {0x7f,0x02,0x0c,0x02,0x7f},   // M 0x4d 77
            {0x7f,0x04,0x08,0x10,0x7f},   // N 0x4e 78
            {0x3e,0x41,0x41,0x41,0x3e},   // O 0x4f 79
            {0x7f,0x09,0x09,0x09,0x06},   // P 0x50 80
            {0x3e,0x41,0x51,0x21,0x5e},   // Q 0x51 81
            {0x7f,0x09,0x19,0x29,0x46},   // R 0x52 82
            {0x46,0x49,0x49,0x49,0x31},   // S 0x53 83
            {0x01,0x01,0x7f,0x01,0x01},   // T 0x54 84
            {0x3f,0x40,0x40,0x40,0x3f},   // U 0x55 85
            {0x0f,0x30,0x40,0x30,0x0f},   // V 0x56 86
            {0x3f,0x40,0x30,0x40,0x3f},   // W 0x57 87
            {0x63,0x14,0x08,0x14,0x63},   // X 0x58 88
            {0x07,0x08,0x70,0x08,0x07},   // Y 0x59 89
            {0x61,0x51,0x49,0x45,0x43},   // Z 0x5a 90
            {0x3c,0x4a,0x49,0x29,0x1e},   // [ 0x5b 91
            {0x02,0x04,0x08,0x10,0x20},   // \ 0x5c 92
            {0x00,0x41,0x7f,0x00,0x00},   // ] 0x5d 93
            {0x04,0x02,0x01,0x02,0x04},   // ^ 0x5e 94
            {0x40,0x40,0x40,0x40,0x40},   // _ 0x5f 95
            {0x00,0x00,0x03,0x04,0x00},   // ` 0x60 96
            {0x20,0x54,0x54,0x54,0x78},   // a 0x61 97
            {0x7f,0x48,0x44,0x44,0x38},   // b 0x62 98
            {0x38,0x44,0x44,0x44,0x20},   // c 0x63 99
            {0x38,0x44,0x44,0x48,0x7f},   // d 0x64 100
            {0x38,0x54,0x54,0x54,0x18},   // e 0x65 101
            {0x08,0x7e,0x09,0x01,0x02},   // f 0x66 102
            {0x0c,0x52,0x52,0x52,0x3e},   // g 0x67 103
            {0x7f,0x08,0x04,0x04,0x78},   // h 0x68 104
            {0x00,0x44,0x7d,0x40,0x00},   // i 0x69 105
            {0x20,0x40,0x44,0x3d,0x00},   // j 0x6a 106
            {0x00,0x7f,0x10,0x28,0x44},   // k 0x6b 107
            {0x00,0x41,0x7f,0x40,0x00},   // l 0x6c 108
            {0x7c,0x04,0x18,0x04,0x78},   // m 0x6d 109
            {0x7c,0x08,0x04,0x04,0x78},   // n 0x6e 110
            {0x38,0x44,0x44,0x44,0x38},   // o 0x6f 111
            {0x7c,0x14,0x14,0x14,0x08},   // p 0x70 112
            {0x08,0x14,0x14,0x18,0x7c},   // q 0x71 113
            {0x7c,0x08,0x04,0x04,0x08},   // r 0x72 114
            {0x48,0x54,0x54,0x54,0x20},   // s 0x73 115
            {0x04,0x3f,0x44,0x40,0x20},   // t 0x74 116
            {0x3c,0x40,0x40,0x20,0x7c},   // u 0x75 117
            {0x1c,0x20,0x40,0x20,0x1c},   // v 0x76 118
            {0x3c,0x40,0x30,0x40,0x3c},   // w 0x77 119
            {0x44,0x28,0x10,0x28,0x44},   // x 0x78 120
            {0x0c,0x50,0x50,0x50,0x3c},   // y 0x79 121
            {0x44,0x64,0x54,0x4c,0x44},   // z 0x7a 122
            {0x00,0x08,0x36,0x41,0x41},   // { 0x7b 123
            {0x00,0x00,0x7f,0x00,0x00},   // | 0x7c 124
            {0x41,0x41,0x36,0x08,0x00},   // } 0x7d 125
            {0x04,0x02,0x04,0x08,0x04},   // ~ 0x7e 126
      };

this is my complete code, hope that helps.... im a noob too, so the code is not very clean.... i also have another version where i use bitwise operatosr and the PORTs instead of digitalWrite and an interrupt to start the writing instead of the loop...

#undef int() // fixes a bug with the stdio.h
#include <stdio.h> // gives access to function sprintf
#include "font.h";

//constant definition
#define charHeight   7
#define charWidth    5
#define colDelay   250
#define debounce    20
#define bufferSize  50
#define ledPin      13
#define inPin        2

//const int povPins[] = {2,3,4,5,6,7,8};
const int povPins[] = {9,8,7,6,5,4,3};



//variable definition
int switchValue               = 0;
int revolutions               = 0;
long lastCycleStart           = 0;
char stringBuffer[bufferSize] = "I am a very long text! Hopefully I will fit in?!";


void setup() 
{
  for ( int n = 0; n < charHeight; n++ )
  {
    pinMode(povPins[n], OUTPUT);
  }
  
  pinMode(ledPin, OUTPUT);
  pinMode(inPin, INPUT);
} 


// sets the 7 LEDs
void setColumn(byte data)
{
  int pinIndex = 0;
  for (byte mask = B00000001; mask<128; mask = mask << 1)
  {
    digitalWrite(povPins[pinIndex], mask & data);   
    pinIndex++;
  }
}


// writes a letter to POV using standart letter width
void writeLetter(byte letter[])
{
  writeLetter(letter, charWidth);
}

// writes a letter to POV using custom letter width
void writeLetter(byte letter[], int length)
{
  for (int n = 0; n < length; ++n)
  {
    setColumn(letter[n]);
    delayMicroseconds(colDelay);
  }
  setColumn(BLANK);
  delayMicroseconds(colDelay);
}

void writeASCII(char aCharacter)
{  
  int characterFontIndex = getCharIndex(aCharacter);
  for (int n = 0; n < charWidth; ++n)
  {
    setColumn(font[characterFontIndex][n]);
    delayMicroseconds(colDelay);
  }
  setColumn(BLANK);
  delayMicroseconds(colDelay);  
}


//gets the index of our pseudo ASCII table (ascii-32)
int getCharIndex(char ch)
{
    if (ch < 32 || ch > 126) ch = 32;
    return (ch - 32);
}


//prints the stringBuffer  
void printStringBuffer()
{
  for ( int n = 0; n < bufferSize; ++n )
  {
    writeASCII( stringBuffer[n] );
  }
}

// main LOOP
void loop() 
{
  
  switchValue = digitalRead(inPin);  // read input value of the magnetic switch
  
  if (switchValue == HIGH) // check if the input is HIGH (button released)
  { 
    //this is spare time
    digitalWrite(ledPin, LOW);  // turn LED OFF    
  } 
  
  if (switchValue == LOW && millis() - lastCycleStart > debounce) 
  {
    lastCycleStart = millis();
    revolutions++;    
    digitalWrite(ledPin, HIGH);  // turn LED ON
    //sprintf(stringBuffer, "%d", revolutions);    
    printStringBuffer();
  }  
  
}

btw, i bought a 5 euro bike computer and used the magnetic switch to find out when a new revolution starts.

but what are the 0x00, 0x78, 0x14 ect.

Take a number like 17 decimal.

The B00010001 notation is how you specify the same numeric value in binary to the compiler.

The 0x11 notation is how you specify the same numeric value in hexadecimal to the compiler. Each hexadecimal digit corresponds to four binary digits, so it's a little more compact. With practice, one can see the bits when shown the hexadecimal value... it's like the scene in the Matrix where the operator watches the plain green digits to know what's going on. :wink:

Is there any good chips(LED Drivers) to use for POV to control 64 LEDs? I would like to get 254 Shades of brightness.

4 TLC5940 chips can run 64 leds with 4096 levels.

There are some POV samples for this setup as well.

Have you seen this?
http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1218174457

Good luck

I've so far never used TLC5940s, and if memory servers wasn't those a bit hard to come by? (Or maybe there is another IC I'm thinking about).

Based on the existing schematics, I'd recommend taking a look at this really nice and simple POV project: http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1277270646
In fact it seems to be almost directly applicable to peps's schematics, only thing missing is a sensor wired to analogue input 5, assuming a rotating POV. Of course there is no PWM there (but that's possible to implement in software if wanted).