This took me far more time to write than it should have, but this code works within the limitations of only having digitalRead available. It’s not pretty but it’s functional. I’m going to roll most of this sketch and a few other bits into my existing project sketch and see how it goes…
// Experimental fan failure detection code for use with the MCP23017 port expander IC.
#include <SimpleTimer.h>
#include <Wire.h>
#include <Centipede.h>
int fanState1;// returns either HIGH or LOW
int fanState2;// returns either HIGH or LOW
int previousfanState1;// count of all HIGH's returned from the digitalRead(). Count is reset to 0 whenever a LOW is returned.
int previousfanState2;// count of all HIGH's returned from the digitalRead(). Count is reset to 0 whenever a LOW is returned.
SimpleTimer timer;
Centipede CS; // create Centipede object
void checkFanState() {
fanState1 = CS.digitalRead(9);// digitalRead() will toggle between 0 and 1, depending on the reading frequency of the function & the RPM of the fan.
fanState2 = CS.digitalRead(10);// 0 or LOW returned = Fans are ON. A continuously returned 1 or HIGH indicates that the fan is NOT rotating.
previousfanState1 = previousfanState1 + fanState1;// creates an counter that increments by 1 for each digitalRead() that returns HIGH.
previousfanState2 = previousfanState2 + fanState2;// creates an counter that increments by 1 for each digitalRead() that returns HIGH.
if (fanState1 < 1 ) {// if a LOW is returned....
previousfanState1 = 0;// reset the HIGH count to 0
Serial.print("FAN1 ON");// Normal Fan operation
Serial.println();
}
if (previousfanState1 > 10){// if a HIGH is returned more than 10 times in a row...we're assuming there's a problem.
Serial.print("FAN1 MALFUNCTION");
Serial.println();
}
else{
Serial.println(previousfanState1);
}
if (fanState2 < 1 ) {// if a LOW is returned....
previousfanState2 = 0;// reset the HIGH count to 0
Serial.print("FAN2 ON");// Normal Fan operation
Serial.println();
}
if (previousfanState2 > 10){// if a HIGH is returned more than 10 times in a row...we're assuming there's a problem.
Serial.print("FAN2 MALFUNCTION");
Serial.println();
}
else{
Serial.println(previousfanState2);
}
}
void setup() {
Serial.begin(9600);
Wire.begin(); // start I2C
CS.initialize(); // set all register to default
CS.pinMode(9, INPUT); // tach signal 1
CS.pinMode(10, INPUT); // tach signal 2
CS.pinMode(8, OUTPUT); //SET PIN TO OUTPUT
CS.digitalWrite(8, HIGH); // turns fans ON
timer.setInterval(1000L, checkFanState);
}
void loop() {
timer.run();
}