Summary of DIY Apple Clock
This article details the design of a DIY Apple-style digital clock using an ATtiny microcontroller. It explains utilizing Pin Change Interrupts (PCINT) to handle two buttons for time adjustment, as the chip lacks multiple external interrupts. The project involves multiplexing a four-digit bubble display via a 74HC595 shift register and includes software debouncing logic to ensure stable button inputs.
Parts used in the DIY Apple Clock:
- ATtiny24, 44, or 84 series microcontroller
- 74HC595 shift register
- Bubble display (common cathode)
- Two push buttons
- Volatile integer variables for digit storage
- Debounce delay timer
The ATtiny24, 44, 84 series only has 1 external interrupt (INT0) [Page 48 of the datasheet]. This is the interrupt that we are most familiar with using on the Arduino. You can simply use this interrupt by saying “attachInterrupt()”
While it only had 1 interrupt, I wanted to have two buttons on my clock: one button to increase the time and another to decrease the time. Looking back on the datasheet, the ATtiny has two Pin Change Interrupt ports: PCINT0 and PCINT1 [Page 48].
The difference between External Interrupts and Pin Change Interrupts is that an External Interrupt has its own ISR (interrupt service routine). PCINTerrupts share one ISR for all pins on one port. This means that with Pin Change Interrupts we can make any pin be an interrupt, but then we have to go through the trouble of determining which pin caused the interrupt on the port.
Here are two really good articles to read. This is how I learned:
- http://thewanderingengineer.com/2014/08/11/arduino… PCINT in general
- http://thewanderingengineer.com/2014/08/11/pin-cha… PCINT on the ATtiny
volatile int dig1 = 0; //Hours tens volatile int dig2 = 0; //Hours ones volatile int dig3 = 0; //Minutes tens volatile int dig4 = 0; //Minutes ones
Each of these variables determines what number is displayed on each of the four digits on the bubble display.
I declared them volatile because they will be changed in the interrupt routines.
Setting them to 0 means when I turn on my clock, the count will start at 00:00 (12:00 AM).
const int latchPin = A3; //Pin connected to ST_CP of 74HC595 const int clockPin = A4; //Pin connected to SH_CP of 74HC595 const int dataPin = A5; //Pin connected to DS of 74HC595
Physical pins 8(A5), 9(A4), and 10(A3) will be used with the 74HC595 shift register.
The shift register will allow us to control segments a, b, c, d, e, f, g, and dp with pins Q0, Q1, Q2, Q3, Q4, Q5, Q6, and Q7 respectively.
To display each digit, we will be multiplexing.
const int dig1Pin = A0; //Pin to multiplex and display digit1 const int dig2Pin = A1; //Pin to multiplex and display digit2 const int dig3Pin = A2; //Pin to multiplex and display digit3 const int dig4Pin = A6; //Pin to multiplex and display digit4
The bubble display is common cathode. This means that when the digit is grounded or pulled to a digital LOW, the digit will light up. We will be using physical pins 13(A0), 12(A1), 11(A2), and 7(A6) to control the display of each digit on the bubble display.
//Two values below for debouncing. volatile unsigned long xlastDebounceTime = 0; volatile unsigned long ylastDebounceTime = 0; long debounceDelay = 150; // the debounce time; increase if the output flickers
These are some values we will be using to debounce the two buttons when the interrupt is activated. Without debouncing, one button press could be registered as five, and using the clock would be annoying.
Check out Arduino Examples/Digital/Debounce if you want.
For more detail: DIY Apple Clock
- Why use Pin Change Interrupts instead of External Interrupts?
The ATtiny only has one external interrupt but supports two Pin Change Interrupt ports allowing more pins to trigger events. - How are the time digits stored in the code?
Four volatile integer variables named dig1 through dig4 store the tens and ones for hours and minutes. - Which physical pins connect to the 74HC595 shift register?
Pins A3, A4, and A5 are used for latch, clock, and data connections respectively. - What is the purpose of multiplexing in this project?
Multiplexing allows the system to control segments a through dp and display each of the four digits sequentially. - How does the common cathode display determine which digit lights up?
The digit lights up when its corresponding pin is pulled to a digital LOW or grounded. - Why is debouncing necessary for the buttons?
Without debouncing, a single press could be registered multiple times causing annoying flickering or incorrect counts. - What is the default start time for the clock?
The clock starts at 00:00 because the digit variables are initialized to zero. - Can I change the debounce delay value?
Yes, you can increase the debounceDelay variable if the output flickers during operation.
