Path: Home => AVR overview => Applications => ATtiny crystals => Crystal divider   Diese Seite in Deutsch: Flag DE Logo
Tiny XTAL oscillator Applications of
AVR single chip controllers AT90S, ATtiny, ATmega and ATxmega
A crystal divider for music tones with ATtiny25

Crystal divider for music tones with ATtiny25

This plays music tones with a crystal-driven ATtiny25. It can be configured to play either eight, 15, 22, 29, 36, 43, 50 or 57 different tones (between one and eight octaves) of the gamut. Those are selected and switched on by up to 57 keys.

If you need more accuracy for the tones, you can use a 16-bit TC for that. As the ATtiny25 doesn't haven a 16-bit TC, try this version with an ATtiny24's 16-bit TC instead here, it works a little bit different.

Configuration can be done with a LibreOffice-Calc file, which provides all necessary tables for calculation here. The drawings can be downloaded as LibreOffice-Draw file from here.

Hardware Tones Crystals Resistors Software

The hardware

The schematic of the music tone player This is all you need:
  1. A crystal X clocks an ATtiny25.
  2. A resistor network with switches and resistors selects the tone to be played. Up to 57 switches can be attached. The resulting voltage from the resistor network is measured on the ADC1 input pin of the ATtiny25. The voltage on ADC1 is V = Vop * R0 / (R0 + Rn), which results in ADC values of ADC = 1023 * R0 / (R0 + Rn), if the reference voltage is set to the operating voltage of the ATtiny25 (e. g. to 3.3 or 5 V, note that crystal frequencies larger than 10 MHz require 4.5V minimum operating voltage). The tolerance of the resistors should be either 5, 2 or 1%, depending from the number of octaves/keys.
  3. The frequency of the tone is generated on the OC0A output pin and can directly (via an electrolytical capacitor) drive a small speaker. The opened jumper J1 disconnects the capacitor and the loudspeaker from the MOSI-pin, if and during the controller is programmed via the ISP6 interface.

Crystal tone generator on a breadboard Here is the complete hardware on a breadboard. The resistor network has been replaced by a potentiometer to test the voltage ranges.

The jumper to switch off the speaker during programming wasn't really necessary. It can be left connected without causing problems (the speaker's inductivity was low enough for the programming rectangles).

Top of page Hardware Tones Crystals Resistors Software

Configuring the tones

Tones that can be played The main tone selection is made on the first spreadsheet named "Notes" in the LibreOffice-Calc file here.

This page holds the musical notes between a1m (up the displayed list) and d7 (down the list) and their frequency in Hz in column B. Now just click on the drop-down field in cell A4 and select one of the entries there. If you select 1 octave, eight different tones can be played. You see that in that case the tone a1 with 440 Hz is the first tone that will be played and a2 with 880 Hz is the last one. If your single-octave-player shall start with a3, just overwrite the 1 with the formula in the line below and place a 1 into cell C41. The seven notes following this line are automatically numbered.

Note that the number of the first selected tone in line 4 (22 by default) is the line in relation to the first entry, not the line number. The number of keys for one and up to to eight octaves is in line 5 of the sheet. The three lines below V format the selected entries for export to other sheets.

Top of page Hardware Tones Crystals Resistors Software

Configuring the crystal

The crystals to select from The spreadsheet crystals in the LibreOffice-Calc file here shows all commercially available crystals with their frequencies in MHz in column A. The line 6 lists all keys (in that case 22 keys), the line 7 the target frequencies for those keys.

The numbers displayed show the necessary divider value to arrive at these frequencies if the crystal frequency is that in column A. For a crystal frequency of 32.768 kHz and a tone frequency of 440 Hz, the divider is half of 74.473 (= 37.236), because the OC0A pin toggles twice for a complete wave.

If the crystal is selected in the sheet SourceCode, the line of its divider values appears in green. Here the 18 MHz crystal is selected.

Calculation of the prescaler values From the dividers on that spreadsheet, the sheet Presc calculates the prescaler values for clocking the TC0. Those can be 1, 8, 64, 256 or 1,024, depending from the necessary divider.

Calculation of the compare A values for CTC mode The next sheet, Ctc, calculates the necessary CTC compare values for the comparer A of TC0. These values are directly usable as compare values in the OC0A port register, as they include the -1.

Calculation of the frequencies The next sheet, fIs, calculates the resulting frequency that the crystal produces with the prescaler and the CTC compare value. Those can differ from the target frequency.

Here, the selected crystal of 18 MHz does not exactly meet the tones, but the differences are as small as possible (see the next page).

Delta of the frequencies The next sheet, Delta, calculates the difference of the resulting frequencies with their target values in percent. Those that exceed a 1% deviation are marked in red (move up the table and you'll see those).

Those differences are squared and added over all keys, the square root is calculated from that sum and is divided by the number of keys, to get the average distance in percent in column B. The minimum of those distances is shown in cell B6 and the best-fitting crystal is identified. That is the nearest for that purpose, note that it depends strongly from the number of octaves selected.

To allow to search for nearly-as-good-as those, input a percentage in cell A7. The best fitting crystal is marked in green, those below the upper selection criteria are in yellow.

Note that the crystal's tolerance of between +/- 30 and 50 ppm does not play a relevant role in the accuracy. With an 18MHz crystal and for 440 Hz, the frequency is by -0.124 percent too small, a +/- 50 ppm deviation changes this to -0.119 or -0.129 percent. The effect is below 10% of the existing inaccuracies.

Source code table for a selected crystal The sheet SourceCode allows to select a crystal from a drop-down list of all crystals in cell B3. It then puts together all properties of that crystal and generates the yellow-backgrounded table for export to your source code file.

The table has entries for all keys (here: 22). The first byte is the prescaler value for the TCCR0B port register, the second byte is the CTC compare A value for the OCR0A port register.

For copying the table to the source mark the complete yellow backgrounded cells, press Ctrl-C, go to the end of your source code file and press Ctrl-V.

For programming point Z to the desired note entry (= 2 * NotesTable + 2 * note number) with two LDIs, then LPM register,Z+ and OUT TCCR0B,register, then LPM register,Z and OUT OCR0A,register. Note that the tone toggling has to be switched on, e. g. by
LDI register,(1<<COM0A0)|(1<<WGM01) ; Toggle OC0A, CTC mode
OUT TCCR0A,register ; to control register port A

to switch the toggling and the CTC mode on. To ensure that the switching only appears after a new TC0 start has happened, interimly store those values in registers and output those afterwards in a compare match A interrupt service routine. See below in the software section for an algorithm flow chart.

Top of page Hardware Tones Crystals Resistors Software

Configuring the resistors

Calculating the resistors The configuration of the resistors is done in the sheet Resistors in the LibreOffice-Calc file here. Depending from the numbers of octaves the keys 1 to N are listed in column A. In column D a range of ADC values is created, which spread all key voltages over the ADC range between 0 and 1023. The middle area around NKeys / 2 is wider than the upper and lower area, because the resistor's tolerance is of higher importance for those. This can be seen from the values in column I, where those differences appear: in the diplayed case they range from 3 to 22 ADC units (see the maximum value in cell J5).

Scaling the resistors Note that the difference values in column C are made in the sheet ResScaling. If inappropriate, adjust the formula in cell G5 therein, so that the whole area of 999 ADC values is not exceeded. The recommended values are proven solutions for that non-linear function.

The following settings in sheet "Resistors" are possible. Input the resistor to ground R0 in cell D4. Do not input values smaller than 1k, the current might get too high. If eight octaves are to be played, increase this to 8k2, but be sure that your attached, but silent ISP6 programmer (USCK) does not interfere with the very high resistors in the low key areas.

Select either the E24 or E12 resistor row from the drop-down-field in cell F4: for more than 3 octaves you should select E24. The tolerance of the resistors can be 5, 2 or 1%, depending from the number of octaves (4 or more octaves require 1%), lower values reduce the ADC range for each key (see the Max value in cell I5).

The resulting voltages, if an operating voltage of 5V is applied, is listed in column B.

From the nominal voltage of each key the resistor Rth kΩ in column E is calculated. Column F converts this theoretical resistor to the nearest value within the E12- or E24-resistor-row. The column G converts the voltage to a lower ADC value, if the resistor tolerance produces the smallest voltage. This is the case if the 4k7 to zero is on its lowest tolerance value and the Rn resistor is on its upper tolerance. Vice versa, column H produces the upper range of this ADC value in its highest range. The values in column H are increased by one to allow for a carry detection during compares.

The column J calculates the difference between the high value in this line and the low value in the next higher line. This difference should be zero or positive, to be able to identify the key that is pressed. If this isn't the case (the cell turns red), you'll have to adjust the R0 resistor or the ADC curve manually. This can happen if your available ADC area is too small (cell G5 in sheet ResScaling is too low) or if 8 octaves are selected and one of the middle resistors in column F gets equal to its next lower or higher neighbor (in which case you'll have to either increase R0 or adjust the ADC curve manually or to select a combined resistor combination in column F) by overwriting the calculated value.

The following column K allows to export a table with those values to the source code. For each key the lower and the upper value (plus one) is given. A key is identified, if the ADC value is larger or equal to the first 16-bit word entry and smaller than the second entry. Values in between (Adc value larger or equal to the second word and smaller than the next first word) are illegal and should result in a silent tone.
If you add up more than one ADC measurement to increase the reliability of the ADC measurement, you can multiply the compare values by multiples of two with the drop-down-field behing cell K3. Note that values above 64 for this multiplicator lead to values larger than those that fit into a 16-bit-word.

Displaying the resistors Here is a list of all resistors, if you need to order those in an online shop.

Top of page Hardware Tones Crystals Resistors Software


Flow chart of the software A three-octaves version of the software can be downloaded from here. Just replace the tone- and the ADC table for other ranges.

The software is written in assembler using the flow-chart on the right side of this page.

Do not forget to set the fuses of the device, otherwise your tones are too low.

No problem if you programmed the device and you need, later on, a device without a crystal: just attach a crystal temporarily and reset the fuses to the internal RC oscillator, including the CLKDIV8 fuse. Or clock the device temporarily with a rectangle generator with whatever frequency, but higher than 100 kHz and smaller than 20 MHz, on the XTAL1 pin.

The fuses of the ATtiny25

The flow chart shows the conversion of the ADC measurement to the tone as well as the rolling-over of the tone values to the timer on compare matches. You just need to add the ADC1 initiation and the interrupt service routine for the ADC1 measurements, which sets the bAdc flag when complete (e.g. after 64 measurements and summing those up).

TC0 should be initiated in CTC mode with the toggle of OC0A off and the compare match A interrupt enabled. The registers R0 to R2 should be set to convenient values (non-toggle, 255 compare match A, prescaler to 64), as those are written to the timer in the compare match ISR.

The parameter cAdcClkP should be set to a convenient value. This involves the crystal frequency, the repetition of ADC measurements that are summed up in cAdcCnt (preferably 64) and the desired reaction time between the tone-start-time and the key-press-time.

Not shown here is the init of the hardware and the ADC-Complete Interrupt-Service-Routine. This should add the ADC result to the rAdcH:rAdcL pair and down-count the rAdcCnt register. If zero, the flag bAdc should be set in the flag register rFlag. If not, the next ADC conversion must be started. The conversion of the ADC sum to the switch identification and the tone conversion should be outside the interrupt service routines, because it can require at least 16 (with one octave configured) and up to 114 16-bit compares (with 8 octaves configured).

There are lots of possible variations. As the PB1 pin is currently not connected and not used, you can add a switch here, that e. g. doubles the number of octaves to be played (just double the number of stored tones and start with a higher table address if PB1 is zero). Or, if you want to be able to press combined keys for playing two tones at once, just add additional ATtiny25s and limit each tiny to one octave. The output signal of the ATtiny25s can then be added and the resulting combined voltage can be fed into an amplifier. Or you can invest one ATtiny25 for each key, then you can press any keys that you want and you combine those all. In that case you do not need a resistor encoder, just program each ATtiny25 for its own frequency and switch the tone on and off with the key.

That is already it. Hear some convenient tones from your home-brewed keyboard with that.

Top of page Hardware Tones Crystals Resistors Software

©2023 by