Tag Archives: WS2812B

DIY USB Media Dial

Recently few Media Dial project popped out to my Facebook feed.

It seems pretty cool project to built, but I couldn’t fabricate the files needed in their instructions.
Moreover, they used some expansive microcontrollers and the total build was way above $5.

I decided to challenge myself and build a cheap version which I could print in my 3D printer and the
total cost would be around $5.

The Components

These are the main components I used:

Name Quantity Price (USD)
Digispark Clone 1 1.5

WS2812 Ring (with 16 leds)

1 2.79

Rotary encoder

1 1.72

The microcontroller I choose is the ATtiny85. With few tweaks it fits perfectly with me needs.
I bought a Digispark clone board. It is very small and has a micro usb connector which connects to pins PB3 and PB4 of the ATtiny .
This board is able to emulate HID device with the Digispark libraries.

The LED ring is not a must, but it can add some nice effects when I turn the dial or press the button.
The WS2812 is an addressable led, so we only need 1 gpio from the ATtiny to control all the 16 leds.
Digispark provides a version of the Adafruit Nexopixel library to the Digispark boards.

The encoder is the obvious choice for detecting the direction of the wheel and also to counts steps.
It also has a button and I can add more features with a button click or double clicks.

Modifying the Digispark

To use the Digispark board from the areduino IDE, I needed to add it with it’s libraries to the Arduino board manager.
Here is a quick guide from their website:

TL;DRBoard Manager URL:    http://digistump.com/package_digistump_index.json

I also need to make few tweaks to the board as I mentions earlier:

  •  Change the fuses so PB5 won’t reset the board (this is the default state). I need all the IO of the ATtiny85
  • Remove the LED from the board (it will interfere with the reset of the components)

To change the fuse, I used USBASP V2.0 I had laying around.
This is how I connected the IO to the USBASP:

VCC to 5V, and of course the grounds.

Then I used ‘avrdude’ to check if everything is connected and responding, and the current
fuse settings with the command: (the path might be different in other systems)

C:\Program Files (x86)\Arduino\hardware\tools\avr\bin>avrdude.exe -C "C:\Program Files (x86)\Arduino\hardware\tools\avr/etc/avrdude.conf" -c usbasp -p attiny85 -n

I got this respond:

avrdude.exe: warning: cannot set sck period. please check for usbasp firmware update.
avrdude.exe: AVR device initialized and ready to accept instructions

Reading | ################################################## | 100% 0.03s

avrdude.exe: Device signature = 0x1e930b (probably t85)

avrdude.exe: safemode: Fuses OK (E:FE, H:DD, L:E1)

avrdude.exe done.  Thank you.

Everything is good.

I entered the fuse values in this calculator:  http://www.engbedded.com/fusecalc/
and checked the ‘RSTDISBL’ (external reset disabled) to get the new fuse values.

Only the HIGH fuse changed, so I only change it with this command: (hfuse – HIGH, w – WRITE, 0x5F – Fuse Value, m Program )

C:\Program Files (x86)\Arduino\hardware\tools\avr\bin>avrdude.exe -C "C:\Program Files (x86)\Arduino\hardware\tools\avr/etc/avrdude.conf" -c usbasp -p attiny85  -U hfuse:w:0x5F:m

and this is the respond:

avrdude.exe: warning: cannot set sck period. please check for usbasp firmware update.
avrdude.exe: AVR device initialized and ready to accept instructions

Reading | ################################################## | 100% 0.03s

avrdude.exe: Device signature = 0x1e930b (probably t85)
avrdude.exe: reading input file "0x5F"
avrdude.exe: writing hfuse (1 bytes):

Writing | ################################################## | 100% 0.02s

avrdude.exe: 1 bytes of hfuse written
avrdude.exe: verifying hfuse memory against 0x5F:
avrdude.exe: load data hfuse data from input file 0x5F:
avrdude.exe: input file 0x5F contains 1 bytes
avrdude.exe: reading on-chip hfuse data:

Reading | ################################################## | 100% 0.01s

avrdude.exe: verifying ...
avrdude.exe: 1 bytes of hfuse verified

avrdude.exe: safemode: Fuses OK (E:FE, H:5F, L:E1)

avrdude.exe done.  Thank you.


Now for the LED, I just remove the resistor connected to PB1.
It’s the small resistor between the ATtiny85 and the voltage regulator.

Designing and Printing

The design I made (using Fusion 360) contains 3 main parts:

  • The bottom part where the Digispark sits
  • The center part where the Encoder and the led ring sits
  • The top part that will be turned to control the dial.
    • The top part is made from 3 pieces, because I wanted to have
      a transparent ring for viewing the leds.

I printed all the parts in a black PLA, and the top transparent ring in a clear PLA.
After few hours in my 3D printer (I used the CR-10 Mini), this is what came up:


First I assembled the top part. I inserted the transparent ring to the top part body (and added few drops of glue),
and then did the same thing with the center part.

Then I solders 3 wires to the led ring where is says  V+, IN and G,
and I passed them through the holes in the middle parts.

I also solders wires to all the encoders legs and fixed it to the center part as well.

Now I solders the wires to the Digispark board as the following scheme:

I used the ATtiny internal pullups for the encoder A and B, and also for the button so no external pullups resistors are needed.

Now I connected the Digispark board to the bottom part with two 3mm M3 screws, and connected the middle part to the bottom part with two long M3 screw.

At the bottom part, I room for 8mm anti-slip stickers, but it’s not a must.


I used the Digispark library for the HID emulation of keyboard (or mouse, I used only keyboard) and the Adafruit library for the Neopixels to control the leds.
I wrote one function that handles the encoder (check for changes), and one function that handles the button pressings.
Those functions are called constantly (polling, no interrupts here) and if there is a change – it calls one of the assigned operation functions.
There is function for button click, double click, scrolling the wheel ‘Down’ or ‘Up’.

This is a very fast draft I made, but it’s easy to continue of change it from here.

Every encoder change will turn the next led in the ring (or the previews, depend on the direction) with Blue color.
One click on the button will turn 4 leds to Green, and double click to Red.

The first use I came up for this Media Dial is for Lightroom.
Rotating the dial with increase of decrease the slider values.
One button click will cycle through the next panel slider, and double click will cycle through the previous.

You can see the final result here:

You can find the STL for the 3D files and the source code in my gitlab repository:


(My) Light Paiting Proposal

The time has come and I decided to surprise my girlfriend with a weekend in Prague during which I will ask her to marry me.

I wanted it to be special in my way. I’m Electrical Engineer and consider as a “Maker” so it must be involved with some electronics and building something!

I had few ideas, some involved with creating a custom PCB with LEDs flashing “Will You Marry Me”, but it was too simple and BORING!

I also like photography very much, and long exposures.

Then remembered that tutorial on Adafruit about light painting.

And then it hit me!

I will ask her to take a long exposure photo of me, and then I will do all the painting.
She won’t be able to see or understand what I’m doing until the long exposure will end.
Then, she will see “Will You Marry Me?” on the camera screen!

So how it works?

The camera’s sensor capture everything it “sees” while the shutter is open.
If you open the shutter for a long period of time, and your hands are not stable – you will get a blurry image.

The same principle is here; The camera will be stable on a tripod, but the object will be moving.
I will open the shutter for a very long time (about 15 seconds) and will start moving a light source.
The result will be that light source “smeared” on the photo.

Now imagine that the light source is a bar like in the picture, and I can change the colors very fast (about 60 changes per second)!
When I will move my hand while the shutter is opened, the camera’s sensor will “see” and capture all the changes of the light bar.
If I will sync my movement to the lights changing in the bar – I will be able to “paint” texts or even images.


The hardware

It’s easiest to control such amount of leds (about 70) if they are addressable leds, so I used here 0.5m a of a WS2812B strip (I bought 1 meter of 144 pixels/meter).

In addition I will need a place to store our images. SD Card is very convenient for loading new photos so we will need a SD card adapter / module.

If I want to make it portable then we need a battery. Since I want to make it very portable, and 70 leds will consume a lot of current, I choose to use lipo batteries.

One 18650 battery will give me about 3.7v-4.2v, which is not enough to operate WS2812B which needs 5V, so two of them in series will give me about 7.4v-8.4v.
Now I need to regulate the voltage to 5V, so an adjustable 5A switching step down regulator will do the job here.

I will need a button to start the painting, a switch turn the device on and off, and a knob to change the speed or light intensity (I didn’t use that feature but there is a support for that).
For the knob I used 5k potentiometer.

To control the leds and the sd card reading, I will use a small Arduino pro mini clone. It’s small and it has enough power to drive the leds for this purpose.


Component Quantity
WS2812B 1M 144 leds 1
Protected 18650 2600mAh 2
Micro SD Card Module 1
5K potentiometer 1
470uf 16v Capacitor 1
7mm Push button 1
12mm Latching switch 1
5A XL4005 DC-DC Step Down 1
Arduino Pro Mini 5V 16MHZ 1

If you need a charger for the 18650 battery, you can use the NITECORE D4 (it support more types of batteries like AA, AAA and more..)

The Build

I’m not the first one who build such a light painter.
I got this idea and based all this on this cool project I saw on Adafruit:

The general principle is the same, and I even used their code to run my bar (with few tiny changes), but I wanted a small and portable device.

So I started sketching something I could print using my 3D printer, and came with this:

The top and bottom orange parts are sliding into the black parts.
The tiny orange part is for the Arduino and sd card module from the other side.
The big orange part is for the battries and the voltage regulator.
The handle can be removed and the potentiometer hides there (I didn’t want to change it accidentally) .
On the right near the handle lays the button for easy press while holding the handle.

The bar is made from two parts because I can’t print it in once piece with my printer.

Here’s a photo of all the electronics and almost all the printed parts (did you notice what’s missing? )

I had a little space problem with the voltage regulator (it was too high), so I removed it’s potentiometer and replaced it with a small resistor to get about 5v.
From the datasheet I got the formula for Vout, and on the module I have R1 = 330 ohm, so I used 1.6k ohm resistor I had to get 4.84V which is still fine (above 4.5v is good).


Schematics for the entire light bar:

And this is what came up, exactly how I imagined it:

So I have a working led bar, I can change the colors but now is the hard part – the software.
I need a software to take a photo with a width 72 pixels (because I have 72 leds) and translate each row in the photo to commands for the leds.
(The text is inverted because the software assume that the pixels are connected from the bottom of the bar, and I connected them from the top)

Fortunately, this is what Adafruit did, and since I didn’t have much time for writing my own code – I used their’s this time:


Timing is everything here.
If I move too fast or too slow – the text will be warped.

So I need to find the correct pace, and keep moving smoothly at the same speed.

After few tries I found the golden ratio: 60 lines per second!

The second problem was a little minor, but I needed to know the limits inside the frame, so I wouldn’t go out.
This took some practice, but I counted steps from the camera and to the starting position and then I could estimate my limits.


I designed the text I want to display.
I didn’t want to it be one long row with a tiny text, so I splited it to two rows.
The device thinks it’s one long row and keep displaying it.
In the middle of the image I created, I put a long black break. That brake signaled me that I need to lower the
lightbar and start going backwards (I also mirrored the text).


I asked her to take a photo (I changed all the camera parameters before), and then I started walking with the bar in my hand (sorry for the bad quality but you get the idea)

And this is the result of all the hard work:

Of course she said yes 😉