Arduinos & Breaduinos
Tacómetro
Contador de RPM's com arduino
O principio básico trata-se de obter um sinal que nos indique a rotação de um objecto, seja ele um veio, eixo, roda ou qualquer parte que efectue um movimento periódico.
No mais vulgar dos casos, a rotação de uma peça, normalmente medimos a diferença de tempo em que um determinado ponto da peça leva para atingir de novo uma marca.
Isto é normalmente feito com sensores. Sejam eles electromecânicos ou electrónicos.
Suponhamos duas medidas de tempo (ot e t) tomadas na passagem da nossa marca, o tempo necessário para efectuar essa rotação seria:
dt=t-ot
Teremos assim o período de rotação como a diferença entre a actual medida de tempo e a anterior.
Estando as medidas de tempo em milissegundos, para sabermos a velocidade de rotação em RPM (rotações por minuto) temos:
rpm=60000/(t-ot)
Caso o sinal de origem emita vários pulsos por rotação basta dividir este valor pelo numero de pulsos.
Se daqui quisermos saber uma velocidade de deslocamento basta fazer uma equivalência ou calibração e relacionar a velocidade de rotação deste elemento com a deslocação real, de por exemplo um veículo no terreno, partindo do principio que não existe um elemento de acoplagem variável intercalado.
Ou seja de medirmos a rotação do eixo da roda podemos depois calcular a distancia percorrida. No entanto este tipo de medida também pode ser útil para obtermos a rotação do motor, ainda que não nos interesse a distancia percorrida ou velocidade de deslocamento.
Usamos um sensor magnético (hall effect sensor A3144) que funcionou bem ligado directamente ao pino do uC no entanto podemos adicionar alguns componentes (opcionais) que ajudam a filtar algum ruido que possa existir na alimentação ou no ambiente.
Aqui um exemplo do circuito do sensor com os componentes opcionais:
A resistência de 10K pode ser substituída por ums de 2.2k ou semelhante e os condensadores podem ser dispensados, é questão de fazer um ensaio com a sua montagem e com o seu ambiente.
We are using an I2C LCD
Está também disponível um código muito mais simples usando a livraria PCINT e imprimindo para o monitor de serie aqui.
#include <Wire.h> // Comes with Arduino IDE
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE); // Set the LCD I2C address
/* Pin to interrupt map:
* D0-D7 = PCINT 16-23 = PCIE2 = pcmsk2
* D8-D13 = PCINT 0-5 = PCIE0 = pcmsk0
* A0-A5 (D14-D19) = PCINT 8-13 = PCIE1 = pcmsk1
*/
#define interrupt_pin2 8 //Define Analog Pin (analog pins are 16-21)
volatile unsigned long t=0;
volatile unsigned long ot=0;
ISR(PCINT0_vect) {
if (PINB & 1) {
ot=t;
t=millis();
}
}
//actualizar o visor (aqui calibrado para um maximo de 3000 rpm, basta mudar o valor)
#define max_rpm 3000
void printVu(int r) {
int i=map(r, 0, max_rpm, 0, 20);
for(int n=0;n<20;n++) {
lcd.print((char)(n<i?255:' '));
}
}
void setup() {
Serial.begin(115200);
lcd.begin(20,4); // initialize the lcd for 20 chars 4 lines, turn on backlight
lcd.backlight(); // finish with backlight on
lcd.print("RPM with PCINT");
MCUCR = (1<<ISC01) | (1<<ISC00);
PCICR |= (1<<PCIE0);
PCMSK0 |= (1<<PCINT0);
pinMode(interrupt_pin2, INPUT); //Make pin an input
digitalWrite(interrupt_pin2,HIGH); //Enable pullup resistor on Analog Pin
interrupts();
}
unsigned int rpm=0;
void loop() {
//lcd.setCursor(0,3);lcd.print(millis()-t);lcd.print(" ");
if((millis()-t)>300) rpm=0;
else if (t!=ot) {
rpm=60000.0/(float)(t-ot);
}
Serial.print(rpm);Serial.print(" ");Serial.println(t-ot);
lcd.setCursor(0,1);
lcd.print(rpm);
lcd.print(" rpms ");
lcd.setCursor(0,2);
printVu(rpm);
}