Fan RPM to LCD

I am having trouble reading the RPM of a PWM controllable fan to an LCD. I have tried several examples from several places and have been unable to get them to work. I know I am missing something small I just can't figure out what. Any help would be greatly appreciated. This is the final piece to my puzzle.Sorry the sketch is a little messy, I just haven't cleaned it up yet. I am using a four wire fan blue wire is control, yellow wire is RPM.

#include <LiquidCrystal.h> 
float tempC; 
float tempF; 
float voltage; 
int reading; 
int interval = 50;
int fanPulse = 2;
unsigned long pulseDuration;
//constants
const int tempPin = 0; //analog channel 
const int fan1 = 3; //fan 1
const int fan2 = 6;//fan 2
const int setPointF = 68; //changing this set point will determine cabinet temperature and will be diplayed on the LCD

// initialize the library with the numbers of the interface pins 
LiquidCrystal lcd(7, 8, 9, 10, 11, 12); 

void setup() { 
  pinMode(fan1, OUTPUT); // Set pin for output to control fan 1
  pinMode(fan2, OUTPUT); // Set pin for output to control fan 2
  Serial.print(9600);
  pinMode(fanPulse,INPUT);
  digitalWrite(fanPulse,HIGH);
  // establishes fan start up on lcd
  lcd.begin(16, 2);
  lcd.print(" Starting Up");
  lcd.setCursor(0,1);
  lcd.print(" Please Wait");
  delay(10000);
  lcd.clear();
}
  void readPulse() {
  pulseDuration = pulseIn(fanPulse,LOW);
  double frequency = 1000000/pulseDuration;
  Serial.print("pulse duration:");
Serial.println(pulseDuration);
Serial.print("time for full rev. (microsec.):");
Serial.println(pulseDuration*2);
Serial.print("freq. (Hz):");
Serial.println(frequency/2);
Serial.print("RPM:");
Serial.println(frequency/2*60);

} 
void loop() { 
   //TMP36 voltage at the output varies linearly with ambient temperature. 
  //As a result,it can be used as a thermometer according to the equation:
  // ?C = (Vout(V) - .5)*100 
  //To find Vout in V, we use the following equation for a 5V input 
  // Vout(V) = AnalogReading*(5/1024) 
  reading = analogRead(tempPin);   //read the value from the sensor 
  voltage = reading*(5.0/1024);  //convert reading to voltage (in V), for 5V input 
  tempC = (voltage-0.5)*100;   //convert voltage to temperature 
  tempF = ((tempC*9/5)+32); //convert C temperature to F 
  // (note: line 1 is the second row, since counting begins with 0): 
  lcd.setCursor(0,0);// set the cursor to column 0, line 1 
  lcd.print(tempF);  //Print Fahrenheit temperature to LCD 
  lcd.print((char)223); // degree symbol 
  lcd.print("F "); 
  lcd.setCursor(10,0);
  lcd.print("RPM:");
  lcd.setCursor(0,5);  //print set temp to lcd
  lcd.print("Set:");
  lcd.setCursor(4,1);
  lcd.print(setPointF);
  lcd.print((char)223);
  lcd.print("F");
  lcd.setCursor(9,1);


  
  
  // If the temperature is higher than the set point, run the fans.
  // Fans reach full speed when temperature is more than 10°F above setpoint.
  analogWrite(fan1,constrain( (tempF - setPointF) * 25, 0, 255));
  analogWrite(fan2,constrain( (tempF - setPointF) * 25, 0, 255));

}

I am having trouble reading the RPM of a PWM controllable fan to an LCD.

So, what exactly are we looking for? What does "a little trouble" mean? You can't read the RPM? You can't write anything to the LCD? You can't write something specific to the LCD?

I am using a four wire fan blue wire is control, yellow wire is RPM.

Useful information only if we had the same fan. Since we have no clue what fan you have, there is no possibility of knowing whether we do, or not.

Why have you posted code for the readPulse() function when you never call it?

Which are you having problems with - the getting of the RPM or the displaying of things on the LCD?

I haven't been able to read the RPM of the fan and write it to the LCD. I had The RPM writing to the serial monitor, but I am not sure how to get it to the LCD.

Useful information only if we had the same fan. Since we have no clue what fan you have, there is no possibility of knowing whether we do, or not.

Why have you posted code for the readPulse() function when you never call it?

The fan I am using is a Rocketfish RF 120. I was trying to use the readPulse() function to read the pulses from the fan. So that I could use that to determine the RPM.

I had The RPM writing to the serial monitor, but I am not sure how to get it to the LCD.

Are you able to get anything to appear on the LCD? If not, then your problem is not about getting the RPM to appear on the LCD.

If so, then you need to call the readPulse() function.

Everything else is printing to the LCD with the exception of the RPM value.

Everything else is printing to the LCD with the exception of the RPM value.

Nowhere in the code you posted do you try to print RPM to the LCD. Nowhere in loop() in that code do you even KNOW RPM.

PaulS:

Everything else is printing to the LCD with the exception of the RPM value.

Nowhere in the code you posted do you try to print RPM to the LCD. Nowhere in loop() in that code do you even KNOW RPM.

Then I guess my next question is how do I correct these issues? Sorry for being such a noob.

Then I guess my next question is how do I correct these issues?

You said:

I was trying to use the readPulse() function to read the pulses from the fan. So that I could use that to determine the RPM.

You also said:

I had The RPM writing to the serial monitor, but I am not sure how to get it to the LCD.

How did you have the RPM writing to the serial monitor? Was it from the readPulse() function being called?

This was the sketch I was using for testing the fans. I just checked it again and everything prints to the serial monitor.

 int fanPulse = 2;
unsigned long pulseDuration;
const int fan1 = 3;
const int fan2 = 6;

void setup()
{
Serial.begin(9600);
pinMode(fanPulse, INPUT);
digitalWrite(fanPulse,HIGH);
}

void readPulse() {
pulseDuration = pulseIn(fanPulse, LOW);
double frequency = 1000000/pulseDuration;

Serial.print("pulse duration:");
Serial.println(pulseDuration);

Serial.print("time for full rev. (microsec.):");
Serial.println(pulseDuration*2);
Serial.print("freq. (Hz):");
Serial.println(frequency/2);
Serial.print("RPM:");
Serial.println(frequency/2*60);

}

void loop()
{
analogWrite(fan1,20);
delay(5000);
analogWrite(fan2,100);
readPulse();
analogWrite(fan1,50);
analogWrite(fan2,75);
delay(5000);
readPulse();
analogWrite(fan1,100);
analogWrite(fan2,255);
delay(5000);
readPulse();
analogWrite(fan1,0);
analogWrite(fan2,0);
delay(10000);
}

Once I established this as working I began adding it to the code posted earlier. I cannot get anything to print to the serial monitor with the combined sketch. I'm not sure what I did wrong.

This line in your first sketch won't be helping:

  Serial.print(9600);

Once I established this as working I began adding it to the code posted earlier. I cannot get anything to print to the serial monitor with the combined sketch. I'm not sure what I did wrong.

For one thing, you failed to post the combined sketch.

The combined sketch was the first one I posted.

The combined sketch was the first one I posted.

That sketch did not call readPulse(). The only write to the serial port occurred in readPulse();

See reply #10. There is no Serial.begin() in that sketch.

After a few hours of trial and error and taking into consideration the previous advice received from earlier posts. I got it to work. The only issue I am having is once the RPM of the fans goes above 1300 and then ramps back down the display reads the value as a four digit number rather than a three digit number. For example 400 is displayed as 4000, 600 is displayed as 6000, etc. I'm not sure why, but it is closer. This is the sketch I am currently running.

#include <LiquidCrystal.h> 
float tempC; 
float tempF; 
float voltage; 
int reading; 
int interval = 50;
int NbTopsFan; //Varibles used for calculations
int Calc;
int hallsensor = 2;
typedef struct{                  //Defines the structure for multiple fans and their dividers
  char fantype;
  unsigned int fandiv;
}fanspec;
//Definitions of the fans
fanspec fanspace[3]={{0,1},{1,2},{2,8}};

char fan = 1;   //This is the varible used to select the fan and it's divider, set 1 for unipole hall effect sensor 
               //and 2 for bipole hall effect sensor 


void rpm ()      //This is the function that the interupt calls 
{ 
 NbTopsFan++; 
}
//constants
const int tempPin = 0; //analog channel 
const int fan1 = 3; //fan 1
const int fan2 = 6;//fan 2
const int setPointF = 68; //changing this set point will determine cabinet temperature and will be diplayed on the LCD

// initialize the library with the numbers of the interface pins 
LiquidCrystal lcd(7, 8, 9, 10, 11, 12); 

void setup() { 
  pinMode(fan1, OUTPUT); // Set pin for output to control fan1
  pinMode(fan2, OUTPUT); // Set pin for output to control fan2
  pinMode(hallsensor, INPUT);
  attachInterrupt(0, rpm, RISING);
  // establishes fan start up on lcd
  lcd.begin(16, 2);
  lcd.print(" Starting Up");
  lcd.setCursor(0,1);
  lcd.print(" Please Wait");
  delay(10000);
  lcd.clear();
} 
void loop() { 
   //TMP36 voltage at the output varies linearly with ambient temperature. 
  //As a result,it can be used as a thermometer according to the equation:
  // ?C = (Vout(V) - .5)*100 
  //To find Vout in V, we use the following equation for a 5V input 
  // Vout(V) = AnalogReading*(5/1024) 
  reading = analogRead(tempPin);   //read the value from the sensor 
  voltage = reading*(5.0/1024);  //convert reading to voltage (in V), for 5V input 
  tempC = (voltage-0.5)*100;   //convert voltage to temperature 
  tempF = ((tempC*9/5)+32); //convert C temperature to F 
  // (note: line 1 is the second row, since counting begins with 0):
  NbTopsFan = 0;	//Set NbTops to 0 ready for calculations
   sei();		//Enables interrupts
   delay (1000);	//Wait 1 second
   cli();		//Disable interrupts
   Calc = ((NbTopsFan * 60)/fanspace[fan].fandiv); //Times NbTopsFan (which is apprioxiamately fequency the fan is spinning at) by 60 seconds before dividing by the fan's divider
 
  lcd.setCursor(0,0);// set the cursor to column 0, line 1 
  lcd.print(tempF);  //Print Fahrenheit temperature to LCD 
  lcd.print((char)223); // degree symbol 
  lcd.print("F "); 
  lcd.setCursor(0,7);  //print set
  lcd.print("Set:");
  lcd.setCursor(5,1);
  lcd.print(setPointF);
  lcd.print((char)223);
  lcd.print("F"); 
  lcd.setCursor(10,0);
  lcd.print("RPM");
  lcd.setCursor(10,1);
  lcd.print (Calc,DEC); //Prints " rpm"
  // If the temperature is higher than the set point, run the fans.
  // Fans reach full speed when temperature is more than 10°F above setpoint.
  analogWrite(fan1,constrain( (tempF - setPointF) * 25, 0, 255));
  analogWrite(fan2,constrain( (tempF - setPointF) * 25, 0, 255));

}

Any ideas as to why the value doesn't reset to three numbers?

Any ideas as to why the value doesn't reset to three numbers?

Try writing 3 spaces after the value. The 0 in 1000 does not get overwritten by anything in 999, so you see 9990 on the display.

Oh I forgot I added a 10k pull up resistor from pin 2 to 5V pin.

Thank you Paul that worked. Thanks everyone for the assistance.