/*
Tirando um som no Arduino Nano, com Dante Meira
*/
unsigned long temposil_inicio = 0; // variável auxiliar para medir tempo de silêncio entre notas
unsigned long temposil_agora = 0; // variável auxiliar para medir tempo de silêncio entre notas
unsigned long tempo1 = 0;
unsigned long tempo2 = 0;
unsigned long long microssegundos1 = 0;
unsigned long long microssegundos2 = 0;
unsigned long long microssegundos3 = 0;
unsigned long long microssegundos4 = 0;
unsigned long tempo_pisca = 0;
// frequências das notas musicais
// fonte: https://www.if.ufrgs.br/cref/ntef/som/oitavas.html
const double Do4 = 261.63;
const double Re4 = 293.66;
const double Mi4 = 329.63;
const double Fa4 = 349.23;
const double Sol4 = 391.99;
const double La4 = 440.00;
const double Si4 = 485.80;
const double Do5 = 523.25;
const double Re5 = 587.33;
const double Mi5 = 659.26;
const double Fa5 = 698.46;
const double Sol5 = 783.99;
const double La5 = 880.00;
const double Si5 = 971.60;
const double Do6 = 1046.5;
const double Re6 = 1174.7;
const double Mi6 = 1318.5;
const double Fa6 = 1396.9;
const double Sol6 = 1568.0;
const double La6 = 1760.0;
const double Si6 = 1943.2;
const double Do7 = 2093.0;
const double Re7 = 2349.3;
const double Mi7 = 2637.0;
const double Fa7 = 2793.8;
const double Sol7 = 3136.0;
const double La7 = 3520.0;
const double Si7 = 3886.4;
double notaAF2;
double notaAF3;
typedef struct{
double nota1;
double nota2;
int silencio; // tempo de silêncio após estas notas
}notas;
notas melodia[22]; // array de struct notas
double hertz = 1;
double aux = 1;
unsigned long intervaloAF2 = 1;
unsigned long intervaloAF3 = 1;
boolean boolAF2 = false;
boolean boolAF3 = false;
boolean intervalo = false; // variável intervalo é iniciada como false
#define AF2 2 // AF2 = autofalante conectado ao pino 2
#define AF3 3 // AF3 = autofalante conectado ao pino 3
#define VERMELHO 12
#define VERDE 11
#define AZUL 10
#define AMARELO 9
int tam_array;
int pos_array;
int mil_inter = 0; // quantidade de milésimos de segundo do intervalo de silêncio atual
void setup() {
pinMode(AF2, OUTPUT);
pinMode(AF3, OUTPUT);
pinMode(VERMELHO, OUTPUT);
pinMode(VERDE, OUTPUT);
pinMode(AZUL, OUTPUT);
pinMode(AMARELO, OUTPUT);
pinMode(13, OUTPUT);
// configurando a sequencia de notas da melodia
melodia[0].nota1 = Do5;
melodia[0].nota2 = Do5;
melodia[0].silencio = 70;
melodia[1].nota1 = Re5;
melodia[1].nota2 = Re5;
melodia[1].silencio = 70;
melodia[2].nota1 = Mi5;
melodia[2].nota2 = Mi5;
melodia[2].silencio = 70;
melodia[3].nota1 = Fa5;
melodia[3].nota2 = Fa5;
melodia[3].silencio = 170;
melodia[4].nota1 = Fa5;
melodia[4].nota2 = Fa6;
melodia[4].silencio = 70;
melodia[5].nota1 = Fa5;
melodia[5].nota2 = Fa6;
melodia[5].silencio = 150;
melodia[6].nota1 = Do5;
melodia[6].nota2 = Do6;
melodia[6].silencio = 70;
melodia[7].nota1 = Re5;
melodia[7].nota2 = Re6;
melodia[7].silencio = 70;
melodia[8].nota1 = Do5;
melodia[8].nota2 = Do6;
melodia[8].silencio = 70;
melodia[9].nota1 = Re5;
melodia[9].nota2 = Re6;
melodia[9].silencio = 170;
melodia[10].nota1 = Re5;
melodia[10].nota2 = Re6;
melodia[10].silencio = 70;
melodia[11].nota1 = Re5;
melodia[11].nota2 = Re6;
melodia[11].silencio = 150;
melodia[12].nota1 = Do5;
melodia[12].nota2 = Do6;
melodia[12].silencio = 70;
melodia[13].nota1 = Sol5;
melodia[13].nota2 = Sol6;
melodia[13].silencio = 70;
melodia[14].nota1 = Fa5;
melodia[14].nota2 = Fa6;
melodia[14].silencio = 70;
melodia[15].nota1 = Mi5;
melodia[15].nota2 = Mi6;
melodia[15].silencio = 170;
melodia[16].nota1 = Mi5;
melodia[16].nota2 = Mi6;
melodia[16].silencio = 70;
melodia[17].nota1 = Mi5;
melodia[17].nota2 = Mi6;
melodia[17].silencio = 170;
melodia[18].nota1 = Do5;
melodia[18].nota2 = Do7;
melodia[18].silencio = 70;
melodia[19].nota1 = Re5;
melodia[19].nota2 = Re7;
melodia[19].silencio = 70;
melodia[20].nota1 = Mi5;
melodia[20].nota2 = Mi7;
melodia[20].silencio = 70;
melodia[21].nota1 = Fa5;
melodia[21].nota2 = Fa7;
melodia[21].silencio = 370;
tam_array = 22; // informando tamanho do array da melodia
pos_array = 0;
while(true){
TocaNotas(melodia);
/* todo o código abaixo da chamada à função TocaNotas será executado durante
os intervalos de silêncio entre uma nota e outra
*/
if( (millis() - tempo_pisca) > 250 ){
digitalWrite(13, ( !(digitalRead(13)) ) );
tempo_pisca = millis();
}
}
}
void TocaNotas(notas melo[]){
if(intervalo == true){
temposil_agora = millis();
if (temposil_agora < temposil_inicio + mil_inter){
return; // sai da função se ainda estiver no período de intervalo entre as notas
}else{
intervalo = false;
}
}
notaAF2 = melo[pos_array].nota1;
notaAF3 = melo[pos_array].nota2;
if(notaAF2 == Do5){
digitalWrite(VERMELHO, HIGH);
digitalWrite(VERDE, LOW);
digitalWrite(AZUL, LOW);
digitalWrite(AMARELO, LOW);
}
if(notaAF2 == Re5){
digitalWrite(VERMELHO, LOW);
digitalWrite(VERDE, HIGH);
digitalWrite(AZUL, LOW);
digitalWrite(AMARELO, LOW);
}
if(notaAF2 == Mi5){
digitalWrite(VERMELHO, LOW);
digitalWrite(VERDE, LOW);
digitalWrite(AZUL, HIGH);
digitalWrite(AMARELO, LOW);
}
if(notaAF2 == Fa5){
digitalWrite(VERMELHO, LOW);
digitalWrite(VERDE, LOW);
digitalWrite(AZUL, LOW);
digitalWrite(AMARELO, HIGH);
}
tempo2 = millis();
microssegundos1 = micros();
microssegundos2 = micros();
microssegundos3 = micros();
microssegundos4 = micros();
hertz = notaAF2;
aux = (1000000/hertz) ;
intervaloAF2 = round(aux);
hertz = notaAF3;
aux = (1000000/hertz) ;
intervaloAF3 = round(aux);
while(tempo1 < (tempo2 + 80)){ // cada nota tem duração de 80 milissegundos
if( microssegundos2 < microssegundos1 + intervaloAF2){
microssegundos2 = micros();
}else{
microssegundos1 = micros();
if(boolAF2 == false){
boolAF2 = true;
digitalWrite(AF2, HIGH);
}else{
boolAF2 = false;
digitalWrite(AF2, LOW);
}
}
if( microssegundos4 < microssegundos3 + intervaloAF3){
microssegundos4 = micros();
}else{
microssegundos3 = micros();
if(boolAF3 == false){
boolAF3 = true;
digitalWrite(AF3, HIGH);
}else{
boolAF3 = false;
digitalWrite(AF3, LOW);
}
}
tempo1 = millis();
asm volatile ("nop \n\t");
}
if(intervalo == false){
temposil_inicio = millis();
mil_inter = melo[pos_array].silencio; // milésimos de segundo para o próximo intervalo de silêncio
if(pos_array == tam_array-1){ pos_array = 0; }else{ pos_array++ ; }
intervalo = true;
}
}