How is the switch wired ? Is the pin it is attached to always in a known state LOW or HIGH or is it left floating at an unknown voltage and prone to pick up interference ?
Interrupts are used so that a program is not tied up waiting for a response from a sensor.
I attached the wiring diagram. The switch is pressed about 5x per sec. The serial monitor printout is also included. The first numbers on the serial monitor print out are the sensor working correctly and measuring RPM. The second set is when the actuator is run too close to the Arduino and the RPM should be zero. The code is :
// 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++;
}
Ok this program is working but I sure don't understand why.
/*
Counting presses
*/
unsigned long previousMillis = 0;
const long interval = 1000;
int switchPin = 2; // switch is connected to pin 2
int val; // variable for reading the pin status
int buttonState; // variable to hold the button state
int counter = 0; // how many times the button has been pressed
void setup() {
pinMode(switchPin, INPUT); // Set the switch pin as input
Serial.begin(9600); // Set up serial communication at 9600bps
buttonState = digitalRead(switchPin); // read the initial state
}
void loop() {
val = digitalRead(switchPin); // read input value and store it in val
delay(5);
if (val != buttonState) { // the button state has changed!
if (val == LOW) { // check if the button is pressed
counter++; // increment the counter variable
}
}
buttonState = val;
unsigned long currentMillis = millis();
if (currentMillis - previousMillis >= interval) {
previousMillis = currentMillis;
// save the new state in our variable
Serial.print("RPM ");
Serial.println(counter*20);
counter=0;
}
}
projecteinsteinvr:
Interrupts are used so that a program is not tied up waiting for a response from a sensor.
That is not a logical statement. It is usually possible to get sensor data without waiting and without using interrupts.
Your program (in Reply #3) is very badly structured. You are disabling all interrupts for a long time during which you try to do some Serial.Print()s - which require interrupts to be enabled.
Try it like this
// read RPM
volatile unsigned long half_revolutions = 0; // NOTE volatile for variable updated in ISR
unsigned long latest_half_revolutions;
unsigned long previousHalfRevolutions;
unsigned long halfRevsThisPeriod;
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, use >= so as not to miss anything
previousHalfRevolutions = latest_half_revolutions;
noInterripts(); //Disable interrupt when getting value
latest_half-revolutions = half_revolutions;
interrupts();
halfRevsThisPeriod = latest_half_revolutions - previousHalfRevolutions;
rpm = halfRevsThisPeriod * 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(halfRevsThisPeriod); //print revolutions per second or Hz. And print new line or enter.
lastmillis = lastMillis + 1000; // this is more precise
}
}
// this code will be executed every time the interrupt 0 (pin2) gets low.
void rpm_fan(){
half_revolutions++;
}
Data can be read from a sensor in one of the following three ways: 1. Fully Tied Protocol (Continuous polling): Instruct the sensor for data conversion; keep checking continuously that the sensor is ready with data; then, read the data and then do other things.
2. Partially Tied Protocol (Semi-polling): Instruct the sensor for data conversion; do other things, and in the middle of doing other things check (time to time) that the sensor is ready with data; read the sensor data and then keep doing other things.
3. Interrupt Protocol: Instruct the sensor for data conversion; do the tasks of the mainline program (MLP); let the sensor interrupt the processor when data is reday; read data and then rsume the tasks of the MLP.
What the Hell is a "tied protocol" (fully or partially)?
The word tied has appeared in Post#3 due to @projecteinsteinvr. In Post#6, @Robin2 has accepted the conceptual meaning of the phrase tied to interrupt although he has some reservation in the style it has been used as sensor data could still be acquired without waiting -- a mechanism which Robin2 has not elaborated.
I have touched the issue with a hope to hear more from the Forum on the mechanism of 'reading sensor data without waiting.'
It is expected that there should be some humor time to time (and indeed these are there) in this hard Technical Forum, and it could have been made relating the word (tied) with 'French tied loan'.
From the online Cambridge dictionary: A "tied loan" is "a loan made by one organization to another with the condition that the money should be spent on particular things"
I don't see how this has anything to do with blocking code or interrupts. Whatever.
Read up on “ volatile” - software issue
Then check “pull-up” input - both hardware and software issue.
Your input pin should be using build in “pull-up” then you trigger ,
Interrupt on “trailing” edge.