hi there just looking into using a hall sensor on my arduino and came across this code below, i dont know if im being blind but where does it state which input pin its using?
const int ledPin = 13;
volatile int rpmcount;
int sensorState = 0;
unsigned int rpm;
unsigned long timeold;
void rpm_fun()
{
rpmcount++;
digitalWrite(ledPin, HIGH);
delay(50);
digitalWrite(ledPin, LOW);
}
void setup() {
pinMode(ledPin, OUTPUT);
Serial.begin(9600);
attachInterrupt(0, rpm_fun, FALLING);
}
void loop(){
if(rpmcount>=5) {
rpm=(60000*rpmcount)/(8*(millis()-timeold)); //the 8 changes to 4 if 4 magnets are used.
timeold = millis();
//Serial.println(rpmcount,DEC);
rpmcount = 0;
Serial.println(rpm,DEC);
}
}
o ok i see thanks for that link one problem i can see is i am using an arduino uno and i will eventually need 3 hall inputs so how will i overcome that?
There's a delay(50) in the ISR. Not a good idea.
yes there is where it is blinking the led i dont actually need that led how can i get rid of that function as ive noticed if i remove void rpm_fun() i get a error
Joes:
yes there is where it is blinking the led i dont actually need that led how can i get rid of that function as ive noticed if i remove void rpm_fun() i get a error
You could remove the blinking by taking out the two lines of code that write HIGH and LOW to the ledPin, and the delay between them.
You can keep the blinking led.
Move the blink part outside of the ISR. Set up a global byte variable and make it volatile to use as a blink flag, maybe call it bFlag. When the ISR runs, set that to 1 in the ISR. Then in loop() set up an if ( bFlag ) { } that makes the led blink and sets bFlag = 0.
So your ISR increments rpm count and flags the blink, it runs in next to nothing flat and is ready to service the next interrupt that fast.
IIRC you can set up any I/O pin to interrupt on Level Change. But look into things, maybe you don't need to use interrupts at all. Most things don't at 16 MHz.
You'd do better to learn how to use timers to run multiple tasks without using blocking code.
This is Nick Gammon's site, he's a master at explanations.
hi thanks for your replies on that link Gammon Forum : Electronics : Microprocessors : Interrupts there is a lot of stuff on that website to get your head wrapped around lol i have come up with this compiles fine but somethings telling me im missing something here?
volatile int rpmcount;
int sensorState = 0;
unsigned int rpm;
unsigned long timeold;
ISR (PCINT2_vect)
{
// handle pin change interrupt for D0 to D7 here
} // end of PCINT2_vect
void setup ()
{
Serial.begin(9600);
// pin change interrupt (example for D0)
PCMSK2 |= _BV (PCINT16); // want pin 0
PCIFR |= _BV (PCIF2); // clear any outstanding interrupts
PCICR |= _BV (PCIE2); // enable pin change interrupts for D0 to D7
}
void loop(){
if(rpmcount>=5) {
rpm=(60000*rpmcount)/(8*(millis()-timeold)); //the 8 changes to 4 if 4 magnets are used.
timeold = millis();
//Serial.println(rpmcount,DEC);
rpmcount = 0;
Serial.println(rpm,DEC);
}
}
Just check the pins with a port read at the start of loop() and don't fart around with delays or other blocking code. A fast loop() can read and evaluate, and report/store data for 3 pins many times per millisecond. Is > 1000 checks per second fast enough?
i could do it in a port read like you said but this will be linking up with some other code i already have, there is no delays in it will it still be fine as this might be seeing some high rpm's?