Introduction: Programmable POV Fidget Spinner

Fidget spinners are fun, and you can find one at about any check-out counter for just a few bucks these days, but what if you could build your own? And it had LEDs? And you could program it to say or show whatever you wanted? If that sounds geeky cool, THIS IS THE PROJECT FOR YOU.

I've always been interested in using blinking LEDs to get kids interested in programming. The most simple project with an Arduino microcontroller is to blink an LED on and off. Then you get them to see how fast an LED can blink before it looks like it is on continuously (about 12 millisecond intervals). Then you shake the LED back and forth and you can see it blink again! This phenomena is call "persistence of vision" (POV) and is how this project works. It can lead to discussions of both how the eye works and how incredibly fast computers are.

This project uses a programmable 8-bit microcontroller, eight LEDs, and a coin cell. It spins using a standard skateboard bearing, and uses a Hall-effect sensor and a magnet to determine rotation. It is made using beginner-friendly through-hole parts and can be programmed using the Arduino programming environment.

Enough talking, let's get making . . .

Step 1: Gather the Parts, Tools, and Supplies

It is always frustrating to get half-way through a build and find you are missing something. Here is what you'll need:

A kit for this project is available on Tindie.com (minus the battery). Purchasing the kit will save you the time and expense of ordering from several different vendors and avoid the minimum PCB order premium. Also, programming an Attiny is not trivial, and if you buy the kit, it will already be pre-programmed. You will also be helping me develop and share other projects in my workshops!

Attachments

Step 2: Resistance Is Essential.

We are going to assume you have some kit-building experience. If you need some help soldering, head over to www.sparkfun.com/tutorials/213 to brush up or watch the Geek Girl explain it at

I like starting with the resistor because a) they are relatively heat resistant while you are getting into your soldering groove and the iron is coming up to temp, b) they have no polarity, so orientation is not critical, and c) they are the lowest component on the board so sit tight when soldering.

There are eight 330-ohm current limiting resistors, one for each of the LEDs. You can do one at a time, or all eight at once. Bend the leads, insert them in the positions marked "330", and solder the leads in place. Clip them flush with the cutters.

Step 3: Let There Be Light

Now that you've got your soldering groove going, it is time to do the light emitting diodes, which are both heat sensitive and have a polarity. The long leg of the LED is the anode, or the positive (+) lead. It goes in the square pad, or the one marked "+" (photo 1). Solder one lead in and then check that the LED is seated correctly (photo 2). If not, hold the iron to the solder join and press the LED until it seats correctly. This gets much harder to do if both leads are soldered. Once you are satisfied, solder the other lead in place.

You can solder the LED one at a time, or all eight at once. Trim the leads flush.

Note: The LEDs are a tight fit. You may need to file the edges of one or two to get them to seat flat and in a line

Step 4: Code?

Note: If you have a "Rev. 0.0" board, see Step 13 for information about correctly hooking up to program an installed chip.

Yes, this project needs some code. And, if you were paying attention, in Step 1 I told you that programming an Attiny was not trivial. I use the Arduino, it's programming environment, and my AVR programmer. If you buy a kit from me, it will already be programmed, and you can skip this step!

The chip can be programmed before soldering in place (photo 2), or after it has been soldered in place using the ISP header on the bottom of the PCB (photo 3). In either case, the programming is as follows:

Attachments

Step 5: Brains

This project is powered by my favorite 8-bit microcontroller, the ATMEL Attiny84. It has more than enough I/O to handle all the LEDs and the other inputs (Hall sensor, button) without having to do anything tricky.

The orientation of a DIP ("dual inline package") chip is usually indicated either by a hole adjacent to pin one, or a divot on the end of the chip containing pin one, as is the case here. Align the chip with the symbol on the PCB and insert the chip. Solder one pin on opposite sides, and check that both the chip is flat against the PCB and that the orientation is correct. It gets really hard to fix after this. Trust me on this.

Once you are assured it is in correctly, solder the remaining pins and then cut them flush.

While we are here, solder in your 0.1 uF capacitor. It doesn't have a polarity, and is used to filter transients in the power caused by blinking the LEDs.

Step 6: Power

This project is powered by a 3-volt lithium battery. The Attiny needs only 1.8 volts to run, so a coin cell is perfect.

Orient the holder so that the opening is away from the switch. Like the chip, solder one pin on each side and then check that it is fully seated and in the correct orientation.

Solder the remaining leads and then cut them flush.

Step 7: Button and Switch

We need an input to switch modes, so we have a tactile button attached to an input on the microcontroller. Insert the legs into the four pad and push firmly to seat. Solder the legs and trim them flush.

We also want to turn the power off to save the battery, so I've added a single-pole, single-throw switch to control power. Solder the center lead in position and then verify it is seated. Solder the remaining leads and cut them flush.

Step 8: Spin on This

Fidget spinners are usually based on 608ZZ skateboard bearing which has an outer diameter of 22 millimeters. To make this work with a circuit board, I've added a pad that is just slightly larger than 22 mm, and we will solder the bearing into the pad.

To make it spin on a flat plane, I use coins to hold the board level while it is soldered in place. This will take significantly more heat than normal soldering, so raise the temperature on your iron if possible, and hold the iron against both the pad and bearing case until the solder flows on both. Create several solder joins on both side.

Note: If the bearing has shield and grease, I usually remove the shields and degrease them so they spin longer.

Step 9: Check It Out

Without the magnetic sensor, we can still check the LEDs out:

Insert a battery with the positive side outward.

Switch the spinner on and then press the button until all (hopefully) the LEDs are on (see the video).

Spin the spinner and see the pattern.

If an LED does not light, it may be installed backward, or have been heat-damage. Un-solder it and put a new one in.

Step 10: Where Are We?

In order to show messages instead of just patterns, we need to know the position of the spinner in relation to the circle. We will use a Hall-effect sensor and a magnet. This is similar to how combustion engines know when to fire the spark to get the most power. Orientation and alignment of both the sensor and magnet are critical for this to work.

With the cap in place for reference, insert the sensor with the face (with the markings on it) toward the bearing (photo 1). Solder it in place.

The sensor I select is triggered by the north pole of a magnetic field, so you will need to figure out the orientation of the magnet. The best way to do this is to set a mode other than the pattern from the previous step and then find the side of the magnet that starts the LEDs blinking (see video 1). Glue the magnet with the side that worked facing outward. Double check your work (video 2).

Step 11: Operations

With your magnet and sensor in place, you are ready to check out the full awesomeness of your Geek Spinner. The mode of the spinner is shown by the LED that is lit on power up or after a button press (D0 - D7). The mode is changed by pressing the button (see video).

Attachments

Step 14: Revisions and Errata

Revision 0.0: There are a couple of issues with the Revision 0.0 boards

First, and most embarrassing, is that the ISP header on the bottom of the board is "mirrored". In order to program the chip in place, you will have to jury-rig a jumper to swap the pins. Luckily, connecting two jumpers together (as shown in photo 1) will do the trick. The other way would be to jumper into a breadboard.

LEDs 6 & 7 are swapped. This is easily fixed in software, but annoying that I didn't catch it.

Any time you have an awesome idea, someone has already done it: https://www.instructables.com/id/POV-Arduino-Fidget-Spinner/. Surface mount soldering is something I can do, but not really beginner friendly. His code was also a little over my head, but I did use his ideas about displaying RPM and counts.

No project is ever complete or perfect. Here are some thoughts I have going forward:

Balance: Data sheets rarely have information about the weight of the components, so it is hard to make even an educated guess about the balance without just building it. The battery is obviously the heaviest component. I added holes on each end so I could add weight as needed to balance it.

Clockwise? If you noticed, the text only displays correctly if you spin in the clock-wise direction. Spinning the other direction creates a mirror image. Adding a second Hall sensor or magnet would allow you to derive rotation direction (Sean's project did this).

Color? Using programmable RGB LEDs would allow you to do colors. They are typically surface mount though.

I couldn't get the link to work, but I assume you are talking about something like this, which would work (but I'm not sure how it would affect the balance):CONN IC DIP SOCKET 14POS TIN, 3M 4814-3004-CP, https://www.digikey.com/short/31cmn3 (or equivalent).

Why do you separate touchPin and touchPinPullup (and same with mag)? Why not just use one declaration for each as INPUT_PULLUP? Then you wouldn't need to digitalWrite them HIGH either. Or does the ATTiny not support INPUT_PULLUP?

The short answer is that I was using an older “tiny” CORE which had different numbering for digital and analog, and thus I had to indicate both. This is the "counter-clockwise" pin mapping. If you dig into the code, you see it is a mute point because I do digitalRead() on the button instead of analogRead().

I'm going to rewrite the sketch to use the newer "clockwise" pin mapping which should clear up that problem.

And yes, I'll switch to using the INPUT_PULLUP declaration because it makes it clear what you are doing. I need to get in the habit of that.

When attempting to burn the bootloader with the YAPS I get the following error (note: have tried multiple chips, all purchased from the link above):

avrdude: stk500_recv(): programmer is not responding

avrdude: stk500_getsync() attempt 10 of 10: not in sync: resp=0x00

I have the chip directly on the YAPS. Selected ATtiny84 with an internal clock of 8Mhz (have also tried other speeds as well as external clock). Have also done various combinations of resetting the Arduino and YAPS before programming. Still no luck. Any ideas? :)

The error indicates a failure to communicate with the Arduino. A couple of things to check:- With the Arduino disconnected, check what com ports are listed ([Tools]->[Port]).- Plug the Arduino in, wait a few seconds, and set the port to the new com port.- Ensure the green heartbeat LED is blinking. If not, reset the Arduino.