Make a PoV Display With ATtiny13 for $1
35224 Views, 371 Favorites, 0 Comments
Make a PoV Display With ATtiny13 for $1
I was browsing through AliExpress sometime back and this particular listing caught my attention.
5 Pcs of ATtiny13 microcontrollers for ₹124, that's like $1.5.
That's like $0.3 (₹25) per MCU. Isn't that amazing, a programmable microcontroller! for ₹25.
I googled "ATtiny13 Arduino" and yes, ATtiny13 is supported by Arduino.
AWESOME.
So I immediately placed the order.AliExpress takes a heck load of time to deliver to India.I almost forgot that I even placed the order.
After one month or so the package arrived. ATtiny13 has limited library support, so I was not able to do anything with it, other than blink an LED.
A project that I did a long time ago came to my mind as I thought of what more I could do.
It was a PoV display using ATtiny85.PoV Displays are basically a bunch of blinking LEDs with some carefully placed delay.
Both ATtiny85 and ATtiny13 have the same pinout. The total cost of the components for this project is under $1. If you are in India you can get the ATtiny Microcontroller from this link.
Supplies
- 1 x ATtiny13
- 5 x 3mm LEDs (5mm LED will also work, 3mm looks better as you can put them much closer in PCB)
- 1 x CR2032 Battery
- 1 x CR2032 Battery holder
- 1 x Slide Switch
- 1 x Prototyping PCB or My Custom PCB
You will also need a soldering Soldering Iron
What Are PoV Displays and How Do They Work?
According to Wikipedia,
The Persistence of vision is the optical illusion that occurs when visual perception of an object does not cease for some time after the rays of light proceeding from it have ceased to enter the eye.
If you look at a normal display the pixels are arranged in a matrix fashion.
But in a PoV display Pixels/LEDs are arranged as an array.
How does it display anything you may ask, that's where the Persistence of vision comes into play.
Our eyes won't be seeing different columns of LEDs, they would see what appears to be a proper image.
Convert Your Arduino Into a Programmer
You might be looking at the ATtiny13 and wondering "How the heck am I supposed to program this thing, it doesn't have any USB port like an Arduino Uno/ Nano".
Well to program this Microcontroller you need another Arduino, something like Arduino Nano or Arduino Uno.
Download and install Arduino IDE from this link.
Connect your Arduino Nano / Uno to the computer using a USB cable.
Open Tools -> Boards and Select your board (Something like Uno / Nano not ATtiny13).
Now we need to convert our Arduino into a programmer (Yeah, we can do that)
In Arduino IDE,
Open File -> Examples -> 11.ArduinoISP -> ArduinoISP
and click Upload Button.
If the upload is successful then you can use your Arduino to program other microcontrollers.
Setting Up Arduino IDE for ATtiny13
Now we need to install the hardware package for ATtiny13 on Arduino IDE as the IDE doesn't support ATtiny13 by default.
Open File -> Preferences -> Additional Boards Manager URLs
and paste this
https://mcudude.github.io/MicroCore/package_MCUdude_MicroCore_index.json
Then
Open Tools -> Board -> Boards manager.
Find MicroCore from the list and click install.
Now you will be able to select ATtiny13 from Arduino IDE
Select Tools -> Board -> MicroCore -> ATtiny13
We need to change few more options in Arduino IDE
Open Tools
and set the following values
- Board: ATtiny13
- BOD: 2.7v
- Clock: 9.6Mhz internal Osc.
- Timing: "Micros Disabled"
- Port: <Select the USB port in which arduino is connected>
- Programmer: Arduino as ISP (MicroCore)
Connecting ATtiny to Arduino
Now it's time to connect ATtiny to our Arduino.
Connect ATtiny to Arduino as follows (In ATtiny Pin 1 will be marked using a dot .)
- ATtiny13 Pin 1 to Arduino Pin 10
- ATtiny13 Pin 5 to Arduino Pin 11
- ATtiny13 Pin 6 to Arduino Pin 12
- ATtiny13 Pin 7 to Arduino Pin 13
- ATtiny13 Pin 8 to Arduino Pin 5v
- ATtiny13 Pin 4 to Arduino Pin GND (Ground)
Burning Bootloader to ATtiny13
This is a one-time setup, you DON'T have to repeat it every time you upload code to ATtiny.
Click Tools -> Burn Bootloader
This will burn the bootloader to ATtiny, now you can upload programs to ATtiny using Arduino IDE.
Uploading PoV Program to ATtiny
Open a new Sketch in Arduino.
Copy code from this link and paste it into the newly created sketch.
If you want to change the text on this line:
displayString("HELLO 123 "); // replace with your text
Based on the speed of the motor you are going to use, you might want to adjust the code, update variables DELAY_TIME and CHAR_BREAK, you might have to do some trial and errors to find out values that matches your motor.
Make sure that you Board is still selected as ATtiny13 and click upload.
Building PoV Display Circuit
The PoV display Circuit is fairly simple. You can wire up the circuit using the following circuit diagram.
You can use a Prototyping PCB to solder the circuit.
I've designed a PCB for this circuit. If you are using the PCB, then you don't have to do any wiring, just solder the components.
You can order the PCBs from here if you’d like to.
or you can download the PCB files from here and order them from your favourite fab house (I recommend PCBWay use this link and you will get a $5 coupon).
Solder everything, Add battery, Turn on the switch and attach it to something that rotates, like a mini motor or even fan(Don't forget to adjust the delay in code based on the angular velocity, this might take some trial and error).
And that's it, now you have a PoV display, you will be able to see the letters on a moving object Have fun
Code Explanation for the Curious Minds
You might be staring at the code and wondering how some random numbers can represent a character, and how we can use them to blink LEDs properly.
You might be familiar with using an array to represent characters and images. Something Like this:
int a[][5] = {
{0, 1, 1, 0, 0},
{1, 0, 0, 1, 0},
{1, 1, 1, 1, 0},
{1, 0, 0, 1, 0},
{1, 0, 0, 1, 0},
};
for (int i = 0; i < 5; i++) {
for (int j = 0; j < 5; j++) {
digitalWrite(LEDs[j], a[j][i]);
}
}
But this method will take up lots of memory, And we’ll have to use multiple loops to iterate over them.
Now, that’s not a great approach for an ATtiny13 which doesn't have much processing power.
Flagged Enums to the rescue!
Instead of representing a character using a matrix, we represent it using an array. Our PoV display has 5 rows and 5 columns, so we will use an array of length 5.
Each element in that array will tell us if we need to turn on a particular led or not.
We assign a number (enum) to each LEDs, these numbers will be powers of 2.
LED 1: 2^0 = 1
LED 2: 2^1 = 2
LED 3: 2^2 = 4
LED 4: 2^3 = 8
LED 5: 2^4 = 16
These numbers have a speciality, no matter what the combination, you will get a unique number if you add them.
For Eg: If we add 2, 4 and 8 we will get 14, no other combination of these numbers will generate 14.
If an LED is off, we represent it using 0.
Let's look at how we can represent the letter "A". (Refer image)
In the first column, we have to turn off LED1 and turn on all other ones. So, we can represent it using
0 (off) + 2 + 4 + 8 + 16 = 30.
Elements in the array will be:
Column 1: 0 + 2 + 4 + 8 + 16 = 30
Column 2: 1 + 0 + 4 + 0 + 0 = 5
Column 3: 1 + 0 + 4 + 0 + 0 = 5
Column 4: 0 + 2 + 4 + 8 + 16 = 30
Column 5: 0 + 0 + 0 + 0 + 0 = 0 (All LEDs are off)
It’s simple, You do a bitwise AND operation with the number and the enum for the LED, if the results are enum then we need to turn on the corresponding LED.
Let’s consider number 30
Operation Result LED Status
30 & 1 == 1 false turn off LED1
30 & 2 == 2 true turn on LED2
30 & 4 == 4 true turn on LED3
30 & 4 == 8 true turn on LED4
30 & 16 == 16 true turn on LED5
This concept is commonly known as flagged enums.
You can add more than just alphabets and numbers.
Manually generating these arrays is hard. so I made not one but two apps for this.
The first one is written in Preact and it was specifically made for this project, it supports up to 5 LEDs.
The second one is written in Angular and it can support any number of LEDs,
You can use these apps to generate code for other PoV projects as well
Just generate arrays using these apps and add that code to the array in the sketch.