Persistence of Vision Frisbee

The first time I saw a persistence of vision (POV) clock I thought: “Wouldn’t that be cool on the side of the frisbee?”. It is a fun weekend project to make one. Here is an action shot of the POV frisbee I made:

IMG_4897

It looks better in person – this picture is the best we could do with a Canon camera held on a level surface. The frisbee is spelling out ‘bovine aero’. Below is a picture of a test in a darkened room:

IMG_4863

This is the perfect project for Adafruit’s tiny, lightweight Arduino compatible Trinket. The total cost of the materials was around $30:

Assembly is as simple as hooking up an LED & resistor in series to each digital out pin, writing some code to blink the lights in the correct order (see below), and attaching the circuit to the frisbee. Below are some pictures taken during assembly:

IMG_20141013_142138647_HDRIMG_20141013_142156068_HDR

Some insights, if anyone else tries this:

  • I considered using a load sensor to determine the rotation rate of the frisbee (a = v^2/r). If you know the rotational speed of the frisbee, you can time the LED outputs to write more consistently spaced letters. However, it turns out the POV illusion looks OK if you use a fixed letter writing rate (I used an ‘on’ time 1 ms per vertical column of letter).
  • To mount the LEDs on the frisbee, I drilled holes in the side and covered them with electrical tape. Punching the LEDs through the tape provided a stable mount for the LEDS.
  • I used letters made up of 5×5 pixel blocks. A better POV display could use more vertically stacked LEDs, or even multicolored LEDs.

Click below to see the code I used:

int B[25] = {1,1,1,1,1, 1,0,1,0,1, 1,0,1,0,1, 0,1,0,1,0, 0,0,0,0,0};
int O[25] = {0,1,1,1,0, 1,0,0,0,1, 1,0,0,0,1, 0,1,1,1,0, 0,0,0,0,0};
int V[25] = {1,1,1,1,0, 0,0,0,1,0, 0,0,0,0,1, 0,0,0,1,0, 1,1,1,1,0};
int I[25] = {0,0,0,0,0, 1,0,0,0,1, 1,1,1,1,1, 1,0,0,0,1, 0,0,0,0,0};
int N[25] = {1,1,1,1,1, 0,1,0,0,0, 0,0,1,0,0, 0,0,0,1,0, 1,1,1,1,1};
int E[25] = {1,1,1,1,1, 1,0,1,0,1, 1,0,1,0,1, 1,0,1,0,1, 0,0,0,0,0};
int A[25] = {0,1,1,1,1, 1,0,1,0,0, 1,0,1,0,0, 0,1,1,1,1, 0,0,0,0,0};
int R[25] = {1,1,1,1,1, 1,0,1,0,0, 1,0,1,1,0, 0,1,0,1,1, 0,0,0,0,0};
int S[25] = {0,1,0,0,1, 1,0,1,0,1, 1,0,1,0,1, 1,0,0,1,0, 0,0,0,0,0};
int P[25] = {1,1,1,1,1, 1,0,1,0,0, 1,0,1,0,0, 0,1,0,0,0, 0,0,0,0,0};
int C[25] = {0,1,1,1,0, 1,0,0,0,1, 1,0,0,0,1, 1,0,0,0,1, 0,0,0,0,0};
int space[25] = {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 letter_time;
int write_time;

void setup() {
  //use pins 0-4 for output
  pinMode(0, OUTPUT);
  pinMode(1, OUTPUT);
  pinMode(2, OUTPUT);
  pinMode(3, OUTPUT);
  pinMode(4, OUTPUT);

  letter_time = 2; //delay between letters (ms)
  write_time = 1; //how long a led is activated for (ms)
}

//Write an letter to the POV display
void write_letter(int * letter) {
  //write letter, column by column
  for(int i = 0; i < 5; i++) {
    for(int j = 0; j < 5; j++) {
      digitalWrite(j, letter[j+i*5]);
    }
    delay(write_time);
  }

  //write space after letter
  for(int i = 0; i < 5; i++) {
    digitalWrite(i, 0);
  }
  delay(letter_time);
}

void loop() {
  write_letter(B);
  write_letter(O);
  write_letter(V);
  write_letter(I);
  write_letter(N);
  write_letter(E);
  write_letter(space);
  write_letter(A);
  write_letter(E);
  write_letter(R);
  write_letter(O);
  write_letter(space);
}
Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s