Estou desenvolvendo um joguinho baseado no uso de LDR,mas com um problema.. O código que estou usando para o protótipo do jogo é simples: jogodotempoversaoum.ino

O jogo deve funcionar da seguinte forma: o LDR estará recebendo um feixe de luz de um laser (desses de R$1,99), enquanto ele estiver recebendo essa luz, o buzzer estará tocando uma melodia. Quando o laser for interrompido (pela passagem da mão de alguém), a melodia deverá parar e as funções de funcionamento dos botões serão ativadas. ( um liga o led e o outro faz o buzzer apitar.).

O problema é que com o código que fiz, quando o LDR lê o laser ele toca a melodia até o fim, independente da luz continuar nele ou não. Gostaria de fazer a melodia parar (estando no fim ou não) e os botões serem habilitados logo após a interrupção do feixe de luz.

Alguém pode ajudar?

O código é:

int ldr = 0;

int value = A0;

const int buttonA = 4; // entrada digital onde está o primeiro botão

const int buttonB = 5; // entrada digital onde est[a o segundo botão

int buttonAstate = 0;

int buttonBstate= 0;

int led = 6;// led conectado na porta digital 6

void setup()

{

Serial.begin(9600);

pinMode(10,OUTPUT); // buzzer conectado na porta digital 10

pinMode(buttonA,INPUT);

pinMode(buttonB,INPUT);

pinMode(led,OUTPUT);

}

void loop()

{

int value = analogRead(ldr); // faz a leitura do sensor de luz

if( value <700)

{

buttonAstate = digitalRead(buttonA); // le o primeiro botão

buttonBstate = digitalRead (buttonB);//le o segundo botão

if (buttonAstate == LOW) // faz o buzzer apitar sem que o led acenda

{

tone(10,1000,400);

digitalWrite(led,LOW);

}

if (buttonBstate == LOW) // faz o led ligar quando o botão estiver sendo pressionado

{

digitalWrite(led,HIGH);

}

if (buttonBstate == HIGH)

{

digitalWrite(led,LOW);

}

}

Serial.println(value); // mostra o valor de luz recebido pelo ldr no monitor serial

delay(50);

if(value >=700)

{

// caso o valor seja maior do que o definido, toca uma melodia no buzzer

tone(10,5000,1000);

delay(1000);

tone(10,5000,1000);

delay(1000);

tone(10,6000,1000);

delay(1000);

tone(10,7000,1000);

delay(1000);

tone(10,7000,1000);

delay(1000);

tone(10,6000,1000);

delay(1000);

tone(10,5000,1000);

delay(1000);

tone(10,4500,1000);

delay(1000);

tone (10,4000,1000);

delay(1000);

tone (10,4000,1000);

delay(1000);

tone(10,4500,1000);

delay(1000);

tone(10,5000,1000);

delay(1000);

tone(10,5000,1000);

delay(1000);

tone(10,4500,1000);

delay(1000);

tone(10,4500,2000);

delay(2000);

tone(10,5000,1000);

delay(1000);

tone(10,5000,1000);

delay(1000);

tone(10,6000,1000);

delay(1000);

tone(10,7000,1000);

delay(1000);

tone(10,7000,1000);

delay(1000);

tone(10,6000,1000);

delay(1000);

tone(10,5000,1000);

delay(1000);

tone(10,4500,1000);

delay(1000);

tone(10,4000,1000);

delay(1000);

tone(10,4000,1000);

delay(1000);

tone(10,4500,1000);

delay(1000);

tone(10,5000,1000);

delay(1000);

tone(10,4500,1000);

delay(1000);

tone(10,4000,1000);

delay(1000);

tone(10,4000,2000);

delay(5000);

}

}

Exibições: 6958

Responder esta

Respostas a este tópico

Você respondeu a sua dúvida:

Gostaria de fazer a melodia parar (estando no fim ou não) e os botões serem habilitados logo após a interrupção do feixe de luz.

http://labdegaragem.com/profiles/blogs/tutorial-utilizando-interrup...

http://arduino.cc/en/Reference/AttachInterrupt

Uma dica é você quebrar essa estrutura "sequencial" da música.

Uma opção seria armazenar (pode ser até em EEPROM) as notas e os delays em uma matriz 4xN, onde N é o número de notas, e ir executando as notas dentro de um laço de repetição.

Um jeito menos cientifico, menos polido mas mais simples seria vc criar uma nova função Delay, que em vez de fazer um delay de 1000 por ex faria 1000 delays de 1 (ou 100 delays de 10).

Essa rotinha primeiro testaria se ja houve a interrupção do feixe, em uma variavel. Se sim sai sem fazer nada.

Se não ela faz em loop o delay e o teste do feixe. Se estiver interrompido seta a tal variavel.

Nao sei se fui claro, mas a ideia seria basicamente aproveitar o tempo que ficaria parado no delay para verificar se houve interrupcao do feixe, se sim memoriza isso pra no resto da musica passar rapidinho (inaudivel). Essa variavel seria resetada para rearme depois.

 Olá Rebeca,

 Como o Jonatas disse é interessante criar uma matriz com as notas e as durações delas. Aproveitando um código que já havia feito, você pode usar a seguinte estrutura:

// Definicoes de Tempo
#define T_333_MSEG       333
#define T_1_SEG         1000
#define T_2_SEG         2000
#define T_4_SEG         4000

// Definicoes de Notas
#define NOTA_1          4000
#define NOTA_2          4500
#define NOTA_3          5000
#define NOTA_4          6000
#define NOTA_5          7000

// Definicao da estrutura da nota
struct Melodia{
    unsigned int _freq;  // Frequencia da nota
    unsigned int _delay; // Duracao da nota
    unsigned int _mult;  // Multiplicador da duracao = Precisao de leitura
};

// Definicao de uma melodia
struct Melodia Musica_1[] = {{NOTA_3,T_333_MSEG,3},  // 1
                                           {NOTA_3,T_333_MSEG,3},  // 2
                                           {NOTA_1,T_333_MSEG,3}}; // 3

#define NumeroDeNotas   3

Onde você cria uma tabela, e para cada nota você apenas desloca o vetor do array.  Caso queira você pode criar um array contendo várias músicas também, não somente a Musica_1.

E conforme a dica dele sobre a interrupção e o que o Eduardo disse sobre segmentar a duração da nota, realmente você teria que implementar algo do tipo para poder ter mais "precisão" na hora de parar a música e reiniciá-la. E existem dois grandes vilões para isto, a função "delay" que faz você ficar parado naquele trecho de código, te impedindo de verificar a entrada analógica, e a própria função "tone", que não é capaz de te informar o tempo decorrido da nota, ou mesmo informar se ela já parou de ser tocada ou não.

Para isto eu estava implementando o método do Eduardo, que é segmentar a duração. Por exemplo, para 1 segundo, podemos segmentar o tempo em 3 intervalos de aproximadamente 333 milisegundos. E essa será a precisão do tempo para o sensor atuar sobre a música. Segmentando mais, você tem mais precisão, mas pode prejudicar outras funções, como a própria função tone. Faça experimentos.

E não descarte verificar a versão com interrupções, que é a forma de se aproveitar melhor os recursos do microcontrolador.

Para melhorar o tom das notas, crie contantes com as tabelas de frequências de notas musicais, como a seguir:

Segue meu código de exemplo.

T+.

// Definicoes de Tempo
#define T_333_MSEG       333
#define T_1_SEG         1000
#define T_2_SEG         2000
#define T_4_SEG         4000

// Definicoes de Notas
#define NOTA_1          4000
#define NOTA_2          4500
#define NOTA_3          5000
#define NOTA_4          6000
#define NOTA_5          7000

// Definicao da estrutura da nota
struct Melodia{
    unsigned int _freq;  // Frequencia da nota
    unsigned int _delay; // Duracao da nota
    unsigned int _mult;  // Multiplicador da duracao = Precisao de leitura
};

// Definicao de uma melodia
struct Melodia Musica_1[] = {{NOTA_3,T_333_MSEG,3},  // 1
                             {NOTA_3,T_333_MSEG,3},  // 2
                             {NOTA_4,T_333_MSEG,3},  // 3
                             {NOTA_5,T_333_MSEG,3},  // 4
                             {NOTA_5,T_333_MSEG,3},  // 5
                             {NOTA_4,T_333_MSEG,3},  // 6
                             {NOTA_3,T_333_MSEG,3},  // 7
                             {NOTA_2,T_333_MSEG,3},  // 8
                             {NOTA_1,T_333_MSEG,3},  // 9
                             {NOTA_1,T_333_MSEG,3},  // 10
                             {NOTA_2,T_333_MSEG,3},  // 11
                             {NOTA_3,T_333_MSEG,3},  // 12
                             {NOTA_3,T_333_MSEG,3},  // 13
                             {NOTA_2,T_333_MSEG,3},  // 14
                             {NOTA_2,T_333_MSEG,6},  // 15
                             {NOTA_3,T_333_MSEG,3},  // 16
                             {NOTA_3,T_333_MSEG,3},  // 17
                             {NOTA_4,T_333_MSEG,3},  // 18
                             {NOTA_5,T_333_MSEG,3},  // 19
                             {NOTA_5,T_333_MSEG,3},  // 20
                             {NOTA_4,T_333_MSEG,3},  // 21
                             {NOTA_3,T_333_MSEG,3},  // 22
                             {NOTA_2,T_333_MSEG,3},  // 23
                             {NOTA_1,T_333_MSEG,3},  // 24
                             {NOTA_1,T_333_MSEG,3},  // 25
                             {NOTA_2,T_333_MSEG,3},  // 26
                             {NOTA_3,T_333_MSEG,3},  // 27
                             {NOTA_2,T_333_MSEG,3},  // 28
                             {NOTA_1,T_333_MSEG,3},  // 29
                             {NOTA_1,T_333_MSEG,3}}; // 30

#define NumeroDeNotas   30

// Definicao de pinos
#define buttonA         4    // entrada digital onde esta o primeiro botao
#define buttonB         5    // entrada digital onde esta o segundo botao
#define led             6    // led conectado na porta digital 6
#define value           A0   // entrada do sensor de luz
#define PINO_BUZZER     10

// Definicao de variaveis
int ldr = 0;
int buttonAstate = 0;
int buttonBstate= 0;

// Nivel do Sensor
#define SENSOR_LEVEL    700

void setup()
{
        Serial.begin(9600);
        
        pinMode(PINO_BUZZER,OUTPUT);

        pinMode(buttonA,INPUT);
        pinMode(buttonB,INPUT);
        pinMode(led,OUTPUT);
}

void loop()
{
        if(SensorRead()){
                // leitura dos botoes
                buttonAstate = digitalRead(buttonA);
                buttonBstate = digitalRead (buttonB);

                // faz o buzzer apitar sem que o led acenda
                if (buttonAstate == LOW){
                        tone(10,1000,200);
                        digitalWrite(led,LOW);
                }

                // faz o led ligar quando o botao estiver sendo pressionado
                if (buttonBstate == LOW){
                        digitalWrite(led,HIGH);
                }else{
                        digitalWrite(led,LOW);
                }
        }else{
                // Garante led apagado
                digitalWrite(led,LOW);

                TocaUmaNota();
        }

}

// Pode ser chamado por interrupcao
unsigned int TocaUmaNota(){
        static unsigned int i = 0;

        // Toca uma nota
        tone(PINO_BUZZER, Musica_1[i]._freq, Musica_1[i]._delay);

        // Segura o tempo da nota // Piora precisao
        //delay(Musica_1[i]._delay);

        // Segura o tempo da nota e verifica se deve parar
        for(int j=0;j<Musica_1[i]._mult;j++){

                delay(Musica_1[i]._delay);

                if(!SensorRead()){
                    // Deve parar a nota
                    j = Musica_1[i]._mult;
                }
        }
        
        // Avanca uma nota
        i++;
        
        // Verifica se ja terminou a musica
        if(i<NumeroDeNotas){
          return 1;
        }else{
          // Interrompe a melodia
          noTone(PINO_BUZZER);
                    
          // Retorna para o inicio e avisa que ja terminou
          i=0;
          return 0;
        }
}

unsigned int SensorRead()
{
        // faz a leitura do sensor de luz
        int value = analogRead(ldr);

        // mostra o valor de luz recebido pelo ldr no monitor serial
        Serial.println(value);

        if(value < SENSOR_LEVEL){
                return 1;
        }else{
                return 0;
        }
}

=) Obrigada! Deu certinho agora, só vou tentar alterar a melodia, mas o modelo que você fez faz exatamente o que precisava ^^ 

RSS

© 2024   Criado por Marcelo Rodrigues.   Ativado por

Badges  |  Relatar um incidente  |  Termos de serviço