Re: Velocimetro com arduino como faço para medir a velocidade?

fiz o seguinte programa com arduino para fazer um velocimetro.
mais somente consegui fazer com que o arduino detecte os polos do ima. e conte a quantidade de vezes que o polo sul passou pelo ima.

estou usando um sensor que a saida dele fica em nivel alto, somente quando passa o polo sul do imã a saida vai para nivel baixo.
ou seja entao o arduino esta detectando a passagem do polo sul pelo sensor.
gostrai que alguem me ajudasse a fazer essa mediçao de velocidade.

int i=0;
int norte=13;
void setup(){

Serial.begin(9600);

pinMode(norte, INPUT);

}

void loop()
{
if(digitalRead(norte)==HIGH){
Serial.println("polo norte");
}
else if(digitalRead(norte)==LOW)
{
Serial.println("poloSul");
i++;
Serial.println(i);
}
delay(50);

}

Primeiro tens de contar os pulsos... se contares o numero de pulsos por segundo (ou menos), ficas com uma ideia da velocidade.

Queres que a gente faça o trabalho por ti?

Já agora, o teu código nunca funcionará correctamente devido ao delay que lá tens.

minha duvida e essa como colocar a contagem para que seja feito em um segundo.

Porque este ("i") que coloquei esta fazendo a contagem total toda vez que passa o polo por ele adciona, e eu queria justamente esta contagem por segundo.

se alguem puder me ajudar.
fico grato.

Procura por interrupts e usa um dos pinos com interrupcao para incrementar uma variavel unsigned long do tipo volatil.
Configura a interrupcao no bordo descendente.
Depois podes calcular a velocidade com base no número dessa variavel por minuto

Ou, mais bonito ainda, liga o sensor à entrada dum timer e usa-o como contador. Não é simples, mas é muito giro de se ver. :slight_smile:

progra:
(...)alguem me ajudasse a fazer essa mediçao de velocidade.(...)

esse Delay(50); me imcomoda!!! rs

uma solução é usar uma das interrupções do arduino a outra é guardar o estado anterior da porta para que ela não seja contada mais de uma vez e comparar o millis para o momento do cálculo das rotações.

vejo um probleminha em teu código e sugiro algo como o abaixo (se não for usar interrupções)

o delay pode fazer você perder um pulso ^^

//tipo:
int estadoanterior = 1; //HIGH
int voltas = 0;
unsigned long tempo = 0;

void loop(){ 
unsigned long agora;
int estado = digitalRead(norte);
int rotacao = 0;

if (estado == LOW & estado != estadoanterior){
Serial.println("polo sul");
voltas++;
}else if (estado == HIGH & estado != estadoanterior){
Serial.println("polo norte");
}

agora = milles();
if (agora - tempo => 1000){ //1000 milesegundos = 1 segundo
rotacao = voltas/1000; //rotação por segundos
Serial.print("passou um segundo e ");
Serial.print(voltas);
Serial.print(" voltas");
Serial.print(", ");
Serial.print(", RPS ");
Serial.println(rotacao);
tempo = agora; //guarda o tempo atual para que a mensagem apareça um segundo depois
voltas = 0; //reinicia a contagem para o próximo segundo
}
}

para o velocímetro você só precisa saber quantos centímetros, metros, milímetros ou outra medida que tua roda percorre até percorrer o angulo de 360 :wink:

Tira apenas a ideia do código, pois estou quase caindo de sono e nem consigo ler o que escrevi rs

Teve um post, pouco tempo atrás, onde um carinha tinha uma dúvida relacionada ao cálculo de velocidade e estava usando uma interrupção do arduino: Velocimetro só chega a 96Km/h ... ajuda - Português - Arduino Forum diz se ele ajuda em algo.

Ops, acabo de checar que você passou por lá, desculpe-me, qual é a tua duvida mesmo? o.O

desculpa minha ignorancia Mortis e porque estou aprendendo o arduino agora nao tive muito contato antes.
mais eu tenho uma duvida.

conforme o exemplo que colocou ele vai contar de acordo o tempo que o polo estiver no imã nao?
eu precisarei indentificar os pulsos.

estou certo? porque nao entendo tanto.

conforme o exemplo que colocou ele vai contar de acordo o tempo que o polo estiver no imã nao?

:~ Ja li a tua pergunta mas continuo sem entender o que queres dizer com polo estiver no ima

@Mortis

if (estado == LOW & estado != estadoanterior)

Penso que por laspo te enganaste no &, pois apenas um & é uma operaçao de bitwise AND

if ((estado == LOW) && (estado != estadoanterior))

HugoPT:
Penso que por laspo te enganaste no &, pois apenas um & é uma operaçao de bitwise AND

Obrigado Hugo, estou mesmo pancada da cabeça rs

progra:
conforme o exemplo que colocou ele vai contar de acordo o tempo que o polo estiver no imã nao?
eu precisarei indentificar os pulsos.

Progra,

Por favor, não me entenda mal, eu gosto de brincar e me esqueço que pela internet pode não parecer brincadeira. Não se desculpe, eu sou novato e entendo como é iniciar em algo :wink:

Eu disse que não sabia mais qual era a tua dúvida, porque se lermos com cuidado aqueles posts, vemos a tua a pergunta "como faço para medir a velocidade?" respondida :slight_smile:

Sobre o meu rascunho de código, que o Hugo gentilmente corrigiu, eu coloquei quase que o mesmo que você, só que adicionei condições para evitar que o arduino conte um estado LOW mais de uma vez e depois coloquei um if comparando o tempo que passou para que seja avisado via serial quantas voltas o sensor capturou.

O loop do arduino ficará a detectar a mudança de estado do sensor (cada mudança é um pulso, certo?). Cada vez que o sensor mudar de estado o código adiciona +1 na variável voltas.

Quando passar 1 segundo ele envia para a serial quantas voltas (pulsos) ele contou e começa a contar novamente. Nessa parte que você pode fazer as contas, comparando a distancia percorria, para ter milímetros/centímetros/metros, o número de voltas e o tempo.

Mas como eu disse é só um rascunho, para você ver a lógica da minha sugestão. Minha dica agora é: Dá uma lida com calma no que foi colocado (nos dois tópicos), faça testes (o arduino aceita muitos e muitos uploads, não precisar temer 8)) e veja o resultado na serial, tenta melhorar o programa/lógica e veja os resultados no serial monitor.

Depois você nos conta quais foram os resultados e as novas dúvidas (se tiver) :wink:

obrigado galera pela ajuda graças a vcs foi conseguido um grande avanço no trabalho aqui. :slight_smile:

mais infelizmente nao esta do jeito que preciso. :frowning:
eu tentei dizer com o (conforme o exemplo que colocou ele vai contar de acordo o tempo que o polo estiver no imã nao?) e pq no casso meu a programaçao esta contando quando o polo sul passa pelo sensor incrementa 1.
mais desta forma que vcs me ensinaram.
quando eu deixar o polo sul do imãno sensor por mais de um segundo, no segundo em questao ele contria ate 100 por exemplo mostrando como por exemplo se fosse o tempo que o polo sul do ima ficou proximo ao sensor.
e o que estou precissando na verdade e que o polo sul passa mais enquanto o norte nao passar ele nao incrementa pois nao houve um ciclo ainda.por exemplo no casso de eu manter o polo sul do ima por mais de um segundo no sensor ele nao incrementa ainda porque o polo norte ainda nao passou pelo sensor.
para deixar um exemplo mais pratico do que estou fazendo e como se fosse um velocimetro de uma bicicleta em que se tem na roda um imã e ne um ponto fixo proximo a roda tem o sensor ao se passar o imã pelo sensor ele vai incrementar 1. mais se por exemplo o imã ficar bem em frente ao sensor e nao se movimentar nao incrementar. pois a roda vai estar parada bem na posição em que o imã ficou em frente ao sensor.
pelo que intendi quando fiz a simulação por exemplo e como se estivesse fazendo 100 leituras em um segundo e se eu deixar o polo sul do imã no sensor ele fazer a contagem de 100 mais na verdade nao houve nem um ciclo por isto que falei que ele tem fazer a contagem dos pulsos.

obrigado galera. :slight_smile:

Progra,

Não consigo perceber pois a variável voltas só é incrementada quando o estado da porta muda e essa mudança é para LOW.

O funcionamento seria Igual ao de um botão, botão pressionado (pino norte = HIGH) ou solto (pino norte = LOW)

Como estão as conexões do teu circuito?
Em repouso (sem imã por perto) o sensor é HIGH, certo?

Tenta usar o resistor pull up da porta para manter a porta HIGH (evitar oscilações) até que o sensor a coloque LOW, pode se isso.

int estadoanterior = 1; //O estado HIGH
int voltas = 0;
unsigned long tempo = 0;
int norte=13;

void setup(){
  Serial.begin(9600);
  pinMode(norte, INPUT); //define a porta como input
  digitalWrite(norte, HIGH); // ativa o resistor pullup
}

void loop(){ 
  unsigned long agora;
  
  agora = millis();
  int estado = digitalRead(norte);
  int rotacao = 0;
  
  if (estado != estadoanterior){ //Se o estado da porta mudou
    if(estado == LOW) //Se o estado mudou para LOW
    {
      Serial.println("polo sul");
      voltas++; //Incrementa 1
    }
    else 
      Serial.println("polo norte");
  }
  
  if (agora - tempo >= 1000){ //1000 milesegundos = 1 segundo 
    rotacao = voltas/1000; //rotação por segundos
    Serial.print("passou um segundo e ");
    Serial.print(voltas);
    Serial.print(" voltas");
    Serial.print(", ");
    Serial.print(", RPS ");
    Serial.println(rotacao);
    tempo = agora; //guarda o tempo atual para que a mensagem apareça um segundo depois
    voltas = 0; //zera o contador
  }
}

Teu código ficou parecido com o acima? Qual resultado agora? Infelizmente estou no trabalho, mas, a não ser que eu precise de internação imediata, deve funcionar rs

Ou o Hugo pede para trazerem a camisa de força :wink: