Programming
The frequency and delay of the tune was obtained from
here
The code in the link above can be run on a Windows compiler such as GCC. There are only two functions that I am innterested in, which are: Beep(x,y) and Sleep(z).
The x parameter in the Beep function is the frequency in Hertz and the y parameter is the duration in which the beep can be heard in milliseconds.
The z parameter in the Sleep function specifies the time delay in milliseconds.
Programmer bash file
I have created a bash file that makes reprogramming the microcontoller easier. This bash file reprograms the microcontroller just by running "bash Program", where Program stands for the file name of the bash file. The code inside the file is shown below:
#!/bin/bash
avr-gcc -w -Os -DF_CPU=2000000UL -mmcu=attiny44 -c -o main.o main.c
avr-gcc -w -mmcu=attiny44 main.o -o main
avr-objcopy -O ihex -R .eeprom main main.hex
sudo avrdude -F -V -c usbtiny -p t44 -P usb -U flash:w:main.hex:i
Code
Here is how I have designed the code:
First of all, the windows library cannot be added to the microcontroller, so the Beep and Sleep functions will not work. So, for the Beep I have created a function that inputs in the frequency and outputs it as a 50% dutycycle square wave that has the inputted frequency. The following explains how the conversion equation was done:
Conversion
void interval(int x)
{
int beep = x;
int on = 1000000/(beep*2);
int t = 100000/(on*2)*2;
int i = 0;
for (i=0; i<t; i++){
PORTA |= 0b10001000;mydelay(on/8);
PORTA &= ~(0b10001000);mydelay(on/8);
}
}
int beep = x;
This is unnecessary and useless ^^
int on = 1000000/(beep*2);
Here I am calculating the on and off time of the wave (since the wave has 50% dutycycle)
First, I'm converting the frequency to time (f=1/t) and the dividing it by 2
So far im left with half of the period of the wave. To take as an example, the frequency of the beeps go up to ~1100Hz and if this was the input frequency to the function, the "on" time will be 0.000909 seconds. Since "on" is assigned as an integer, the number will be rounded down to 0. In order to solve this issue, Ive multiplied the time by 10^6 to convert it to micro seconds.
int t = 100000/(on*2)*2;
This is a bad name for a variable. Here t does not stand time, but it stands for the number of times the for loop would run in order to generate a beep for 100 milliseconds (since most of the beep durations are 100 milliseconds or a multiple of that). on was multipled by 2 in order to get the period. 1000/(on*2) will give you the number of loops for 1ms (since the unit of on is us) and multiplying it by 100 will give the number of loops for a 100ms beep. The reason why I doubled the time is explained later***
int i = 0;
self explanatory
for (i=0; i<t; i++){
same
PORTA |= 0b00001000;mydelay(on/8);
Here Im calling pin number 10 on the microcontroller to output for on microseconds. Through the datasheet, I have found that pin 10 is a porta pin and is labelled as PA3 as shown in the image below. 0b is the prefix for calling a pin in binary and PA3 is the 4th pin and 4 is translated as 1000 in binary (the other zeroes are for the rest of the porta pins (8 total)). mydelay is another function. The reason why I needed to add this function is that the compiler will not compile the delay unless a fixed variable is inputted. The reason why I divided the on time by 8 is explained later***
PORTA &= ~(0b00001000);mydelay(on/8);
This is actually the off part of the signal
Calling the function
Sample of one beep:
int freq = 330;
Here I am specifying the frequency of the square wave.
interval(freq);_delay_ms(0.25*100);
The frequency is inputted to the function, and the delay is the time between each beep. The reason why I reduced the delay by 4 times is explained later***
***
The reason why i have changed the t, on and delay time was that, when I first ran the code without changing them, i have noticed that the frequency of the beeps were definitely too low and the song was not recognisable if the listener did not have in mind that this is the super mario's the song. So I manipulated the frequency and time of the beep until I was satisfied with the result.
The whole code
#include <avr/io.h>
#include <util/delay.h>
void mydelay(int asd){
int i =0;
for (;i<asd;i++)
_delay_us(1);
}
void interval(int x)
{
int beep = x;
int on = 1000000/(beep*2);
int t = 100000/(on*2)*2;
int i = 0;
for (i=0; i<t; i++){
PORTA |= 0b10001000;mydelay(on/8);
PORTA &= ~(0b10001000);mydelay(on/8);
}
}
int main (void)
{
DDRA = 0b10001000;
while(1)
{
int freq = 330;
interval(freq);_delay_ms(0.25*100);
freq = 330;
interval(freq);_delay_ms(0.25*300);
freq = 330;
interval(freq);_delay_ms(0.25*300);
freq = 262;
interval(freq);_delay_ms(0.25*100);
freq = 330;
interval(freq);_delay_ms(0.25*300);
freq = 392;
interval(freq);_delay_ms(0.25*700);
freq = 196;
interval(freq);_delay_ms(0.25*700);
freq = 262;
interval(freq);_delay_ms(0.25*300);
freq = 262;
interval(freq);_delay_ms(0.25*300);
freq = 262;
interval(freq);_delay_ms(0.25*300);
freq = 196;
interval(freq);_delay_ms(0.25*300);
freq = 196;
interval(freq);_delay_ms(0.25*300);
freq = 196;
interval(freq);_delay_ms(0.25*300);
freq = 164;
interval(freq);_delay_ms(0.25*300);
freq = 164;
interval(freq);_delay_ms(0.25*300);
freq = 164;
interval(freq);_delay_ms(0.25*300);
freq = 220;
interval(freq);_delay_ms(0.25*100);
freq = 220;
interval(freq);_delay_ms(0.25*100);
freq = 220;
interval(freq);_delay_ms(0.25*100);
freq = 246;
interval(freq);_delay_ms(0.25*300);
freq = 233;
interval(freq);
freq = 233;
interval(freq);
freq = 220;
interval(freq);_delay_ms(0.25*300);
freq = 196;
interval(freq);_delay_ms(0.25*150);
freq = 330;
interval(freq);_delay_ms(0.25*150);
freq = 392;
interval(freq);_delay_ms(0.25*150);
freq = 440;
interval(freq);_delay_ms(0.25*300);
freq = 349;
interval(freq);_delay_ms(0.25*100);
freq = 392;
interval(freq);_delay_ms(0.25*300);
freq = 330;
interval(freq);_delay_ms(0.25*300);
freq = 262;
interval(freq);_delay_ms(0.25*100);
freq = 294;
interval(freq);_delay_ms(0.25*100);
freq = 247;
interval(freq);_delay_ms(0.25*500);
freq = 262;
interval(freq);_delay_ms(0.25*300);
freq = 262;
interval(freq);_delay_ms(0.25*300);
freq = 262;
interval(freq);_delay_ms(0.25*300);
freq = 196;
interval(freq);_delay_ms(0.25*300);
freq = 196;
interval(freq);_delay_ms(0.25*300);
freq = 196;
interval(freq);_delay_ms(0.25*300);
freq = 164;
interval(freq);_delay_ms(0.25*300);
freq = 164;
interval(freq);_delay_ms(0.25*300);
freq = 164;
interval(freq);_delay_ms(0.25*300);
freq = 220;
interval(freq);_delay_ms(0.25*100);
freq = 220;
interval(freq);_delay_ms(0.25*100);
freq = 220;
interval(freq);_delay_ms(0.25*100);
freq = 246;
interval(freq);_delay_ms(0.25*300);
freq = 233;
interval(freq);
freq = 233;
interval(freq);
freq = 220;
interval(freq);_delay_ms(0.25*300);
freq = 196;
interval(freq);_delay_ms(0.25*150);
freq = 330;
interval(freq);_delay_ms(0.25*150);
freq = 392;
interval(freq);_delay_ms(0.25*150);
freq = 440;
interval(freq);_delay_ms(0.25*300);
freq = 349;
interval(freq);_delay_ms(0.25*100);
freq = 392;
interval(freq);_delay_ms(0.25*300);
freq = 330;
interval(freq);_delay_ms(0.25*300);
freq = 262;
interval(freq);_delay_ms(0.25*100);
freq = 294;
interval(freq);_delay_ms(0.25*100);
freq = 247;
interval(freq);_delay_ms(0.25*900);
freq = 392;
interval(freq);_delay_ms(0.25*100);
freq = 370;
interval(freq);_delay_ms(0.25*100);
freq = 349;
interval(freq);_delay_ms(0.25*100);
freq = 311;
interval(freq);_delay_ms(0.25*300);
freq = 330;
interval(freq);_delay_ms(0.25*300);
freq = 207;
interval(freq);_delay_ms(0.25*100);
freq = 220;
interval(freq);_delay_ms(0.25*100);
freq = 262;
interval(freq);_delay_ms(0.25*300);
freq = 220;
interval(freq);_delay_ms(0.25*100);
freq = 262;
interval(freq);_delay_ms(0.25*100);
freq = 294;
interval(freq);_delay_ms(0.25*500);
freq = 392;
interval(freq);_delay_ms(0.25*100);
freq = 370;
interval(freq);_delay_ms(0.25*100);
freq = 349;
interval(freq);_delay_ms(0.25*100);
freq = 311;
interval(freq);_delay_ms(0.25*300);
freq = 330;
interval(freq);_delay_ms(0.25*300);
freq = 523;
interval(freq);_delay_ms(0.25*300);
freq = 523;
interval(freq);_delay_ms(0.25*100);
freq = 523;
interval(freq);_delay_ms(0.25*1100);
freq = 392;
interval(freq);_delay_ms(0.25*100);
freq = 370;
interval(freq);_delay_ms(0.25*100);
freq = 349;
interval(freq);_delay_ms(0.25*100);
freq = 311;
interval(freq);_delay_ms(0.25*300);
freq = 330;
interval(freq);_delay_ms(0.25*300);
freq = 207;
interval(freq);_delay_ms(0.25*100);
freq = 220;
interval(freq);_delay_ms(0.25*100);
freq = 262;
interval(freq);_delay_ms(0.25*300);
freq = 220;
interval(freq);_delay_ms(0.25*100);
freq = 262;
interval(freq);_delay_ms(0.25*100);
freq = 294;
interval(freq);_delay_ms(0.25*500);
freq = 311;
interval(freq);_delay_ms(0.25*300);
freq = 311;
interval(freq);_delay_ms(0.25*300);
freq = 311;
interval(freq);_delay_ms(0.25*300);
freq = 296;
interval(freq);_delay_ms(0.25*300);
freq = 296;
interval(freq);_delay_ms(0.25*300);
freq = 296;
interval(freq);_delay_ms(0.25*300);
freq = 262;
interval(freq);_delay_ms(0.25*1300);
freq = 262;
interval(freq);_delay_ms(0.25*1300);
freq = 262;
interval(freq);_delay_ms(0.25*1300);
freq = 262;
interval(freq);_delay_ms(0.25*100);
freq = 262;
interval(freq);_delay_ms(0.25*300);
freq = 262;
interval(freq);_delay_ms(0.25*300);
freq = 262;
interval(freq);_delay_ms(0.25*100);
freq = 294;
interval(freq);_delay_ms(0.25*300);
freq = 330;
interval(freq);_delay_ms(0.25*50);
freq = 330;
interval(freq);_delay_ms(0.25*50);
freq = 262;
interval(freq);_delay_ms(0.25*50);
freq = 262;
interval(freq);_delay_ms(0.25*50);
freq = 220;
interval(freq);_delay_ms(0.25*50);
freq = 220;
interval(freq);_delay_ms(0.25*50);
freq = 196;
interval(freq);_delay_ms(0.25*700);
freq = 262;
interval(freq);_delay_ms(0.25*100);
freq = 262;
interval(freq);_delay_ms(0.25*300);
freq = 262;
interval(freq);_delay_ms(0.25*300);
freq = 262;
interval(freq);_delay_ms(0.25*100);
freq = 294;
interval(freq);_delay_ms(0.25*100);
freq = 330;
interval(freq);_delay_ms(0.25*700);
freq = 440;
interval(freq);_delay_ms(0.25*300);
freq = 392;
interval(freq);_delay_ms(0.25*500);
freq = 262;
interval(freq);_delay_ms(0.25*100);
freq = 262;
interval(freq);_delay_ms(0.25*300);
freq = 262;
interval(freq);_delay_ms(0.25*300);
freq = 262;
interval(freq);_delay_ms(0.25*100);
freq = 294;
interval(freq);_delay_ms(0.25*300);
freq = 330;
interval(freq);_delay_ms(0.25*50);
freq = 330;
interval(freq);_delay_ms(0.25*50);
freq = 262;
interval(freq);_delay_ms(0.25*50);
freq = 262;
interval(freq);_delay_ms(0.25*50);
freq = 220;
interval(freq);_delay_ms(0.25*50);
freq = 220;
interval(freq);_delay_ms(0.25*50);
freq = 196;
interval(freq);_delay_ms(0.25*700);
}
return 0;
}