Re: fan speed without interrupts

I’m currently working on similar project. My goal is to operate multiple cabinet fans and control them using PWM.
The following code worked for me (at the time of post). Please find some bugs for me :confused: .
Here is the code

/*
 * RPM Counter for arduino without using Interrupt Service Routine (ISR)
 * Author: Sandeepan Sengupta
 * Dated: 28th June, 2016
 * West Bengal, India
*/

//Enable or Disable RPM debug for fans
bool FAN_1_debug = HIGH;
bool FAN_2_debug = HIGH;
bool FAN_3_debug = HIGH;

//Comment out the followings to disable fan features
#define FAN_1_cfg
#define FAN_2_cfg
#define FAN_3_cfg

//Comment out the followings to disable propagation delay in code
#define pulseIn_delay
#define calculation_delay

int pulse_count=2;

int FAN_1 = 2;
int FAN_2 = 7;
int FAN_3 = 8;

double FAN_1_RPM;
double FAN_1_RPM_MAX = 1200; // Manufacturer specified upper limit of RPM, may differ for the test sample
double FAN_1_RPM_min = 0; // Manufacturer specified lower limit of RPM, may differ for the test sample
double FAN_1_RPM_Tolerance = 0; // User/Manufacturer assigned tolerance range in percentage (eg 12 for 12% tolerance)

double FAN_2_RPM;
double FAN_2_RPM_MAX = 1200;
double FAN_2_RPM_min = 0;
double FAN_2_RPM_Tolerance = 0;

double FAN_3_RPM;
double FAN_3_RPM_MAX = 1200;
double FAN_3_RPM_min = 0;
double FAN_3_RPM_Tolerance = 0;

void setup() 
{
Serial.begin(9600); 
 {
  while(!Serial);
 }

pinMode(FAN_1, INPUT); 
digitalWrite(FAN_1,HIGH); //Internal pull-up

pinMode(FAN_2, INPUT); 
digitalWrite(FAN_2,HIGH); //Internal pull-up

pinMode(FAN_3, INPUT); 
digitalWrite(FAN_3,HIGH); //Internal pull-up
}  

void loop() 
{
  #ifdef FAN_1_cfg
  Serial.println("Results for FAN 1:");
  FAN_1_RPM = RPM_Counter(FAN_1, pulse_count, FAN_1_RPM_MAX, FAN_1_RPM_min, FAN_1_RPM_Tolerance, FAN_1_debug);
  #endif
  
  #ifdef FAN_2_cfg
  Serial.println("Results for FAN 2:");
  FAN_2_RPM = RPM_Counter(FAN_2, pulse_count, FAN_2_RPM_MAX, FAN_2_RPM_min, FAN_2_RPM_Tolerance, FAN_2_debug);
  #endif
  
  #ifdef FAN_3_cfg
  Serial.println("Results for FAN 3:");
  FAN_3_RPM = RPM_Counter(FAN_3, pulse_count, FAN_3_RPM_MAX, FAN_3_RPM_min, FAN_3_RPM_Tolerance, FAN_3_debug);
  #endif
}

//Defination for RPM_Counter() function.
/*
 tacho_pin  = digital pin number to attatch Tachometer (RPM source)
 pulse      = Number of pulse produced by Tachometer for one full rotation (360 degree).
              (Usually 2 Pulses per revolution.)
 RPM_debug  = Set HIGH/LOW to eanble/disable serial monitor output for debugging
 MAX        = Upper Limit of expected RPM value
 MIN        = Lower Limit of expected RPM value
 Tolerance  = Tolerance Range (Percentage Value)
*/
double RPM_Counter(int tacho_pin, int pulse, double MAX, double MIN, double Tolerance, bool RPM_debug )
{
  unsigned long Rise_Time   = 0; 
  unsigned long Fall_Time   = 0;

  //Function call : pulseIn();
  Rise_Time = pulseIn(tacho_pin, HIGH);
  #ifdef pulseIn_delay
  delay(50);
  #endif
  
  Fall_Time = pulseIn(tacho_pin, LOW);
  #ifdef pulseIn_delay
  delay(50);
  #endif

  //Calculations
  unsigned long Total_Time  = Rise_Time + Fall_Time;
  #ifdef calculation_delay
  delay(10);
  #endif
  
  double        frequency   = 1000000/(pulse*Total_Time);
  #ifdef calculation_delay
  delay(10);
  #endif
  
  double        RPM         = frequency*60;
  #ifdef calculation_delay
  delay(10);
  #endif

  //Validation for RPM value
  bool validation = RPM_validate(RPM, MAX, MIN, Tolerance);
  
  if (RPM_debug == LOW)
  {
    Serial.println("RPM debug is off\n\n");
  }
  else
  if (RPM_debug == HIGH && validation == HIGH)
  {
    Serial.print("\nHIGH Pulse Duration:\t"); 
    Serial.print(Rise_Time);  
    Serial.print(" microseconds"); 
    
    Serial.print("\nLOW pulse duration:\t"); 
    Serial.print(Fall_Time);  
    Serial.print(" microseconds"); 
    
    Serial.print("\nTotal Time:\t\t"); 
    Serial.print(Total_Time); 
    Serial.print(" microseconds"); 
    
    Serial.print("\nFrequency:\t\t"); 
    Serial.print(frequency); 
    Serial.print(" Hertz"); 
    
    Serial.print("\nRPM:\t\t\t"); 
    Serial.print(RPM);
    Serial.println("\n\n");
    
    return RPM;
  }
  else
  if (RPM_debug == HIGH && validation == LOW)
  {
    Serial.println("System Error:\tRPM out of range\n\n");
  }
}

bool RPM_validate(double RPM_value, double RPM_MAX, double RPM_min, double RPM_Tolerance)
{
  if (RPM_value<RPM_min*(1-0.01*RPM_Tolerance)||RPM_value>RPM_MAX*(1+0.01*RPM_Tolerance))
  {
    #ifdef calculation_delay
    delay(10);
    #endif
    
    return LOW;
  }
  else
  {
    return HIGH;
  }
}

Sandeepan: The following code worked for me (at the time of post). Please find some bugs for me

Where should I put them?

...R

@Sandeepan, please do not cross-post. Please do not hijack.

Referenced threads... http://forum.arduino.cc/index.php?topic=134041.0 http://forum.arduino.cc/index.php?topic=167448.0