ATtiny85 Ring Watch





Introduction: ATtiny85 Ring Watch

Base on the previous Instructables - ATtiny Watch Core and more, I have made a real gadget, an ATtiny85 Ring Watch.

Step 1: Preparation


Today core subject, ATtiny85. Someone suggest me to use SOIC version to reduce the watch size and I found the coin cell mAh calculation method will count the battery voltage down to 2.0 V, so this watch require a low voltage version MCU to keep it stable. So I have ordered an ATTINY85V-10SU. (much expensive $_$)


Any ISP that can program ATtiny85, this time I am using a Digispark act as a littleWire. (,160.0.h...)


In order to meet the ring size, I choose CR1220, I expect it can last over half an year.


(Quote from previous project) Since the number of IO pins of ATtiny85 is very limited, I design display and further modules should all run in I2C. Power consumption and source availability are also important factors. I choose an OLED screen drive with SSD1306. It can find in 4 different sizes, 64x32 is the smallest one. (another sizes are 128x64, 128x32 and 64x48)

Watch Body

(Quote from previous project) It should be more stylish if make it by wood, but I am lazy one, so just print it out.

Transparent Cover

(Quote from previous project) A small piece of transparent PET plastic plate. It is transparent, provide enough support and very easy to get from many product packing.

Other Parts

  • A SOIC ISP clip for program ATTINY85V-10SU
  • 3 pieces of M2 screws
  • 3 buttons
  • 2 various resistors (more than 1k)
  • coated copper wires
  • thin mental plate for making a tailor-made battery holder
  • a SOP8 to DIP8 board
  • a little piece of multipurpose PC board for building button panel

Step 2: Setup Arduino With ATtiny85, EEPROM and TinyWireM Support


Download Arduino 1.6.5 (1.6.6/7 have known compatible issue - "contains deprecated")

Download ArduinoTiny (if you not familiar with GitHub, simply click Download ZIP button)

Install Arduino

Run Windows installer / copy to Applications folder / simply unzip the file

Locate the Arduino path

If you install with Windows install, it should be:

C:\Program Files\Arduino

If you are using OSX, it should be:


Or any path you unzipped to.

Add ArduinoTiny Support

  1. Unzip
  2. Copy tiny folder to the hardware folder under Arduino path

Add EEPROM support

In Arduino path, copy hardware\arduino\avr\libraries\EEPROM\EEPROM.h to hardware\tiny\avr\cores\tiny folder.

Install TinyWireM Library

  1. Run Arduino
  2. Select Sketch Menu -> Include Library sub-menu -> Manage Libraries...
  3. Search TinyWireM
  4. Select TinyWireM and click Install button
  5. Close Library Manager and close Arduino

Debug TinyWireM

TinyWireM have an know issue but not yet fixed, you can fix it easily:

  1. Locate TinyWireM library path (Windows: "My Documents\Arduino\libraries\TinyWireM"; OSX: "~/Documents/Arduino/libraries/TinyWireM")
  2. Modify "TinyWireM.cpp" line 53, save and close the file


if (USI_BufIdx >= USI_BUF_SIZE) return 0;       // dont blow out the buffer


if (USI_BufIdx >= USI_BUF_SIZE - 1) return 0;       // dont blow out the buffer

Step 3: Download Latest Source Code

Download the latest source code here:

If you are not familiar with GitHub, simply press Download ZIP button.

You may find further details in the following materials:

Step 4: Create Watch Body

Say it again, it should be more stylish if make it by wood, but I am lazy one, so just print it out.

Attached the Sketchup and STL file for reference.


Step 5: Solder MCU

This step is not essential, but it can make further solder work and reprogram easily.

Solder SMD reference:

Step 6: Create Tailor-made Button Board

In previous project, I use 2 pins to handle 2 buttons input. It is too expensive for using an ATtiny85 IO pin for each input button. This time I try to use 1 IO pin to handle 3 buttons input.

Here is my setting:

set button - GND -> button -> PIN 2 (PB3, ADC3)

up button - GND -> 6.8k resistor -> button -> PIN 2

down button -> GND -> 68k resistor -> button -> PIN 2

Various resistors value should be ok, over 1k is recommended. 3 buttons have different resistor values, so it can use analogRead() function to distinguish which button pressed. I have measured some common resistor analog value for reference.

You may change the threshold value in ATtinyWatch.ino file if you use different resistor.




Step 7: Solder Circult

Since the ring watch have a curved surface, it cannot solder all component on a single PC board. MCU, OLED, button panel and battery holder all connected by coated copper wire. VCC and GND coated copper wire should around 6-8 cm and require remove the coating at the middle connect point by sand paper. Other wires are a little bit shorter.

Here is the connection summary:


Pin 2: Button Panel

Pin 4: OLED GND -> Button Panel ->Battery Holder



Pin 8: OLED VCC -> Battery Holder

Step 8: Create Tailor-made Battery Holder

The ring is small and it can not fit a normal CR1220 battery holder. So we need some thin mental plate to tailor-made a smaller one. My thin mental plate is re-cycling from Dupont line header wastage, you may find other near you.

Cut a short piece of mental plate and solder to a coated copper wire.

Bent it and slot it to the ring body, do it both at positive and negative terminal.

Slot in the battery and test the connective.

Step 9: Program MCU

  1. Plug your ISP to the computer
  2. Run Arduino
  3. Open ATtinyWatch.ino from unzipped ATtinyWatch folder
  4. Select Tools menu -> Board sub-menu -> select ATtiny85
  5. Select Tools menu -> Clock sub-menu -> select 1 MHz (internal oscillator; BOD disabled)
  6. Select Tools menu -> Programmer sub-menu -> your ISP
  7. Remove CR1220
  8. Connect the SOIC ISP clip to ATtiny85 and press Upload button

ISP -> ATtiny85

MISO -> Pin 6

VCC -> Pin 8

SCK -> Pin 7

MOSI -> Pin 5

RESET -> Pin 1

GND -> Pin 4


If you have SSD1306 screen other than 64x32 resolution, you can change resolution define in ssd1306.h


// custom screen resolution by define SCREEN128X64, SCREEN128X32, SCREEN64X48 or SCREED64X32 (default)
#define SCREEN_128X64 //#define SCREEN_128X32 //#define SCREEN_64X48 // not tested //#define SCREEN_64X32

Other program ATtiny85 reference:

Step 10: Debug Screen

Press up or down button while no any date time field selected will enter Debug Screen.

The value means:

Row 1 (I): Watch Dog Timer(WDT) interrupt count, this value will be reset for each set time operation that over 1 hour interval

Row 2 (M): Auto tuned value of micro-second per WDT interrupt, this value will be updated for each set time operation that over 1 hour interval

Row 3 (V): Calibrated value of battery level in millivolt

Row 4 (T): ATtiny85 internal temperature sensor raw value, this value is accumulated last 64 sample values

Step 11: Calibrate Time

Press set button will switch selected Date and time fields, selected field will be highlighted.

Press up and down buttons to change the selected field value. Press set button while highlighting SECOND fields will finished set time operation.

For each set time operation that over 1 hour interval, the micro-second per WDT interrupt value will be auto tuned.

In my experience, holding voltage and temperature condition stable, it should not drift over 1 minute each day after auto tune :P

Step 12: Calibrate Voltage Reference

  1. Comment the #define lines of DEBUG_SCREEN_V and MULTI_METER_VOLTAGE in WDT_time.h
  2. Program the watch
  3. Record the debug screen V reading and multimeter measured voltage
  4. Uncomment and fill the DEBUG_SCREEN_V and MULTI_METER_VOLTAGE reading value
  5. Re-program the watch


#define DEBUG_SCREEN_V 4979 // put your screen reading here

#define MULTI_METER_VOLTAGE 4740 // put your multimeter reading here (in millivolt)

Step 13: Calibrate Temperature Reference

  1. Record the debug screen T reading and real temperature value 2 times in different temperature condition
  2. Uncomment and fill the DEBUG_SCREEN_T_1, TEMPERATURE_1, DEBUG_SCREEN_T_2 and TEMPERATURE_2 values
  3. Re-program the watch


#define DEBUG_SCREEN_T_1  21823L
#define TEMPERATURE_1     52000L
#define DEBUG_SCREEN_T_2  18757L
#define TEMPERATURE_2     12000L

Step 14: Assembly

Slot the OLED screen in the pit and place all the component at the right place.

Step 15: Screw Up

Assembly the ring and screw up the M2 screws to the ring body.

Step 16: Transparent Cover

  1. Cut a 16 mm width and 82 mm long PET transparent plastic plate
  2. Cut a little bit at 4 corners for easiler slot in
  3. Stick a 1.5 mm width double sided adhesive tape at 2 borders
  4. Slot in the transparent cover to the ring body at one side
  5. Stick the transparent cover to the ring body
  6. Slot in another side

Other transparent cover reference:

Step 17: Happy Time!

It's time to show what you have done to everyone!

What's next:

  • Slimmer ring body, as many one knows, SOP8 to DIP8 board is optional and the button panel can be smaller by replacing to SMD one
  • Add other I2C modules
  • Amber sensor to fine tune brighter screen under the sun
  • Research sync time method, GPS, WiFi + internet, BLE + mobile phone and more



  • Pocket-Sized Contest

    Pocket-Sized Contest
  • Pro Tips Challenge

    Pro Tips Challenge
  • Paper Contest 2018

    Paper Contest 2018

We have a be nice policy.
Please be positive and constructive.




Hi~ Thank you for great job and sharing!!.
I'd like to add Bluetooth capability to your project for other applications. I tried to use sofrwareserial to use Bluetooth. However, adding "softwareserial.h" to your code caused a compile error. The error message is as follows.

SoftwareSerial\SoftwareSerial.cpp.o: In function `__vector_2':
C:\Program Files (x86)\Arduino\hardware\arduino\avr\libraries\SoftwareSerial/SoftwareSerial.cpp:227: multiple definition of `__vector_2'
ATtinyWatch_128_64_20171212.cpp.o:C:\Program Files (x86)\Arduino/ATtinyWatch_128_64_20171212.ino:177: first defined here
collect2.exe: error: ld returned 1 exit status

Do you have any idea what this is caused by and how i can fix it?
Thank you !

Hi wschang, I have tried some compatible software serial library before. But the main problem is you cannot fit all the code in 8 KB flash.

Thanks for the insight into how to get this working on an ATTiny85, your code works great but I'm writing another application based on your SSD1306 library (from this instructable) and so I needed to create a new font for my use. I tried following your instructions (in the other watch instructable) but they don't seem to work for this version of SSD1306.cpp or I don't know what I'm doing creating it??? I did get the font files to match your watch_digit.h file but using that with the SSD1306.cpp and SSD1306.h from this instructable doesn't work. Did you possibly use different parameters to Convert for this one?

Hi warpster, what is the error message?

Not getting an error, I'm seeing something on the display but nothing that looks like any of the characters in the font. I think I'm not getting the font data in the proper order. What order do I need to scan the font bits?

Top left , horizontal, top to bottom

Top right, horizontal, top to bottom

Top left, vertical, left to right

Top right vertical, right to left

Bottom left, horizontal, bottom to top

Bottom right, horizontal, bottom to top

Bottom left vertical, left to right

Bottom right, vertical, right to left

Also if I'm understanding the code correctly you are determining the pixel height by taking the font number like the '2' from font_2x_display and multiplying the width by that number ?

Recall my memory, it should be top to bottom then left to right. So I have rotate the font bitmap 90 degree and then flip it before the conversion.

As a followup to my question I am trying to get both a 16 pixel and 24 pixel version of the logisoso font but only 0-9 and A-Z and a-z and space, can that be done?

I think ATtiny85 cannot fit both 2x and 3x font at the same time.

Hi, This project is awesome! I am having a small issue, though. When I plug in the battery and the watch starts, it continually switches between debug mode and the time mode on the screen, like it loads time mode, then debug mode, then time mode, etc. Any ideas as to what this is caused by and how I can fix it?

It should be related to the buttons signal. Try disconnect the buttons (pin 2) and then test again.