Home / Documentation
Name Modified Size InfoDownloads / Week
Parent folder
HowItWorks.pdf 2024-01-30 156.3 kB
README 2024-01-27 3.8 kB
Totals: 2 Items   160.1 kB 0
Compilation
===========
The sofware is a standalone assembler program. It was compiled using Microchip Studio, which is a rebadged Atmel Studio 7. The .hex file can be uploaded to any ATmega328P using the usual methods (such as avrdude). 

Calculations
============
The square waves are generated on the transition of Timer 1 running with a prescale of 8. With a 16MHz instruction clock this is 2MHz. If a fixed number of Timer 1 intervals are used between transitions, the frequencies are sufficiently inaccurate that the error is audible. To overcome this, the interval is extended at intervals by 500ns. The resultant notes are within 0.1Hz of the desired notes.

To calculate the values used by the program, first an accurate frequency is required. This is easily calculated by first calculating the logarithmic interval
 10^(log10(2)/12) = 1.0594630943592952645618252949463
By multiplying any desired base frequency by this value 12 times, the twelve notes of the octave are derived. This has been done in the table below.

Next, the note period is required - e.g.
for A7 this is 1/3520 = 2.8409090909090909090909090909091e-4 seconds
This is double the required period between transitions of the output pin, as each cycle of the square wave has a high and a low period. To get the number of 2MHz cycles divide by 2 and multiply by 2,000,000 (or easier, multiply by 1,000,000)
= 284.09090909090909090909090909091
A transition is required every 284 Timer 1 cycles, plus inserting a 285 cycle period every 1/0.09090909090909090909090909091 = 11 cycles. In the program, this is approximated by adding a dither value to a byte, and every time the byte overflows, the period is extended. The dither value is calculated by 0.09090909090909090909090909091 * 256 with rounding = 23. This overflows approximately every 11.13 additions.

To find the generated frequency, the calculation is reversed:

1,000,000/(284+23/256) = 3,520.0132000495001856256960963604 Hz

Here are the calculated values used in the two sources:

                 Desired Hz                Count for half cycle 2MHz clock     Dither byte     Actual
A7    3520                                               284                       23         3,520.01
A#7   3,729.3100921447193312576250382111                 268                       37         3,729.33
B7    3,951.0664100489928946460363348707                 253                       25         3,951.04
C8    4,186.0090448095781548455998963729                 238                      228         4,186.02
C#8   4,434.9220956299535399805813376194                 225                      124         4,434.90
D8    4,698.6362866785209642045282217693                 212                      212         4,698.63
D#8   4,978.0317395532945717819443092181                 200                      226         4,978.03
E8    5,274.0409106059188757734681767449                 189                      156         5,274.00
F8    5,587.6517029280621511260038502385                 178                      247         5,587.69
F#8   5,919.9107633861503829391233526818                 168                      236         5,919.90
G8    6,271.9269757079887053711924873572                 159                      113         6,271.90
G#8   6,644.8751612791222163590686229394                 150                      126         6,644.86
A8    7040                                               142                       12         7,039.93
A#8   7,458.6201842894386625152500764222                 134                       19         7,458.56
B8    7,902.1328200979857892920726697414                 126                      140         7,902.21
C9    8,372.0180896191563096911997927458                 119                      114         8,372.03
Source: README, updated 2024-01-27