You are on page 1of 4

// read RPM

volatile int rpmcount = 0;//see http://arduino.cc/en/Reference/Volatile


int rpm = 0;
unsigned long
lastmillis = 0;
void setup(){
Serial.begin(9600);
attachInterrupt(0, rpm_fan, FALLING);//interrupt cero (0) is on pin two(2).
}
void loop(){
if (millis() - lastmillis == 1000){
reading frecuency (Hz).*/
detachInterrupt(0);

/*Uptade every one second, this will be equal to

//Disable interrupt when calculating

rpm = rpmcount * 60; /* Convert frecuency to RPM, note: this works for one
interruption per full rotation. For two interrups per full rotation use rpmcount *
30.*/
Serial.print("RPM =\t"); //print the word "RPM" and tab.
Serial.print(rpm); // print the rpm value.
Serial.print("\t Hz=\t"); //print the word "Hz".
Serial.println(rpmcount); /*print revolutions per second or Hz. And print new line or
enter.*/
rpmcount = 0; // Restart the RPM counter
lastmillis = millis(); // Uptade lasmillis
attachInterrupt(0, rpm_fan, FALLING); //enable interrupt
}

void rpm_fan(){ /* this code will be executed every time the interrupt 0 (pin2) gets
low.*/
rpmcount++;
}
// Elimelec Lopez - April 25th 2013
Code v2 (Calculate Average)

// read RPM and calculate average every then readings.


const int numreadings = 10;
int readings[numreadings];
unsigned long average = 0;
int index = 0;
unsigned long total;
volatile int rpmcount = 0;//see http://arduino.cc/en/Reference/Volatile
unsigned long rpm = 0;unsigned long lastmillis = 0;
void setup(){
Serial.begin(9600);

attachInterrupt(0, rpm_fan, FALLING);

void loop(){
if (millis() - lastmillis >= 1000){
reading frecuency (Hz).*/

/*Uptade every one second, this will be equal to

detachInterrupt(0);
//Disable interrupt when calculating
total = 0;
readings[index] = rpmcount * 60; /* Convert frecuency to RPM, note: this works for
one interruption per full rotation. For two interrups per full rotation use rpmcount *
30.*/
for (int x=0; x<=9; x++){
total = total + readings[x];
}
average = total / numreadings;
rpm = average;
rpmcount = 0; // Restart the RPM counter
index++;
if(index >= numreadings){
index=0;
}
if (millis() > 11000){

// wait for RPMs average to get stable

Serial.print(" RPM = ");


Serial.println(rpm);

lastmillis = millis(); // Uptade lasmillis


attachInterrupt(0, rpm_fan, FALLING); //enable interrupt
}

void rpm_fan(){ /* this code will be executed every time the interrupt 0 (pin2) gets
low.*/
rpmcount++;
}
Reading Fan RPM

The hall effect sensor pin goes to pin 2, or interrupt 0. The LED and 10k resistor
needed to be there for this to work. If your fan takes a lot of current, you might need
to use an external power source.
Simple Circuit Option:
If the internal pull-up resistor for pin 2 (interrupt 0) is enabled by adding the line:
digitalWrite(2, HIGH);
to setup(), then the hall effect sensor can be connected directly to pin 2 without
requiring an external 10k pull-up resistor and LED. The LED is actually only serving as
a visual indicator in the original circuit and is not mandatory in for either.
Ze code:
if (half_revolutions >= 20) {
volatile byte
//Update RPM every 20 counts, increase this for
half_revolutions;
better RPM resolution,
unsigned int rpm;
//decrease for faster update
unsigned long timeold;
rpm = 30*1000/(millis() timeold)*half_revolutions;
void setup()
timeold = millis();
{
half_revolutions = 0;
Serial.begin(9600);
Serial.println(rpm,DEC);
attachInterrupt(0,
rpm_fun, RISING);
}
half_revolutions = 0;
}
rpm = 0;
void rpm_fun()
timeold = 0;
{
}
half_revolutions++;
void loop()
//Each rotation, this interrupt function is run
twice
{
}
by zitron
Edited by Elimelec Lopez - April 25th 2013
// read RPM
int half_revolutions = 0;
int rpm = 0;
unsigned long lastmillis = 0;
void setup(){
Serial.begin(9600);
attachInterrupt(0, rpm_fan, FALLING);
}
void loop(){
if (millis() - lastmillis == 1000){ //Uptade every one second, this will be equal to
reading frecuency (Hz).

detachInterrupt(0);//Disable interrupt when calculating


rpm = half_revolutions * 60; // Convert frecuency to RPM, note: this works for one
interruption per full rotation. For two interrups per full rotation use
half_revolutions * 30.
Serial.print("RPM =\t"); //print the word "RPM" and tab.
Serial.print(rpm); // print the rpm value.
Serial.print("\t Hz=\t"); //print the word "Hz".
Serial.println(half_revolutions); //print revolutions per second or Hz. And print new
line or enter.
half_revolutions = 0; // Restart the RPM counter
lastmillis = millis(); // Uptade lasmillis
attachInterrupt(0, rpm_fan, FALLING); //enable interrupt
}
}
// this code will be executed every time the interrupt 0 (pin2) gets low.
void rpm_fan(){
half_revolutions++;
}
volatile keyword
volatile is a keyword known as a variable qualifier, it is usually used before the
datatype of a variable, to modify the way in which the compiler and subsequent program
treats the variable.
Declaring a variable volatile is a directive to the compiler. The compiler is software
which translates your C/C++ code into the machine code, which are the real instructions
for the Atmega chip in the Arduino.
Specifically, it directs the compiler to load the variable from RAM and not from a
storage register, which is a temporary memory location where program variables are
stored and manipulated. Under certain conditions, the value for a variable stored in
registers can be inaccurate.
A variable should be declared volatile whenever its value can be changed by something
beyond the control of the code section in which it appears, such as a concurrently
executing thread. In the Arduino, the only place that this is likely to occur is in
sections of code associated with interrupts, called an interrupt service routine.
Example
void loop()
// toggles LED when interrupt pin
{
changes state
digitalWrite(pin, state);
int pin = 13;
}
volatile int state = LOW;
void blink()
void setup()
{
{
state = !state;
pinMode(pin, OUTPUT);
}
attachInterrupt(0, blink,
CHANGE);
}
Pin Allocation
Pin
Function
Analog
Button (select, up, right, down and left)
0
Digital
DB4
4
Digital
DB5
5
Digital
DB6
6
Digital
DB7
7
Digital
RS (Data or Signal Display Selection)
8
Digital
Enable
9
Digital
Backlit Control
10
//Sample using LiquidCrystal library
#include <LiquidCrystal.h>
/
******************************************
*************
This program will test the LCD panel and
the buttons
Mark Bramwell, July 2010
******************************************
**************/
// select the pins used on the LCD panel
LiquidCrystal lcd(8, 9, 4, 5, 6, 7);
// define some values used by the panel
and buttons
int lcd_key
= 0;
int adc_key_in = 0;
#define btnRIGHT 0
#define btnUP
1
#define btnDOWN
2
#define btnLEFT
3

lcd.setCursor(0,0);
lcd.print("Push the buttons"); // print a
simple message
}
void loop()
{
lcd.setCursor(9,1);
// move
cursor to second line "1" and 9 spaces
over
lcd.print(millis()/1000);
// display
seconds elapsed since power-up
lcd.setCursor(0,1);
// move to
the begining of the second line
lcd_key = read_LCD_buttons(); // read
the buttons
switch (lcd_key)
//
depending on which button was pushed, we

#define btnSELECT 4
#define btnNONE
5
// read the buttons
int read_LCD_buttons()
{
adc_key_in = analogRead(0);
// read
the value from the sensor
// my buttons when read are centered at
these valies: 0, 144, 329, 504, 741
// we add approx 50 to those values and
check to see if we are close
if (adc_key_in > 1000) return btnNONE; //
We make this the 1st option for speed
reasons since it will be the most likely
result
// For V1.1 us this threshold
if (adc_key_in < 50) return btnRIGHT;
if (adc_key_in < 250) return btnUP;
if (adc_key_in < 450) return btnDOWN;
if (adc_key_in < 650) return btnLEFT;
if (adc_key_in < 850) return btnSELECT;
// For V1.0 comment the other threshold
and use the one below:
/*
if (adc_key_in < 50) return btnRIGHT;
if (adc_key_in < 195) return btnUP;
if (adc_key_in < 380) return btnDOWN;
if (adc_key_in < 555) return btnLEFT;
if (adc_key_in < 790) return btnSELECT;
*/
return btnNONE; // when all others fail,
return this...
}
void setup()
{
lcd.begin(16, 2);
the library

// start

perform an action
{
case btnRIGHT:
{
lcd.print("RIGHT ");
break;
}
case btnLEFT:
{
lcd.print("LEFT
");
break;
}
case btnUP:
{
lcd.print("UP
");
break;
}
case btnDOWN:
{
lcd.print("DOWN ");
break;
}
case btnSELECT:
{
lcd.print("SELECT");
break;
}
case btnNONE:
{
lcd.print("NONE ");
break;
}
}
}

You might also like