Ir ao conteúdo

Posts recomendados

Postado

Boa tarde.

Estou tentando fazer um metrônomo com arduino, é basicamente assim:

Tem um dip switch de 4 vias, cada via faz 1 led apagar. São 4 leds no total, eles acendem em sequência como um knight rider, e cada vez que um acende, é reproduzido uma frequência, sendo que o primeiro led é mais agudo.

Então, acionando a primeira via do dip, 4 leds acendem em sequência e isso fica em loop, acionando a segunda, apenas 3 leds, e assim por diante.

Ele tem que ser de 20 à 240 bpm, isso é 1/3 Hz à 4 Hz, ou seja, 3000 ms à 250 ms de delay. Então um potenciômetro controla a frequência, e também tem um pra controlar o volume do falante.

Liguei o potenciômetro da frequência no A0, mas queria limitar a frequência pra faixa que eu queria.

Não conheço muito de arduino, o que eu fiz foi o seguinte: como o análogo lê valores inteiros entre 0 e 1023, fiz uma equação matricial, obtive que x = -250/93 e y = 3000.

1023 * (-250/93) + 3000 = 250, e 0 * (-250/93) + 3000 = 3000, assim, eu estabeleci o intervalo.

Não sei se isso é gambiarra, mas foi o que eu pensei em fazer kkk.

 

Não deu muito certo, quero dizer, o intervalo ficou entre 1/3 Hz e 1 Hz no simulador, e deveria ir até 4 Hz.

Ele também não mostra nada no monitor serial, não sei o motivo.

Alguém teria alguma dica, tanto para resolver esse problema, quanto para implementar o metrônomo com mais alguma função interessante? 

 

image.png.a087670a011a5c7cab91c22900b6e1c8.png

 

//Teste metrônomo

 #define NOTE_C4 262
 #define NOTE_D4 294
 #define NOTE_E4 330
 #define NOTE_F4 349
 #define NOTE_G4 392
 #define NOTE_C5 523
 int analogPin = A0;
 int val = 0;

void setup()
{
  Serial.begin(9600);
  pinMode(0, INPUT);
  pinMode(1, INPUT);
  pinMode(2, OUTPUT);
  pinMode(3, OUTPUT);
  pinMode(4, OUTPUT);
  pinMode(5, OUTPUT);
  pinMode(8, OUTPUT);
}

void loop()
{
  digitalWrite(2, HIGH);
  digitalWrite(3, HIGH);
  digitalWrite(4, HIGH);
  digitalWrite(5, HIGH);
  val = analogRead(analogPin);
  Serial.println(val);
  recomecar: //Verifica a via do dip novamente
  int button = digitalRead(0); //Via 1
    if( button == 1){  
      digitalWrite(2, LOW);
      digitalWrite(3, LOW);
  	  digitalWrite(4, LOW);
  	  digitalWrite(5, LOW);
      while (analogRead(A0) != 0) {
        digitalWrite(2, LOW);
        digitalWrite(5, HIGH);
        tone(8, NOTE_G4, 80);
        delay(analogRead(A0)*(-250/93)+3000); //De 20 à 240 bpm
        digitalWrite(5, LOW);
        digitalWrite(4, HIGH);
        tone(8, NOTE_E4, 80);
        delay(analogRead(A0)*(-250/93)+3000); //De 20 à 240 bpm
        digitalWrite(4, LOW);
        digitalWrite(3, HIGH);
        tone(8, NOTE_E4, 80);
        delay(analogRead(A0)*(-250/93)+3000); //De 20 à 240 bpm
        digitalWrite(3, LOW);
        digitalWrite(2, HIGH);
        tone(8, NOTE_E4, 80);
        delay(analogRead(A0)*(-250/93)+3000); //De 20 à 240 bpm
        goto recomecar;
      }
	}
  int button2 = digitalRead(1); //Via 2
  	if( button2 == 1){
      digitalWrite(2, LOW);
      digitalWrite(3, LOW);
  	  digitalWrite(4, LOW);
  	  digitalWrite(5, LOW);
      while (analogRead(A0) != 0) {
        digitalWrite(3, LOW);
        digitalWrite(5, HIGH);
        tone(8, NOTE_G4, 80);
        delay(analogRead(A0)*(-250/93)+3000); //De 20 à 240 bpm
        digitalWrite(5, LOW);
        digitalWrite(4, HIGH);
        tone(8, NOTE_E4, 80);
        delay(analogRead(A0)*(-250/93)+3000); //De 20 à 240 bpm
        digitalWrite(4, LOW);
        digitalWrite(3, HIGH);
        tone(8, NOTE_E4, 80);
        delay(analogRead(A0)*(-250/93)+3000); //De 20 à 240 bpm
        goto recomecar;
      }
	}
  int button3 = digitalRead(6); //Via 3
  	if( button3 == 1){
      digitalWrite(2, LOW);
      digitalWrite(3, LOW);
  	  digitalWrite(4, LOW);
  	  digitalWrite(5, LOW);
      while (analogRead(A0) != 0) {
        digitalWrite(4, LOW);
        digitalWrite(5, HIGH);
        tone(8, NOTE_G4, 80);
        delay(analogRead(A0)*(-250/93)+3000); //De 20 à 240 bpm
        digitalWrite(5, LOW);
        digitalWrite(4, HIGH);
        tone(8, NOTE_E4, 80);
        delay(analogRead(A0)*(-250/93)+3000); //De 20 à 240 bpm
        goto recomecar;
      }
	}
  int button4 = digitalRead(7); //Via 4
  	if( button4 == 1){
      digitalWrite(2, LOW);
      digitalWrite(3, LOW);
  	  digitalWrite(4, LOW);
  	  digitalWrite(5, LOW);
      while (analogRead(A0) != 0) {
        digitalWrite(5, LOW);
        tone(8, NOTE_G4, 80);
        delay(analogRead(A0)*(-250/93)+3000); //De 20 à 240 bpm
        digitalWrite(5, HIGH);
        tone(8, NOTE_G4, 80);
        delay(analogRead(A0)*(-250/93)+3000); //De 20 à 240 bpm
        goto recomecar;
      }
	}
}

 

Postado

Para fazer esse tipo de conta tem que levar em conta as limitações da sua calculadora. Na parte onde está 250/93 o resultado é 2. Se puxar o resto aparece  64. Alguns processadores trabalham com ponto flutuante mas o buraco é mais em baixo (e o preço mais em cima).

Onde está

delay(analogRead(A0)*(-250/93)+3000); //De 20 à 240 bpm

faça

delay (3000 - (analogRead(A0)*43)/16); //De 20 à 240 bpm

Nessa segunda forma o resto também será perdido mas será menos significativo no resultado final por ser o produto de A0 por 43.

No produto o resultado vai alcançar 16 bits antes da divisão por 16.

adicionado 16 minutos depois

@Lucca Rodrigues , sei que é muito mais fácil mandar a linguagem de altop nível te prover um delay do que manipular os timers do processador. Na execução final vamos ter um timer trabalhando isso daí. Por que não tenta fazer essa manipulação direto no timer do seu Arduíno? Vai te custar algumas horas de leitura para compreender melhor o funcionamento do timer mas seu desenvolvimento será gigante quando começar a trabalhar nas tripas dos processadores. Uma melhor compreensão de como um timer trabalha também te dará a visão daquilo que se consegue fazer com o processador selecionado. Não pense que a linguagem C ou outra qualquer consegue romper os limites fisicos do MC utilizado.

Boa sorte.

  • Curtir 1
  • Obrigado 1
Postado
10 horas atrás, Sérgio Lembo disse:

faça

delay (3000 - (analogRead(A0)*43)/16); //De 20 à 240 bpm

Nessa segunda forma o resto também será perdido mas será menos significativo no resultado final por ser o produto de A0 por 43.

No produto o resultado vai alcançar 16 bits antes da divisão por 16.

 

@Sérgio Lembo Em "1023", ele leva 4 s 374 ms agora, deveriam ser 250 ms. No meio, o delay fica próximo de 1 segundo, mas em "0" continua 3 segundos, próximo de "1023" chega a beirar os 5 segundos. Continua não mostrando nada no monitor serial.

Em vez disso, troquei -250/93 por -2.688. Nesta forma, o resto não é perdido, certo? Se no mínimo, apenas a terceira casa decimal fosse perdida, ele mostraria 258 milissegundos, mas está mostrando 252 como deveria, então acho que está certo. De fato me esqueci dos limites das operações no arduino, e mesmo assim, não estou familiarizado com os mesmos ainda. Obrigado por me lembrar.

Crie uma conta ou entre para comentar

Você precisa ser um usuário para fazer um comentário

Criar uma conta

Crie uma nova conta em nossa comunidade. É fácil!

Crie uma nova conta

Entrar

Já tem uma conta? Faça o login.

Entrar agora

Sobre o Clube do Hardware

No ar desde 1996, o Clube do Hardware é uma das maiores, mais antigas e mais respeitadas comunidades sobre tecnologia do Brasil. Leia mais

Direitos autorais

Não permitimos a cópia ou reprodução do conteúdo do nosso site, fórum, newsletters e redes sociais, mesmo citando-se a fonte. Leia mais

×
×
  • Criar novo...