Viva.
Estou a querer ler a velocidade de uma roda.
Com um sensor óptico ja consigo ler correctamente as rotações por minuto, agora estou falhando na conversão dos RPM em km/h.
Encontrei uns calculadores online que calculam a velocidade, dado os RPMs e o raio de leitura.
A formula que encontrei é a seguinte:
The RPM to Linear Velocity formular is :
** v = r × RPM × 0.10472**
** v: Linear velocity, in m/s**
** r: Radius, in meter**
** RPM: Angular velocity, in RPM (Rounds per Minute)**
Agora o codigo:
volatile byte revolutions;
unsigned int rpm;
unsigned long timeold;
unsigned long velo;
void setup() {
Serial.begin(9600);
attachInterrupt(0, rev_counter, RISING);
revolutions = 0;
rpm = 0;
timeold = 0;
}
void loop() {
if (revolutions >= 1) { //Calculates rpm after every 1 revs.
//rpm=(revolutions/20)/(((millis() - timeold)/60)/1000); //there are 20 holes on the encoder wheel
rpm = 60000 / (millis() - timeold);
timeold = millis();
revolutions = 0;
Serial.print("RPM =\t");
Serial.print(rpm, DEC);
//Serial.print('\n');
// v = r × RPM × 0.10472
Serial.print("\t speed=\t");
/*
The RPM to Linear Velocity formular is :
v = r × RPM × 0.10472
v: Linear velocity, in m/s
r: Radius, in meter
RPM: Angular velocity, in RPM (Rounds per Minute)
*/
velo = (0.015 * rpm * 0.10472);
Serial.print(velo, DEC);
Serial.print("km/h");
Serial.print('\n');
}
if (millis() > (timeold + 2500)) {
rpm = 0;
Serial.print("RPM =\t");
Serial.print(rpm, DEC);
Serial.print('\n');
}
}
void rev_counter() {
revolutions++;
}
O problema é que no calculador online, que supostamente aplica a formula, obtenho resultados muito diferentes dos apresentados no serial monitor.
Pergunta onde estou a falhar, formula ou no codigo ?
Outra questão ( esta é mais por me ter baldado nas aulas de matemática-geometria ), conhecida a velocidade a X cms do eixo duma roda, qual é a velocidade a Y cms ?
Obrigado.
Teste o código abaixo e copie o que está no Monitor Serial e cole aqui, falando o que era esperado:
const unsigned long TempoAmostragem = 60000UL; //Milisegundos
volatile unsigned int NumeroVoltas = 0;
unsigned int RPM = 0;
unsigned int Velocidade = 0;
unsigned long TemporizadorRPM = 0;
void setup() {
Serial.begin(9600);
attachInterrupt(0, ContadorVoltas, RISING);
}
void loop() {
if(millis() - TemporizadorRPM >= TempoAmostragem){
RPM = (NumeroVoltas) * (60000UL / TempoAmostragem);
NumeroVoltas = 0;
TemporizadorRPM = millis();
Velocidade = (RPM * 0.0015708f); // 0.0015708 = 0.015 * 0.10472
Serial.print("RPM =\t");
Serial.print(RPM);
Serial.print("\t Velocidade =\t");
Serial.print(Velocidade);
Serial.print(" km/h");
Serial.println();
}
}
void ContadorVoltas() {
NumeroVoltas++;
}
Não sei se o giova014 está a ir pelo caminho correcto. O meu primeiro palpipe ao ver o seu código é que o problema se deve a erro de truncagem - talvez fazendo o cálculo apenas uma vez este erro seja minimizado. Está a fazer cálculos com valores decimais que devem retornar um valor (também decimal) com uma parte inteira bastante pequena (dependendo das velocidades em jogo). Tente fazer os cálculos e armazenar o valor final numa variável do tipo float e envie esse valor para a porta série e faça a conversão para long depois disso (e volte novamente a enviar o valor para a porta série) e veja se os resultados são iguais.
A fórmula do site está correcta e a implementação também me parece correcta, por isso não restam muitas opções.
Em relação à questão da velocidade a X ou Y cm do eixo, basta que o R que utiliza na fórmula seja X ou Y. Basicamente, a fórmula que está a utilizar calcula o perímetro de uma roda com um raio R e converte minutos em segundos (a cada rotação da roda, esta anda o equivalente ao seu perímetro). O perímetro de uma roda é 2piR. Se quiser calcular o perímetro de uma roda com um raio diferente, bata utilizar um R diferente. (já agora, o valor que entra na fórmula 0.10472 é apenas 2*pi/60 - também pode usar estes valores no seu programa e ver se o resultado se aproxima mais do real ou não).
Viva.
Muito agradecido aos dois.
Mas acho que o erro era outro.
Depois de fazer alguns cálculos a mão ( calculadora ) deparei com um erro de conversões de ms ( metros por segundo ) dados pela meu código e com o valor do calculador online kmh ( quilometro por hora ).
alterei o codigo e ficou com estas duas linhas:
/*
The RPM to Linear Velocity formular is :
v = r × RPM × 0.10472
v: Linear velocity, in m/s
r: Radius, in meter
RPM: Angular velocity, in RPM (Rounds per Minute)
*/
velo = (0.015 * rpm * 0.10472); // ms
velok = (( velo*3600) /1000 ); // kmh
De qualquer forma vou testar mais logo esta alteração e o codigo fornecido pelo giova014 e as dicas do luisilva
Masi uma vx muito agradecidos.
arssant:
Viva.
Muito agradecido aos dois.
Mas acho que o erro era outro.
Depois de fazer alguns cálculos a mão ( calculadora ) deparei com um erro de conversões de ms ( metros por segundo ) dados pela meu código e com o valor do calculador online kmh ( quilometro por hora ).
alterei o codigo e ficou com estas duas linhas:
/*
The RPM to Linear Velocity formular is :
v = r × RPM × 0.10472
v: Linear velocity, in m/s
r: Radius, in meter
RPM: Angular velocity, in RPM (Rounds per Minute)
*/
velo = (0.015 * rpm * 0.10472); // ms
velok = (( velo*3600) /1000 ); // kmh
De qualquer forma vou testar mais logo esta alteração e o codigo fornecido pelo **giova014** e as dicas do **luisilva**
Masi uma vx muito agradecidos.
O programa que postou originalmente não dava o valor em km/h, mas sim em m/s, por isso, neste momento estou um pouco confuso, sem saber o que quer realmente.
luisilva:
O programa que postou originalmente não dava o valor em km/h, mas sim em m/s, por isso, neste momento estou um pouco confuso, sem saber o que quer realmente.
O problema foi eu ter seleccionado no calculador online kmh como resultado, e no meu codigo estava a calcular ms, dai a disparidade de resultados entre os valores obtidos no meu codigo e os do calculador online.
So agora revendo o calculador online e que me apercebi do meu erro.