Long timer with ATtiny25 Hardware, Mounting and Software for a long timer
Long-time timer with ATtiny25
Those who need a long-time timer with an additional beeper, to not having to stare at a
LED, and want to adjust the timer more accurately, can use this hard- and software. It
is built with an ATtiny25 (instead of the tiny13
here), also in a small 8-pin IC, but
can play programmable tones (Tone height, duration) when changing the red/green phase.
That can not be done with an ATtiny13, because one needs an additional timer in CTC mode
and with a versatile prescaler parade, which an ATtiny25 has.
The schematic is available here as LibreOffice draw
file. The associated calculations are in the LibreOffice spread-sheet
The red-green duo-LED works exactly like in the
Tiny13-Long-time-timer. The two OC0A-
and OC0B-outputs drive the LED. The necessary resistor values for different operating
voltages are listed in the table.
Adjusting the interval time does not work with jumpers but analog with a 10-turn trim
potentionmeter. Higher voltages on the ADC3 input increase the time towards the maximum
that is programmed (can be one to 63 hours).
The speaker is decoupled from the DC output voltage by an electrolytical capacitor.
As speaker I took a tiny Visaton K16-50, which I glued onto the side of the 6-pin ISP
plug. Other speakers work as well, they should have 45 or 50Ω.
If the jumper 1 is installed, all phase durations are accelerated by 64 (fast-motion
mode). This can be used to adjust the trim potentiometer. Those who want exactly
one hour time-intervals, plug the jumper on and adjust the trim pot to
60 * 60 / 64 = 56.25 seconds between two green-to-red
or red-to-green color changes. I had to adjust the ADC3 voltage to 1.17 Volt, when
using 2.74 V operating voltage and a multiplicator of 2 to get one hour.
Please note that other AVR devices than ATtiny25, 45 or 85 do NOT work, either
because they do not have a second timer (such as ATtiny13) or because TC1 is not
an 8-bit timer (most other tiny and mega) or do not have such a versatile prescaler
park like the ATtiny25. Those who want to use such different devices have to re-write
the complete tone-generation section of the source code.
The source code in assembler format is available for downloading
here and for viewing in the browser
here. The gamut frequencies to select the
two tones from are in the assembler include file here
and can be viewed in the browser here.
If you want to use an ATtiny45 or 85 instead, just change the def-inc include
line. All that changes in the source code is the stack pointer SPH in an ATtiny85,
which is automatically inserted by the .IFDEF directive.
Assembling works with any AVR assembler that knows .IF-, .IFDEF-, .ERROR- and
.MESSAGE-directives. The assembler version 2 from Studio 4.19 can do this, my
own one (gavrasm) also can do that. Who use a different assembler without those
directives needs to change the source code. Assembling the standard source code
yields 203 words (406 bytes) of machine code, so there is enough space left for
your own modifications (19.8% of the total in an ATtiny25).
When programmig the flash no fuse settings need to be changed. In any case: remove
jumper 1 to be able to program, and re-install it afterwards, if needed.
Hint to high-level-programmers: yes, the source code has 511 lines plus the 77 of
the gamut table. But a considerable part of those lines are only comments. And
you won't be able to fit all your high-level-libraries into the small memory of
an ATtiny25, so better select an ATtiny85 for that. Or, even better: learn a
language for grown-ups, e.g. assembly.
Software aids to debug the hardware
In the source code several test routines are included that can test all hardware.
These can be activated by setting the following key constants to one:
cDebugLed: blinks the LED red and green,
cDebugSpk: switches the speaker on and issues a tone,
cDebugAdc: measures the voltage on the trim potentiometer and displays
it as LED intensity in green (zero to half the operating voltage) or in red
cDebugPA2: if Jumper 1 is closed the LED turns red.
Of course only one of the four options should be one. Other options below are not
The timing and the control of the LED is similar to the
speaker control is added here to play tones.
The complete program runs with and within interrupts. Four interrupts work
The complete timing and LED switching is done with the TC0OVF interrupt.
Collecting and processing AD converter values is done with the ADCC interrupt.
Control of the tone duration is done via the OC1B interrupt.
Control of the jumper 1 on PCINT2 is done by the PCINT interrupt.
Outside those four interrupt service routines nothing else is done and the tiny
only is send to sleep. It sleeps more than 95%, which reduces operating current.
The timer is driven by default with a prescaler value of 64. This results in a
PWM frequency of 61 Hz and is good for PWM-controlling the LED. If you
change to a higher prescaler value (256 or 1,024 are valid) the LED will flicker
(256) or blink (1,024). Faster prescaler values of 1 or 8 are also valid, but
reduce the time scale (see table).
The time range that can be adjusted with the 10-turn trim potentiometer can be
changed with the factor cDurMax. At minimum (=1) one hour can be
adjusted, each increase adds another hour. This factor can be up to 63 for
extremely long times. By default it is set to two hours.
The AD converter is triggered by the TC0 overflow (61 Hz with the 64 prescaler),
ADATE in ADCSRA is 1 and ADTS in ADCSRB is 4. The number of measurements in
cDurMax is summed up by use of the counter register rAdcCnt.
This sum value is divided by 16 and written to the green delay register pair
rGreenH:rGreenL. The green value is subtracted from the sum and this
is written to the red delay register pair rRedH:rRedL.
Acceleration with the jumper 1 works via pin change interrupt PCINT. The ISR
sets the prescaler either to one (jumper closed) or to the default prescaler
value of 64 (jumper open). This also works during counting, not only when the
end of the interval is reached.
To issue the two tones uses TC1. This is configured as follows:
It works in CTC mode (Clear-Timer-on-Compare). Its port register OCR1C
receives the CTC value of the tone.
Its prescaler can be set to between 1 and 16,384. For the audible tones
the prescaler can be set to 1 (from 1,950 Hz upwards), 2 (from
980 Hz), 4 (from 490 Hz), 8 (from 245 Hz), 16 (from
122 Hz), 32 (from 61.6 Hz) and 64 (from 30.5 Hz).
For the two selected tones their frequency in Milli-Hertz can be written manually
to the constants fG2R (tone when green-turns-to-red) and fR2G (tone
when red-turns-to-green. But you can also use the gamut frequencies which are
listed as constants in the include file gamut.inc. This file provides all
gamut frequencies ftn in Milli-Hertz as constants, that the tone t
(C to H) in the octave n (0..8) has. The original LibreOffice spreadsheet is
here. Those who do not need the gamut
can simply delete the line with the include directive for the gamut.
Derived from the two tone frequencies (in mHz), the assembler generates the
following derived constants (? = R or G):
cs?2?: the prescaler bits for TC1,
cp?2?: the prescaler value for TC1,
cd?2?: the divider, by which TC1 has to divide the prescaled clock
(minus one in OCR1C),
cTc1?2?: the control word for writing the prescaler value and the CTC
bit to TC1,
cDur?2?: the number of half waves over which the tone is kept on to
achieve the duration in the constant cDur (in Milli-Seconds). Hint: Higher
tone frequencies need more half waves than lower ones.
All values are integer-rounded. Tones between 27,5 Hz and 18,79 kHz can
be comfortably selected from the gamut table. The error in this range is below
+/-0,5%, much smaller than the tolerance of an unadjusted internal RC-oscillator
in the ATtiny25.
When the tone generation in the TC0OVF-ISR is started, the following is done:
the cDur value (16-bit) is written to the register pair XH:XL,
the cd value is written to the port registers OCR1C and OCR1B,
the cTc1 value is written to the port register TCCR1,
the toggling of the OC1B output is switched active in the port register
the Interrupt-Enable-Bit OCIE1B in the Timer-Interrupt-Mask-Register
TIMSK is set.
Within the ISR of the TC1 compare int the counter in register pair XH:XL is decreased,
if zero the tone is switched off by setting the OC1B output to clear and by disabling
the TC1 interrupt.