Essa é minha primeira postagem neste blog. Minha intenção é compartilhar um pouco do que estou aprendendo sobre microcontroladores e outros assuntos relacionados. Contribuições, sugestões e criticas serão sempre bem vindas.
A idéia de fazer o Arduino tocar um xilofone surgiu quase que por acaso. Eu estava vendo alguns vídeos sobre CNC, pois queria construir algo para confecção de placas de circuito impresso, percebi que não seria tão fácil assim. Lembrei então do pequeno xilofone de minha filha de três anos e tive a idéia de fazer com que o arduino o tocasse.
O Arduino
Foto do site arduino.cc |
O funcionamento básico
O carro é movido até a primeira nota a ser tocada. Após tocar a primeira nota começa a contar o tempo de intervalo entre esta e a segunda nota enquanto move o carro para tocá-la . Ao se posicionar para tocar a segunda nota verifica se o tempo de interva-lo foi concluido. Se sim toca a segunda nota imediatamente, caso contrario aguara a conclusão da contagem de tempo antes de tocar. Esse processo se repete para todas as notas até o fim da música. É importante notar que a capacidade de movimento do conjunto limita o andamento máximo da música.
A estrutura mecânica
A parte mecânica é composta basicamente de rosca sem fim e carro, peças retiradas de uma velha impressora matricial que eu estava guardando há muito tempo sem saber se um dia serviria para algo. A estrutura onde foi montado o conjunto foi feita em madeira, improvisei rolamentos nas extremidades do sem fim para facilitar o giro. O que eu chamo de carro é o conjunto formado por pequeno cilindro plástico com uma espécie de rosca interna que, quando acoplado ao sem fim se movimenta horizontalmente em função da rotação deste e uma chapa fina de alumínio dobrada de modo à funcionar como uma mola. Esta chapa carrega uma pequena solenóide retirada de uma antiga secretária eletrônica e a baqueta que é acionada pela solenóide, e retorna a posição de descanso pela força da chapa de alumínio.
A estrutura eletroeletrônica
Para controlar o sentido de rotação do motor foram usados dois relés. Cada relé quando acionado pelo arduino faz o motor gira em um sentido. Um TIP 120 foi adicionado para possibilita o controle da rotação do motor por PWM mas, com os testes prático ficou melhor usar sempre o PWM máximo.
O programa
O programa funciona mas ainda esta longe de ser o ideal. Preciso trocar os vetor int por char usar strlen pra não precisra informar a quantidade de notas da música a ser tocada. Vou tentar também faser alterações para poder enviar a musica via serial no formato MIDI.
Abaixo você tem o código comentado. A idéia pricipal é a seguinte:
- A música é armazenada em um vetor;
- As notas são armazanadas neste vetor seguidas do multiplicador do tempo de intervalo entre uma nota e a proxima. { nota, intervalo, nota, intervalo, ..........};
- Para represntar as notas foi usada a notação: C , D, E, F, G, A, B, c para respectivamente dó (mais grave), ré mi, fá, sol, lá, sí, dó (mais agudo).
- Como para cada posição do carro é atribuido um valor inteiro. O valor referente a nota a ser tocada é comparado com o valor da posição atual do carro. A partir dessa comparação decide-se o sentido de movimentação do carro.
Código
int C = 1000; // dó mais grave
int D = 905;
int E = 808;
int F = 710;
int G = 614;
int A = 516;
int B = 417;
int c = 334; // dó mais agudo
int tempo = 130; // pausa entre notas
long previousMillis = 0; // usada para cotar o tempo que o carro leva para ir de uma noa para outra
int potPin = 0; // pino do potenciometro (usado como sensor de posição)
int baquetaPin = 2; // pino que acionara a solenoide (ligada abaqueTA)
int esquerdaPin = 3; // pino do relé sentido horario ( carro para esquerda)
int direitaPin = 5; // pino do relé sentido antihorario ( carro para direita)
int pwmPin = 9; // pino PWM velocidade de rotação do motor
int i=0;
float soma =0;
float val;
////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////
//////////////////// MUSICAS//////////////////////////////////
int qtdNotas = 164;
int quero_ver[195] = {E,1,D,1,C,1,D,1,E,1,F,1,E,1,D,1,E,1,F,1,
G,1,F,1,E,1,F,1,G,1,A,1,G,1,F,1,E,1,F,1,
D,4,
E,1,D,1,C,1,D,1,E,1,F,1,E,1,D,1,E,1,F,1,
G,1,F,1,E,1,F,1,G,1,A,1,G,1,F,1,G,1,A,1,
B,4,
c,1,B,1,A,1,G,1,A,1,B,1,A,1,G,1,F,1,G,1,
A,1,G,1,F,1,E,1,F,1,D,4,
D,1,E,1,F,1,G,1,F,2,E,2,E,1,F,1,G,1,A,1,
G,2,F,2,F,1,G,1,A,1,B,1,A,2,G,1,B,4,c,1,
B,1,A,1,G,1,A,1,B,1,A,1,G,1,F,1,G,1,A,1,
G,1,F,1,E,1,F,1,D,4,E,2,F,2,D,4,C,8,0};
/*int ia_ia_oh[105] = {F,2,F,2,F,1,C,1,D,2,D,2,C,1,A,2,A,2,G,2,
G,2,F,4,
F,2,F,2,F,1,C,1,D,2,D,2,C,1,A,2,
A,2,G,2,G,2,F,4,
C,2,C,1,F,2,F,2,F,1,C,1,
D,3,
C,2,C,1,F,2,F,2,F,1,C,2,D,3,
C,2,C,1,
F,2,F,2,F,1,C,2,D,2,D,2,C,1,A,2,
A,2,G,2,
G,2,F,16,0};*/
int asa_br[164] = {C,2,D,2,E,4,G,4,G,4,E,4,F,12,C,2,D,2,E,4,
G,4,G,4,F,2,E,10,
C,2,C,1,D,2,E,5,G,6,G,2,F,2,E,2,C,3,F,5,E,2,E,2,D,2,D,3,E,6,D,2,D,2,C,2,C,5,
C,2,C,1,D,2,E,5,G,6,G,2,F,2,E,2,C,3,F,5,E,2,E,2,D,2,D,3,E,6,D,2,D,2,C,2,C,5,
c,1,A,1,B,1,G,1,A,1,F,1,G,1,E,1,F,1,D,1,E,1,
C,2,C,2,D,4,C,4,
c,1,A,1,B,1,G,1,A,1,F,1,G,1,E,1,F,1,D,1,E,1,
C,2,C,2,D,4,C,8};
////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////
void setup()
{
pinMode(potPin, INPUT);
pinMode(baquetaPin, OUTPUT);
pinMode(esquerdaPin, OUTPUT);
pinMode(direitaPin, OUTPUT);
pinMode(pwmPin, OUTPUT);
}
//////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////
void loop()
{
val = analogRead(potPin);
int i ;
int *aux;
aux = asa_br;
posicione(aux[0]); // move o carro para primeira nota
for(i=0;i<qtdNotas; i=i+2) // toca todas as notas
tocar(aux[i+2], aux[i+1]); // chama a função tocar passando a px nota e o tempo
}
//////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////
void tocar(int nota, int pausa) // função tocar
{
previousMillis = millis(); // millis retorna o tempo de excução do programa até este ponto
digitalWrite(baquetaPin, HIGH); // toca a nota
delay(10); //
digitalWrite(baquetaPin, LOW); //
posicione(nota);
if( (tempo * pausa) > int(millis() - previousMillis)) // se pausa entre notas for maior que o tempo gasto para
delay((tempo * pausa) - int(millis() - previousMillis) ); // mover o carro ate a nota completa a pausa antes de tocar
}
//////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////
void posicione(int nota) // posiciona o carro na posição da nota a ser tocada
{
while(val < nota -5 || val > nota + 5) // tolerancia da posição + ou - 5
{
if(val > nota + 5) // se o carro estiver a esquerda da nota a ser tocada
{
digitalWrite(direitaPin, HIGH); // move o carro para a direita
analogWrite(pwmPin,255); // manda o pulso PWM por 200 microsegundos
delayMicroseconds(150); //
analogWrite(pwmPin,0); // zera PWM
digitalWrite(direitaPin,LOW); // abre relé
val = analogRead(potPin); // lê posição
}
else if(val < nota - 5) // se o carro estiver a direita da nota a ser tocada
{
digitalWrite(esquerdaPin, HIGH); // move o carro para a esquerda alimenta o relé correspondente
analogWrite(pwmPin,255); // manda o pulso PWM
delayMicroseconds(150); // por 200 microsegundos
analogWrite(pwmPin,0); // zera PWM
digitalWrite(esquerdaPin,LOW); // abre relé
val = analogRead(potPin); // lê posição
}
}
}
Nenhum comentário:
Postar um comentário