quinta-feira, 19 de novembro de 2015

Código Arduíno para montar um Trombone com sensor ultrassom e um botão para acionamento das notas MIDI

Código Arduíno para montar um Trombone com sensor ultrassom e um botão para acionamento das notas MIDI

A Fig. 1 mostra o esquema de conexão feito no Fritzing.
Figura 1: Esquema de conexão feito no Fritzing

A Fig. 2 mostra a montagem do circuito do Trombone utilizando um protoboard.
Figura 2: Montagem do circuito do Trombone utilizando um protoboard.

A Fig. 3 mostra o diagrama de funcionamento do Trombone Eletrônico.
Figura 3: Diagrama de funcionamento do Trombone Eletrônico.


Observações:
  • Projeto feito para a obtenção de nota na disciplina "Projeto Interdisciplinar de Engenharia II" da UCL (Serra - ES - Brasil).
  • Funcionando corretamente.
  • Foi utilizado um Funduíno UNO (equivalente ao Arduino UNO).
  • O código foi feito utilizando o programa do Arduíno (disponível gratuitamente em https://www.arduino.cc/) e utilizando o site do Codebender (https://codebender.cc/), que permite a edição, compilação e carregamento do programa na placa Arduíno.
    • Eu prefiro editar no Codebender, pois a verificação e a compilação do código foram mais rápidas, o que agiliza o teste à medida em que são feitas modificações no programa. Além disso, o Codebender armazena o código, permitindo a edição onde houver acesso à internet disponível.
  • Utiliza um sensor ultrassom.
  • Utiliza um botão para executar as notas quando acionado.
    • Para o botão funcionar, foram utilizados 2 resistores de 4,6kOhm em série (aproximadamente 10kOhm).
  • Está programado para acionar dez notas (uma a uma) numa distância de 0 a 50cm. Acima de 50cm de distância captada pelo ultrassom, o equipamento não emite notas.
  • A programação pode ser alterada:
    • acrescentando ou retirando notas MIDI, modificando-se os intervalos de distância;
    • aumentando ou diminuindo a distância limite de 50cm associada ao intervalo de notas conforme a medição do ultrassom.
  • O código conta com comentários explicativos ao longo das linhas para facilitar a compreensão.
  • O sensor ultrassom foi fixado com fita isolante no fim de um tubo para esgoto de 50mm de diâmetro.
  • A vara móvel do trombone foi feita com eletroduto de 1/2". Dentro do tubo de 50mm foi fixado no eletroduto um frasco de desodorante aerosol (o fundo do frasco foi "retificado" com fita isolante para ficar reto). Na frente do trombone foi colocado um tampão com um furo para a vara (de eletroduto) correr.
Softwares utilizados:
  • Arduino / Codebender;
  • loopMIDI
  • Hairless
  • Reaper
  • Kontakt 5

O código está disponível abaixo, entre aspas.

"
// Definindo os pinos Echo (recepção do ultrassom) e Trigger (gatilho, disparo do ultrassom)
#define echoPin 13 //Pino 13 recebe o pulso do echo
#define trigPin 12 //Pino 12 envia o pulso para gerar o echo
#define botaoacionador 2 //Pino 2 envia o sinal do botão acionador do trombone

// Liga e desliga as notas midi
const byte noteOffCommand = 0;
const byte noteOnCommand = 1;

// Tempo de duração das notas (em milissegundos)
int tempodasnotas = 90;

// Tempo de intervalo entre as notas (em milissegundos)
int tempoentrenotas = 120;

// Tempo de espera se a distância for maior que 50cm (em milissegundos)
int tempodeespera = 100;

// Interruptor de Acionamento do Trombone
int acionador = 0; // variável para ler o estado do botão acionador do trombone

// Notas midi
int nota1 = 36; // Nota C (Dó)
int nota2 = 38; // Nota D (Ré)
int nota3 = 40; // Nota E (Mi)
int nota4 = 41; // Nota F (Fá)
int nota5 = 43; // Nota G (Sol)
int nota6 = 45; // Nota A (Lá)
int nota7 = 47; // Nota B (Si)
int nota8 = 48; // Nota C (Dó)
int nota9 = 50; // Nota D (Ré)
int nota10 = 52; // Nota E (Mi)
//fim das notas midi

//variável para armazenar a nota a executar
int notaaexecutar = 0;

//variável para armazenar a nota anteriormente tocada
int notaanterior = 1;

//variável para armazenar a distancia anteriormente medida
int distanciaanterior = 0;

//variável para armazenar o estado do botão (0 para desligado e 1 para ligado)
int botao = 0;

// variável que informa se o botão foi acionado agora (1) ou não (0)
int botaoacionadoagora = 2;

// variável distancia limite de 50cm atingida (1) ou não atingida (0)
int distancialimite = 2;
// variável informa que a distancia permanece além do limite de 50cm (1) ou não (0)
int zonafora = 2;
// variável informa que a distancia saiu da zona fora do limite de 50cm agora (1) ou não (0)
int saiudazonaforaagora = 2;

byte channel = 0;  // Channel 1  (0-15 selects channel 1-16)

//byte pitchByte = 69;  // A4 = Middle A = 440 Hz (Piano keyboard runs from 21/A0 to 108/C8)
//byte velocityByte = 127;  // Medium Velocity/Volume (value from 0 to 127)

// Configuração do Setup
void setup()
{
   Serial.begin(115200); //inicia a porta serial (115200 para o HairLess, pode ser modificada no Hairless)
   pinMode(echoPin, INPUT); // define o pino 13 como entrada (recebe)
   pinMode(trigPin, OUTPUT); // define o pino 12 como saida (envia)
   pinMode(botaoacionador, INPUT); // define o botão acionador como entrada (recebe)
}

// Inicia o loop de verificações de distâncias e emissão de notas midi
void loop()
{

// Configurando o botão de acionamento
acionador = digitalRead(botaoacionador); // Lê o valor de entrada do botão (HIGH ou LOW)
if (acionador == HIGH) { // verifica se a entrada é HIGH (interruptor livre)

// Se o botão estava pressionado, ele vai desarmar a nota tocada anteriormente
if (botao == 1) {
// estado da variável botão passa para desligado
botao = 0;

// reseta a variável distanciaanterior
distanciaanterior = 0;

if (notaaexecutar != 0 && zonafora == 0){
// desliga a nota MIDI "notaaexecutar" executada anteriormente quando o botão estava apertado
Serial.write(0x80 + (noteOffCommand << 4) + (byte(channel)));
Serial.write(byte(notaaexecutar));
Serial.write(byte(0));
}
}
if (botao == 0) {
delay(1); // espera 1 milissegundo
}
} else {
if (botao == 0){
// variável botao grava que o botao está pressionado
botao = 1;
// variável que informa se o botão foi acionado agora (1)
botaoacionadoagora = 1;
}

// Realizando a medida com o ultrassom
  //seta o pino 12 com um pulso baixo "LOW" ou desligado ou ainda 0
    digitalWrite(trigPin, LOW);
  // delay de 2 microssegundos
    delayMicroseconds(2);
  //seta o pino 12 com pulso alto "HIGH" ou ligado ou ainda 1
    digitalWrite(trigPin, HIGH);
  //delay de 10 microssegundos
    delayMicroseconds(10);
  //seta o pino 12 com pulso baixo novamente
    digitalWrite(trigPin, LOW);
  //pulseInt lê o tempo entre a chamada e o pino entrar em high
    long duration = pulseIn(echoPin,HIGH);
  //Esse calculo é baseado em s = v . t, lembrando que o tempo vem dobrado
  //porque é o tempo de ida e volta do ultrassom
    long distancia = duration /29 / 2 ;

// se a distância medida pelo ultrassom permanecer constante, a nota MIDI continua a ser executada
if (distanciaanterior == distancia){
  // Tempo de espera para checar a distância até o ultrassom novamente
  delay(tempodeespera);
}

// se a distância medida pelo ultrassom variar, a nota MIDI a ser executada muda
else {

// Se a distancia medida for menor que 50cm
if (distancia < 50){
// Se a distancia anterior estava fora do limite de 50cm
if (zonafora == 1){
// variável informa que a distancia não está fora do limite de 50cm
zonafora = 0;

// variável distancialimite indica que a distancia de 50cm não foi atingida (0)
distancialimite = 0;

// variável informa que a distancia saiu da zona fora do limite de 50cm (1)
saiudazonaforaagora = 1;
}
if (zonafora == 2);{
// variável informa que a distancia não está fora do limite de 50cm
zonafora = 0;
}
}

// Se a distancia medida for maior que 50cm
if (distancia > 50){ // distância máxima de captação limitada em 50cm
    // variável distancia limite de 50cm atingida
    distancialimite = 1;
}

// Se a distancia limite de 50cm for atingida (1)
if (distancialimite == 1){
if (zonafora == 0  || zonafora ==2){  
// variável informa que a distancia está fora do limite de 50cm (1)
zonafora = 1;

if (notaanterior != 1){
    // desliga a nota MIDI "notaanterior" executada anteriormente quando o botão estava apertado
Serial.write(0x80 + (noteOffCommand << 4) + (byte(channel)));
Serial.write(byte(notaanterior));
Serial.write(byte(0));
}
}
}

// a variável notaaexecutar recebe um novo valor conforme a distancia medida pelo ultrassom
if (distancia <= 5){
notaaexecutar = nota1; // a variável notaaexecutar recebe o valor da variável nota1
}

else if ((distancia > 5) && (distancia <= 10)){
notaaexecutar = nota2; // a variável notaaexecutar recebe o valor da variável nota2
}

else if ((distancia > 10) && (distancia <= 15)){
notaaexecutar = nota3; // a variável notaaexecutar recebe o valor da variável nota3
}

else if ((distancia > 15) && (distancia <= 20)){
notaaexecutar = nota4; // a variável notaaexecutar recebe o valor da variável nota4
}

else if ((distancia > 20) && (distancia <= 25)){
notaaexecutar = nota5; // a variável notaaexecutar recebe o valor da variável nota5
}

else if ((distancia > 25) && (distancia < 30)){
notaaexecutar = nota6; // a variável notaaexecutar recebe o valor da variável nota6
}

else if ((distancia > 30) && (distancia <= 35)){
notaaexecutar = nota7; // a variável notaaexecutar recebe o valor da variável nota7
}

else if ((distancia > 35) && (distancia <= 40)){
notaaexecutar = nota8; // a variável notaaexecutar recebe o valor da variável nota8
}

else if ((distancia > 40) && (distancia <= 45)){
notaaexecutar = nota9; // a variável notaaexecutar recebe o valor da variável nota9
}

else if ((distancia > 45) && (distancia <= 50)){
notaaexecutar = nota10; // a variável notaaexecutar recebe o valor da variável nota10
}

// Se o botão foi acionado agora
if (botaoacionadoagora == 1  && zonafora != 1) {
// Toca a nota MIDI correspondente à distância medida pelo ultrassom
    Serial.write(0x80 + (noteOnCommand << 4) + (byte(channel)));
    Serial.write(byte(notaaexecutar));
    Serial.write(byte(127));

    // Tempo de espera para checar a distância até o ultrassom novamente
    delay(tempoentrenotas);

    // a variável distancia anterior receber o valor da distancia medida após a execução da nota MIDI
    distanciaanterior = distancia;
 
    // a variável notaanterior receber o valor da nota MIDI executada
    notaanterior = notaaexecutar;

// variável botaoacionadoagora informa que o botão já foi acionado (0)
botaoacionadoagora = 0;
}

// Se a distancia medida saiu da zona fora do limite de 50cm agora (1)
else if (saiudazonaforaagora == 1) {
// Toca a nota MIDI correspondente à distância medida pelo ultrassom
    Serial.write(0x80 + (noteOnCommand << 4) + (byte(channel)));
    Serial.write(byte(notaaexecutar));
    Serial.write(byte(127));

    // Tempo de espera para checar a distância até o ultrassom novamente
    delay(tempoentrenotas);

    // a variável distancia anterior receber o valor da distancia medida após a execução da nota MIDI
    distanciaanterior = distancia;
 
    // a variável notaanterior receber o valor da nota MIDI executada
    notaanterior = notaaexecutar;

// variável botaoacionadoagora informa que o botão já foi acionado (0)
saiudazonaforaagora = 0;
}

// Se a nota a ser executada for igual à nota midi anterior
else if (notaaexecutar == notaanterior || notaaexecutar == 0) {
    // Tempo de espera para checar a distância até o ultrassom novamente
    delay(tempodeespera);
}

// Se a nota a ser executada for diferente da nota MIDI anteriormente executada
else {

// Se a variável notaanterior for diferente de 1, desliga a nota anteriormente tocada
if (notaanterior != 1){
    // desliga a nota MIDI "notaanterior" executada anteriormente quando o botão estava apertado
Serial.write(0x80 + (noteOffCommand << 4) + (byte(channel)));
Serial.write(byte(notaanterior));
Serial.write(byte(0));
}

    // Toca a nota MIDI correspondente à distância medida pelo ultrassom
    Serial.write(0x80 + (noteOnCommand << 4) + (byte(channel)));
    Serial.write(byte(notaaexecutar));
    Serial.write(byte(127));

    // Tempo de espera para checar a distância até o ultrassom novamente
    delay(tempoentrenotas);

    // a variável distancia anterior receber o valor da distancia medida após a execução da nota MIDI
    distanciaanterior = distancia;
 
    // a variável notaanterior receber o valor da nota MIDI executada
    notaanterior = notaaexecutar;
}

}
}

//final do programa
}
"

Lucas T R Freitas

Nenhum comentário: