Introduction: Arduino + LEDs + Fan = POV "APPLAUSE" Sign
I saw these POV(Persistence of Vision) devices on other Instructables and thought I would like to make one and I have always wanted my own "APPLAUSE" sign. Next improvement will be to make it go on whenever I enter the room. :) Maybe have it say, "And here's Charlie !" But that is for another time.
So I got a fan at a garage sale, did some reading , found some code and below is a video of my machine in action.
I started with nice code from an Instructable by Scott Mitchell - "Arduino Bike POV" but what I ended up with is his code greatly parred down. I could not get it to work at first and so I keep changing the code . Turned out my problem had nothing to do with the code. So I am going to go back to his code and try again as his is much more generic and would work more easily with different phrases. But that is for later also.
The video below shows the POV in action. It does not seem as broken or disconnected in real life as it does on the video.
Step 1: Get Stuff
Items used in this project:
small fan - garage sale - 2.00
misc lumber - my basement - 0.00
a length of plastic 15 by 2.5 inches - my basement - 0.00
an Arduino - I use a Ardweeny from SolarBotics - about 10.00
7 red LEDs - already had - 1.00
7 - 330 ohm resistors - 3.00
Halls Sensor - I got from Adafruit - US5881LUA - 2.00
1 10k resistor to be used with the Halls sensor - 1.00
2 magnets from local hobby store - 1.00
also will need : wire, 9v battery , screws, Loctite 5 min epoxy, small PCB from Radio Shack
Step 2: Begin Assembly
1. Cut a small - 3 by 5 - piece of 1/4 inch plywood and epoxied to the fan hub . Right now the epoxy is the only thing holding the LED assembly to the fan. Perhaps some wire ties for safety would be good. I think I will add them later.
2. I cut a 15 by 2.5 inch piece of plastic from some stock I had. Sheets of plastic can be had at Home Depot. I just guessed at the size and it turned out to be pretty good.
3. Drill 7 holes in one end about 3/4 of an inch apart for the LEDs. I found a drill size that allows the LEDs to be pressed into the holes quite tightly. If they had not fit nicely, I would have used a dab of hot glue to hold in place.
4. Insert the 7 LEDs into the holes.
5. Attach the plastic to the 3 by 5 plywood with small wood screws.
Step 3: Finish the Fan Holder
This will depend of the fan you use. I cut a notch out of a piece of 1 by 6 and was able to insert the back of the fan into the notch and then used wire tie to secure the fan to the board. I needed to raise the whole unit so I used a couple of 1 by 3 s to bring the fan up to where it would not hit the base board. I added a piece of plywood to the back so the effect could be better seen. I then painted everything black.
Step 4: Ardweeny & LEDS
The Ardweeny from Solarbotics comes in a kit and it requires about 30 minutes to solder the pieces together. It is intended to be used on a breadboard and after I have bread boarded the circuit, I solder it to a small piece of PCB board which I can in turn attach to the plywood . The Ardweeny will spin along with the LEDs.
After the Ardweeny is constructed, it is time to wire up the LEDs. I used a bare copper wire as a common ground wire. Each of the short wires from the LEDs is soldered to the copper wire and then the copper wire is connected to a ground on the Ardweeny. From the longer, positive leg, of the LED attach a wire to the Ardweeny and include a 330 ohm resistor in the circuit.
I connected the LEDs to pins 1,2,3,4,5,6,7 with the outer most LED being connected to pin 1.
After all connections are made, attach the Ardweeny to the plywood. I used a small screw thru the PCB.
Step 5: Halls Sensor & Battery
Hall Sensor:
Attach the Halls Sensor to the end of the plastic . I first soldered the sensor to a small piece of PCB and then attached the PCB to the plastic with a small screw.
To connect the sensor I used the following information which I got at Adafruit: "Runs at 3.5V up to 24V. To use connect power to pin 1 (all the way to the left), ground to pin 2 (middle) and then a 10K pull up resistor from pin 3 to power. Then listen on pin 3, when the south pole of a magnet is near the front of the sensor, pin 3 will go down to 0V. Otherwise it will stay at whatever the pullup resistor is connected to. Nothing occurs if a magnet's north pole is nearby (unipolar)."
Magnet for the sensor:
I attached a small magnet to the end of a dowel and attached the dowel to the fan support. I did this on both sides of the fan. It is important that one of the magnets has its south side facing out and the other magnet has its north side out.
idea: This sensor is a latch type so it is either a 1 or a 0. When the spin begins, the first magnet will turn the LEDS on and when it gets to the other magnet, it will turn them off. Of course this is in concert with the software.
Purple wire goes to analog pin 0, black to ground and red to A+pin (5 volt output) .
Battery:
The 9V battery should be placed where it will act as a counter balance for the spinning plastic. If the plastic is not balanced pretty good, it will shake the whole fan when it reaches speed. I used a combination of rubber band and wire ties to hold it in place but still can get it out if it needs replacement
Wire the positive and negative wires from the battery to the appropriate pins. I included a switch so I can turn the Ardweeny off. The switch is attached to the plywood with double backed tape.
Step 6: The Code
A search for POV projects found code for a POV Bike project.
Below is what I used but it is a far cry from the original. The original is much more comprehensive and polished but I did start with his code and should give credit to him.
Also the sketch includes a font.h file which I found after searching the internet. I am not sure it was the font.h that was a part of the original. I have included mine below..
// Code for the Arduino Bike POV project
// Arduino Bike POV
//
// by Scott Mitchell
// www.openobject.org
// Open Source Urbanism
//
// Copyright (C) 2008 Scott Mitchell 12-10-2008
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
//============================================================
// 6/2011 heavily modified by c. Dubois for my POV project
// Hall sensor is a switch so I used different code for it
// also used a font.h that I found
// ------------------------------------------------------------
// defining the alphabet
#include "font.h"
// define the Arduino LED pins in use
const int LEDpins[] = {
1,2,3,4,5,6,7};
// number of LEDs
const int charHeight = sizeof(LEDpins);
const int charWidth = 5;
// sensor setup
const int sensorPIN = 0; // define the Arduino sensor pin
// boolean sensorFlag = false; // stores sensor state
int sensVal; // variable to store the value coming from the sensor
const char textString[] = "APPLAUSE";
void setup()
{
pinMode(13, OUTPUT);
pinMode(1 , OUTPUT);
pinMode(2, OUTPUT);
pinMode(3, OUTPUT);
pinMode(4, OUTPUT);
pinMode(5, OUTPUT);
pinMode(6, OUTPUT);
pinMode(7, OUTPUT);
// Serial.begin(9600);
}
void loop()
{
// turn on Led for a circle in middle and proof that arduino is powered
digitalWrite(13, HIGH); // set the LED on
sensVal = analogRead(sensorPIN); // read the Hall Effect Sensor
// Serial.println(sensVal);
// delay(500 );
// had difficulty here
// since it is a switch hall switch probably shoiuld just do digital read
if (sensVal != 1023) {
// printing every letter of the textString
for (int k=0; k<sizeof(textString); k++){
printLetter(textString[k]);
}
}
}
void printLetter(char ch)
{
// make sure the character is within the alphabet bounds (defined by the font.h file)
// if it's not, make it a blank character
if (ch < 32 || ch > 126){
ch = 32;
}
// subtract the space character (converts the ASCII number to the font index number)
ch -= 32;
// step through each byte of the character array
for (int i=0; i<charWidth; i++) {
byte b = font[ch][i];
// bit shift through the byte and output it to the pin
for (int j=0; j<charHeight; j++) {
digitalWrite(LEDpins[j], !!(b & (1 << j)));
}
// space between columns
delayMicroseconds(900);
}
//clear the LEDs
digitalWrite(1 , LOW); // set the LED on
digitalWrite(2 , LOW); // set the LED on
digitalWrite(3 , LOW); // set the LED on
digitalWrite(4 , LOW); // set the LED on
digitalWrite(5 ,LOW); // set the LED on
digitalWrite(6 , LOW); // set the LED on
digitalWrite(7 , LOW); // set the LED on
// space between letters
delayMicroseconds(2500);
}
--------------------------------------
----------------------------------------
///============================================================
// Arduino Bike POV
// font.h
//
// by Scott Mitchell
// www.openobject.org
// Open Source Urbanism
//
// Copyright (C) 2008 Scott Mitchell 12-10-2008
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// A copy of the GNU General Public License
// can be found at <http://www.gnu.org/licenses/>.
//
// B4.1
// Last Modified: October 13, 2008
//============================================================
// defining the alphabet
// ascii 7x5 side-feeding characters for led modules
// addapted from http://www.sxlist.com/TECHREF/datafile/charset/8x6.htm
//const byte font[][5] = {
const unsigned char font[95][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
};
/*
Creative Commons Attribution-Noncommercial-Share Alike 2.5 Australia License
This page was last modified 14:41, 11 January 2009. This page has been accessed 1,477 times.
Content is available under Creative Commons Attribution-Noncommercial-Share Alike 2.5 Australia License.
About Open Source Urbanism
Disclaimers
Powered by MediaWiki
*/

Finalist in the
LED Contest

Participated in the
Microcontroller Contest

Participated in the
Make It Move Challenge
40 Comments
6 years ago
I am getting error while running the code stating
"exit status 1
Error compiling for board Arduino Nano"
What shall I do?
7 years ago
do you have a inverse of the font.h? if do please provide my motor is AC i cant change the movement please prodive
7 years ago
this took u so much work typing in the code it's not funny: lol:/great job
7 years ago
where can i find the schematic diagram of this?
Reply 7 years ago
you'll find this useful
8 years ago on Introduction
9 years ago on Introduction
Really like this project and ive been trying to make one of own. I bought a 3144 Hall Sensor, i was able to run a different program that works with this sensor but when i run your program the hall sensor doesnt seem to want to work.
int val = 0; // This holds the read value.
void setup()
{
pinMode(12, INPUT); // Read the input on pin 2
pinMode(2, OUTPUT); // I used pin 13 since it has an LED on the UNO built-in.
Serial.begin(9600); // I also wanted to confirm the value I read.
}
void loop()
{
val = digitalRead( 12 ); // Go read the pin.
Serial.println(val); // just to see on the serial monitor what I read.
if ( val == HIGH )
digitalWrite ( 2, HIGH ); // Turn on the LED when the value is high.
else
digitalWrite ( 2, LOW ); // Turn off the LED when the value is low.
}
This is the program that works with my hall sensor. Ive tried modifying your program to get it to work but with no luck. Any clue what i can do to get your code to work?
Thank you!
9 years ago on Introduction
i have had tried the same but i did using plywood at the center
& then using pcb bilaterally with one side of pcb with uc &
other with leds & the battery & balanced the weight properly.
But as it started the fan started wobbling & making loud sound. how
do i overcome this didn't u face this?
well done project.
Reply 9 years ago on Introduction
to some extent, I did have wobbly fan but after moving the battery around several times, I did find a place where it was pretty well balanced.
10 years ago on Introduction
As you stated, the sensor is of a latch type, so does it mean the south pole is putting pin 3 to 0, and the north pole is used to restore its output?
i am planning to make one, in which the text would cover all of the circle. Is is possible by removing one magnet, or do i need a different hall sensor?
Reply 10 years ago on Introduction
in this project i used 2 magnets as I wanted the text to be in the upper half of the circle only so one magnet was the starting point and the next was the ending point.
i have used a reed switch when i want to use the whole circle. the reed switch is just a momentary switch which is closed by the magnet when it comes around. so the message will always start at the same spot. by adding blankspaces before and after the message , you can get it centered.
hope that helps
11 years ago on Introduction
I am trying to find a fan that will have some fairly strong wind generated when hooked to Arduino Uno. I bought a computer cooling fan, but it did not produce much wind. Need more powerful fan. Anyone have suggestions? The fan should be able to blow a sheet of paper off a table (for example). Thanks!
Reply 11 years ago on Introduction
I have a project where I use an arduino and a motor controller shield along with a DC motor that has a propeller attached. the DC motor was gotten at a local hobby shop and it was originally meant to fly RC airplanes. It is pretty powerful and it blows a lot of wind. Perhaps that would work for you.
11 years ago on Introduction
I am trying to find help with the following error I receive when I attempt to load the program onto my Uno...
byte b = font[ch][i]; "font" nt declared in this scope
fanfk2.cpp: In function
'void printLetter(char)': fanfk2:103: error: 'font' was not declared in this scope
fanfk2.cpp: At global scope: font:32: error: redefinition of 'const unsigned char font [95][5]'
I appreciate any help to this "noobie"
Reply 11 years ago on Introduction
what I suspect may be wrong is the following:
Your arduino sketch should consists of 2 pieces each in its own tab
1. the arduino code from this instructable but only from the begining of the code to the the line "delayMicroseconds(51000);"
2. then thewre is a drop down menu which you access by clicking the little arrow on the upper right of the shetch (just under the serial monitor icon) . select "new tab" and name it font.h. then copy and paste the remainder of the code into that tab.
hard to explain but I hope that helps
Reply 11 years ago on Introduction
What would you code to hve the fan display other words?
e.g. it would say "applause" for 5 seconnds, then display "winner" 5 seconds and so on...
Thanks!
Reply 11 years ago on Introduction
I did a POV which had 4 different phrases. Perhaps you can modify the code to your needs
https://www.instructables.com/id/Simple-POV-wArdweeny-Persistence-of-Vision/
Reply 11 years ago on Introduction
I have the program loaded and working, however, it seems the letters are too narrow. How does the width=5 command work? Is that the determining factor for the letter width?
Also, you said you didn't use a sensor. I don't have one either, but perhaps my fan runs at a different speed and my letters spin around in a circle. Where in the code can I make adjustments to play around with this?
Thanks,...again
Gary
Reply 11 years ago on Introduction
hello,
the width = 5 refers to the font.h file.
when you look at the font.h file you see that each letter is a matrix of 5 unigue pieces. each piece will light the 7 leds in a pattern that when done quickly and in the proper sequence will produce the letter required.
worddelay will define the blank space between each word so you can play with that to get more or fewer words in the circle
delayMicroseconds(500); this effects the time between 2 columns of leds
delayMicroseconds(2800); this effects the time between 2 different letters
You will need to adjust the above 2 based on the rpms of your fan. just trial and error
hope that helps
Reply 11 years ago on Introduction
Thanks for the help. I have played with the numbers and just can't seem to get it right. Still moving too fast and the letters are not really clear.
I was curious if adjusting the variable here
var = 0;
while(var < 95){
// do something repetitive 120 times
would make a difference.
Gary