Full code below. Note- I have encountered what seems to be noise errata in this system, which has caused me to isolate the fans from the arduino (as it should). They are triggered through a mechanical relay board that provides isolation, and the power to flip the relays in the board is dedicated as well.
I have 3 supplies. A 12V supply that powers the fans, and the LED side of an optocoupler. The other side of the opto is the arduino circuit powered by a separate 12v supply. The opto is brought up/down by the hall effect sensor in the fan. The third supply is a 5V supply that powers the J-VCC on the relay board.
Creating this true electrical isolation solved my problems and got me to deploy this system. However, it still failed when I ran BOTH fans, even when one hall effect sensor was completely disconnected. Which made me think one fan, purely by running, is inducing noise in the other fans signal. However, I could read the signal at the arduino and it looked perfect (I debounced etc and nothing every got it reading correctly with both running). So, my system runs one fan, measures it, then runs the other, measures it. "Both running" would mean (to the arduino): two low signals to the relay board to close this circuits, the 5v then flips the relays which allows the 12v+ to power the fans. Both Optos recieving hall effect sensor signals (ground). I never made sense of this, but the system reacted similar as it does now with this new fan.
Anyways- running one fan at a time, the system has been working perfectly for 300+ tests. Now, I introduce the higher speed fan (which, does have some additional features internally- slow start etc, but the voltage/amperage and hall effect are the same). When the fan gets to 17,000+, the system goes bonkers as I saw before when circuits got noisy (may not be fact, hypothesizing). Readings go all over the place basically, even when before I could read the signal to the arduino is fine.
So, I put in this debounce thinking it was reading way too many cycles. Which it doesnt appear to, but since I put this in, the system locks up- Continues to Serial.print, but it seems functions outside of the Interrupt are not working. Note this may be 100% caused by putting serial.print in the interrupt, and if so is NOT the root cause but more errata I have caused by trying to troubleshoot.
One piece of info- when it locks up, and I power the whole system down while plugged into the USB (so fans shut off, optos get no LED power), the system catches back up to itself/un-locks up. So the 12v+ from the fans and the hall effect somehow are causing it to lock up. This would stop the interrupts, and if the serial.print is causing this issue, would explain it. But, not explain why the system gets terrible readings when the fan speeds up.
When the fan is sped up, the system is in delay(1000), with interrupt on only L=L+1 for interrupt. The loop its performing was working perfectly for the first 12 seconds and perfectly for slower moving fans, so its 100% related to the fan speeding up and whatever electrical (likely) fallout that is causing. Turning on/off fans doesnt cause any issues in the system.
Simplified circuit below (does not show the relay board, or any of the buttons/screens running purely off the arduino). Some value resistors etc have changed but you get the idea.
///SCREEN STUFF
#include <SPI.h>
#include <Wire.h>
#include <Adafruit_SSD1306.h>
#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels
#define OLED_RESET -1 // Reset pin # (or -1 if sharing Arduino reset pin)
#define SCREEN_ADDRESS 0x3C ///< See datasheet for Address; 0x3D for 128x64, 0x3C for 128x32
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
int lstart=1;// 25; //Where to start drawing updated RPM
int rstart=65;//95;
int yRPM=33;//18; //row where RPM info is
unsigned long timestamp;
String PN;
int ftime;
String PN1="9HV_08"; //14,900
int fan1min=14400;
int fan1max=15400;
int ftime1=9;
String PN0="9HVA08"; //16,100
int fan0min= 15600;
int fan0max= 16600;
int ftime0=9;
String PN2="9HVB08"; //18,3009HVB0812P1G001
int fan2min= 17800;
int fan2max= 18800;
int ftime2=16;
bool lpass=true;
bool rpass=true;
bool failure=false;
int min;
int max;
int lsensorpin = 2;
int rsensorpin= 3;
int rgled=4;
int rrled=5;
int gbut=7;
int rbut=6;
int lgled=8;
int lrled=9;
int lrelaypin= 10;
int rrelaypin=11;
int flippin1=12; //Guessing
int flippin2=15; //A1
int debugout=16; //A2
bool redexit=false;
int x=0;
int flipvalue=3;
bool flipchange=false;
unsigned long pmicros;
int bouncetime=500; //(debounce time in Micros)
bool TS=false;
volatile unsigned long L=0;
volatile unsigned long R=0;
unsigned long lRPM=0;
unsigned long rRPM=0;
void setup() {
pinMode(lsensorpin, INPUT);//_PULLUP); //2
pinMode(rsensorpin, INPUT);//_PULLUP); //3
pinMode(rgled, OUTPUT); //4
pinMode(rrled, OUTPUT); //5
pinMode(gbut, INPUT_PULLUP); //6
pinMode(rbut, INPUT_PULLUP); //7
pinMode(lgled, OUTPUT); //8
pinMode(lrled, OUTPUT); //9
pinMode(lrelaypin, OUTPUT); //10
pinMode(rrelaypin, OUTPUT); //11
pinMode(flippin1, INPUT_PULLUP); //15
pinMode(flippin2, INPUT_PULLUP); //15
pinMode(debugout, OUTPUT);
//SDA18
//SCL19
// IDK WHy but screen needs this
if(!display.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS)) {
//Serial.println(F("SSD1306 allocation failed"));
for(;;); // Don't proceed, loop forever
}
display.display(); //Show Adafruit logo 2 seconds
delay(500); // Pause for 2 seconds
display.clearDisplay();
//setupscreen(1); will be done under setflipper
setflipper();
fanson(0);
lightdemo();
Serial.begin(9600);
Serial.println("FInish Setup");
}
//void loop(){};
void loop() {
setflipper();
if ((failure==true) && (digitalRead(rbut)==false)){ //There was a failure and pressing red button to reset. If not pressing red it will go on to checking GO
setlights(0,0,0,0);
failure=false;
//SOMETHING RESETTING SCREEN BACK TO DISPLAYING MIN MAX
}
if ((failure==false) && (digitalRead(gbut)==false) && (TS==false)){ //No previous failure and Green is go
setupscreen(1);
setlights(0,0,0,0);
L=0;
R=0;
lRPM=0;
rRPM=0;
initiateandmonitor(1);
//Serial.print("Got out of initiate with redexit=");
//Serial.println(redexit);
if (redexit==false){ //Spun up without red button
//setupscreen(40); //"Left"
//attachl();
initiateandmonitor(2);
if (redexit==false){
//measure right
//shut down and measure/displauy
fanson(0);
lpass= (lRPM<max && lRPM>min);
rpass= (rRPM<max && rRPM>min);
if (lpass==true && rpass==true){
failure=false;
setlights(1,0,1,0);
}else if (lpass==true && rpass==false){
failure=true;
setlights(1,0,0,1);
}else if (lpass==false && rpass==true){
failure=true;
setlights(0,1,1,0);
}else{
failure=true;
setlights(0,1,0,1);
}
setupscreen(2);
}
}
}
}
void setflipper(){
flipchange=false;
if (digitalRead(flippin1)==false) {
if (flipvalue!=1){ //value has changed
TS=false;
flipchange=true;
flipvalue=1;
PN=PN1;
ftime=ftime1;
min=fan1min;
max=fan1max;
}
}else if(digitalRead(flippin2)==false){
if (flipvalue!=2){ //value has changed
TS=false;
flipchange=true;
flipvalue=2;
ftime=ftime2;
PN=PN2;
min=fan2min;
max=fan2max;
}
}else{
if (flipvalue!=0){ //value has changed
if(digitalRead(rbut)==false){
TS=true;
flipchange=true;
flipvalue=0;
ftime=60;
PN="TShoot";
min=0;
max=0;
}else {
TS=false;
flipchange=true;
flipvalue=0;
ftime=ftime0;
PN=PN0;
min=fan0min;
max=fan0max;
}
}
}
if(flipchange==true){setupscreen(1);}
}
void tickL() {
if ((micros()-pmicros)>bouncetime){
L=L+1;
}else{
Serial.print("Did not count cycle of: ");
Serial.println(micros()-pmicros);
}
pmicros=micros();
}
void tickR() {
if ((micros()-pmicros)>bouncetime){
R=R+1;
}else{
Serial.print("Did not count cycle of: ");
Serial.println(micros()-pmicros);
}
pmicros=micros();
}
void setlights(bool lg, bool lr, bool rg, bool rr) {
digitalWrite(lgled, lg);
digitalWrite(lrled, lr);
digitalWrite(rgled, rg);
digitalWrite(rrled, rr);
}
void lightdemo() {
setlights(1,0,1,0);
delay(1000);
setlights(0,1,0,1);
delay(1000);
setlights(0,0,0,0);
}
void fanson(int fan) {
if(fan==1){ //LEFT
digitalWrite(lrelaypin, false);
digitalWrite(rrelaypin, true);
}else if(fan==2){
digitalWrite(lrelaypin, true);
digitalWrite(rrelaypin, false);
}else if (fan==0){
digitalWrite(lrelaypin, true);
digitalWrite(rrelaypin, true);
}
}
void attachl(){
attachInterrupt(digitalPinToInterrupt(lsensorpin), tickL, RISING);
}
void detachl(){
detachInterrupt(digitalPinToInterrupt(lsensorpin));
}
void attachr(){
attachInterrupt(digitalPinToInterrupt(rsensorpin), tickR, RISING);
}
void detachr(){
detachInterrupt(digitalPinToInterrupt(rsensorpin));
}
void initiateandmonitor(int fan){
fanson(fan);
//delay(500);
redexit=false;
for(x = ftime; x>0; x--){
if(digitalRead(rbut)==false){
redexit=true;
fanson(0);
Serial.println("Breaking the fans");
setlights(0,1,0,1);
setupscreen(3);
break;
}else{
if (fan==1){
L=0;
pmicros=micros();
attachl();
delay(1000);
detachl();
lRPM=L*30;
}else if(fan==2){
R=0;
pmicros=micros();
attachr();
delay(1000);
detachr();
rRPM=R*30;
}
setupscreen(2);
}
}
if(x=0) Serial.println("Spun up with no red button");
}
//SCREENSTUFFFFFFF
void setupscreen(int y) { //y=1 for showing PN being tested. y=2 to display results, y=3 for count down
display.clearDisplay();
display.setTextSize(2); // Draw 2X-scale text
display.setTextColor(SSD1306_WHITE);
if (y==1){
//Lines
display.drawLine(0, 15, display.width()-1, 15, SSD1306_WHITE);
display.drawLine(0, 16, display.width()-1, 16, SSD1306_WHITE);
display.drawLine(62, 15, 62, 55, SSD1306_WHITE);
//Header
display.setCursor(0, 0);
display.print("PN:");
display.setCursor(50, 0);
display.print(PN);
//RPM HEaders
display.setTextSize(1);
display.setCursor(0, 18);
display.print("MIN:");
display.setCursor(70, 18);
display.print("MAX:");
display.setCursor(0, 48);
display.print("SPINUP:");
//Print Min Max
display.setCursor(lstart, yRPM);
display.print(min);
display.setCursor(rstart, yRPM);
display.print(max);
display.setCursor(45, 48);
display.print(ftime);
}else if (y==2){
//Lines
display.drawLine(0, 15, display.width()-1, 15, SSD1306_WHITE);
display.drawLine(0, 16, display.width()-1, 16, SSD1306_WHITE);
display.drawLine(62, 15, 62, 55, SSD1306_WHITE);
//Header
display.setCursor(0, 0);
display.print("Left");
display.setCursor(68, 0);
display.print("Right");
//RPM HEaders
display.setTextSize(1);
display.setCursor(0, 18);
//display.print("RPM:");
if(x>0){
display.print("RPM: T:");
display.setCursor(50, 18);
display.print(x);
} else{
display.print("RPM:");;
}
display.setCursor(65,18);
display.print("RPM:");
//PN at bottom when printing RPM
display.setCursor(0,55);
display.print(String(PN));
display.setCursor(65,48);
display.print(min);
display.setCursor(65,55);
display.print(max);
//Serial.println("Part is " + PN);
//Print RPM's
display.setTextSize(2);
display.setCursor(lstart, yRPM);
display.print(lRPM);
display.setCursor(rstart, yRPM);
display.print(rRPM);
}else if (y==3){ //fans spinning
if (redexit==true){
display.setTextSize(3);
display.setCursor(5,24);
display.print("STOP");
}else{
//Lines
display.drawLine(0, 15, display.width()-1, 15, SSD1306_WHITE);
display.drawLine(0, 16, display.width()-1, 16, SSD1306_WHITE);
//Header
display.setCursor(0, 0);
display.print("SPIN UP");
//Countdown
display.setTextSize(3);
display.setCursor(50,20);
display.print(x);
}
}else if (y==40){ //LEft
//Lines
display.drawLine(0, 15, display.width()-1, 15, SSD1306_WHITE);
display.drawLine(0, 16, display.width()-1, 16, SSD1306_WHITE);
//Header
display.setCursor(0, 0);
display.print("Measure");
//Countdown
display.setTextSize(3);
display.setCursor(20,20);
display.print("Left");
}else if (y==41){ //Right
//Lines
display.drawLine(0, 15, display.width()-1, 15, SSD1306_WHITE);
display.drawLine(0, 16, display.width()-1, 16, SSD1306_WHITE);
//Header
display.setCursor(0, 0);
display.print("Measure");
//Countdown
display.setTextSize(3);
display.setCursor(30,20);
display.print("Right");
}
display.display();
}