I would like to update RPM only when i trigger it with hall sensor, the most frequently I will do that is once per 2-3 seconds.
II want to output signal same as RPM update, so once per 2-3 seconds.
Ahh, I see... I made one } to early, namely imediately after RPM conversion. Now I have moved all RPM-dependant if-statements inside "hallState == HIGH". I have also changed RPM conversion multiplier to 300:
const int hallPin = 12;
const int led = 13;
volatile int rpmcount = 0;
int rpm = 0;
int hallState = 0;
int lasthallState = 0;
void setup() {
Serial.begin(9600);
pinMode(led, OUTPUT);
pinMode(9, OUTPUT);
pinMode(hallPin, INPUT);
attachInterrupt(0, rpm_fan, FALLING);//interrupt zero (0) is on pin two(2), there is 0-5V square wave signal wire connected
}
void loop() {
hallState = digitalRead(hallPin); //Reads current hall state
if (hallState != lasthallState) { //if current hall state is different than last hall state then:
if (hallState == HIGH) { //check if current hall state is HIGH, if yes then:
rpmcount = 0; // set number of interrupts to 0, to begin counting
delay(100); //wait 100ms, it will run rpm_fan during that time and count LOWs on pin 2
rpm = rpmcount * 300; // Convert frecuency to RPM, * 300 = *10 * 30,, *10 - to make it into 1sec, *30, because two interupts per full rotation.
if (rpm <= 4000) {} //if rpm is lower than 4000 then do nothing
else if ((rpm <= 8000) && (rpm > 4000)) { // if 4000<rpm <= 8000 then at pin 9 - HIGH -> 80ms -> LOW
digitalWrite(9, HIGH);
delay(80);
digitalWrite(9, LOW);
}
else if ((rpm <= 10000) && (rpm > 8000)) {
digitalWrite(9, HIGH);
delay(70);
digitalWrite(9, LOW);
}
else if (rpm > 10000) {
digitalWrite(9, HIGH);
delay(60);
digitalWrite(9, LOW);
}
else {}
}
delay(50);
}
lasthallState = hallState;
else {}
}
void rpm_fan() { /* this code will be executed every time the interrupt 0 (pin2) gets low.*/
rpmcount++;
}
Now the flow chart is:
Read hall state -> check if hall state has changed, if yes -> check if hall state is now HIGH, if yes -> set rpm count to 0 -> delay 100ms to count how many LOWs has occured during that time -> calculate RPM bu multiplying rpm count by *300 -> send OUTPUT signal depending on RPM -> delay 50ms for debounce -> set current hall state as last hall state.
Now I'm also thinking if i should detach interrupt after that delay(100); and then attach it again after RPM dependant action? I mean if it should look like that:
const int hallPin = 12;
const int led = 13;
volatile int rpmcount = 0;
int rpm = 0;
int hallState = 0;
int lasthallState = 0;
void setup() {
Serial.begin(9600);
pinMode(led, OUTPUT);
pinMode(9, OUTPUT);
pinMode(hallPin, INPUT);
attachInterrupt(0, rpm_fan, FALLING);//interrupt zero (0) is on pin two(2), there is 0-5V square wave signal wire connected
}
void loop() {
hallState = digitalRead(hallPin); //Reads current hall state
if (hallState != lasthallState) { //if current hall state is different than last hall state then:
if (hallState == HIGH) { //check if current hall state is HIGH, if yes then:
rpmcount = 0; // set number of interrupts to 0, to begin counting
delay(100); //wait 100ms, it will run rpm_fan during that time and count LOWs on pin 2
detachInterrupt(0); //detach interrupt for calculating
rpm = rpmcount * 300; // Convert frecuency to RPM, * 300 = *10 * 30,, *10 - to make it into 1sec, *30, because two interupts per full rotation.
if (rpm <= 4000) {} //if rpm is lower than 4000 then do nothing
else if ((rpm <= 8000) && (rpm > 4000)) { // if 4000<rpm <= 8000 then at pin 9 - HIGH -> 80ms -> LOW
digitalWrite(9, HIGH);
delay(80);
digitalWrite(9, LOW);
}
else if ((rpm <= 10000) && (rpm > 8000)) {
digitalWrite(9, HIGH);
delay(70);
digitalWrite(9, LOW);
}
else if (rpm > 10000) {
digitalWrite(9, HIGH);
delay(60);
digitalWrite(9, LOW);
}
else {}
attachInterrupt(0, rpm_fan, FALLING); //enable interrupt again
}
else {}
delay(50);
}
lasthallState = hallState;
}
void rpm_fan() { /* this code will be executed every time the interrupt 0 (pin2) gets low.*/
rpmcount++;
}