Hello all I am very new to arduino and having difficulty with my first project.
I know it has been done before, but I am trying to temperature control 3 12v fans using PWM. I have the hardware portion figured out using TIP120's and a temp36 reading to an LCD. I have the circuits working separately I am just not sure how to combine them and make the fans speeds controlled by the temp. Here are the separate codes I am using.
for temp
#include <LiquidCrystal.h>
float tempC;
float tempF;
float voltage;
int reading;
int tempPin=0; //analog channel
int interval = 50; //in ms (how often screen reprints
// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(7, 8, 9, 10, 11, 12);
void setup() {
// set up the LCD’s number of rows and columns:
lcd.begin(20,4);
// Print a message to the LCD.
lcd.setCursor(0,1);
lcd.print("Cabinet Temperature:");
}
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 = ((tempC9/5)+32); //convert C temperature to F
// (note: line 1 is the second row, since counting begins with 0):
lcd.setCursor(0, 2);// 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,3); //print set temp to lcd
lcd.print("Set Temp: 80 ");
lcd.print((char)223);
lcd.print("F");
}
for PWM fans
// Define which pin to be used to communicate with Base pin of TIP120 transistor
int TIP120pin = 3; //for this project, I pick Arduino's PMW pin 3
void setup()
{
pinMode(TIP120pin, OUTPUT); // Set pin for output to control TIP120 Base pin
analogWrite(TIP120pin, 255); // By changing values from 0 to 255 you can control motor speed
}
void loop()
{
}
In the example I only show 1 fan, but I will just replicate the circuit three times assigning different pins.
#include <LiquidCrystal.h>
float tempC;
float tempF;
float voltage;
int reading;
const int tempPin = 0; //analog channel
const int TIP120pin = 3; //for this project, I pick Arduino's PMW pin 3
const int interval = 50; //in ms (how often screen reprints
const int setPointF = 80;
// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(7, 8, 9, 10, 11, 12);
void setup() {
// set up the LCD’s number of rows and columns:
lcd.begin(20,4);
// Print a message to the LCD.
lcd.setCursor(0,1);
lcd.print("Cabinet Temperature:");
pinMode(TIP120pin, OUTPUT); // Set pin for output to control TIP120 Base pin
}
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, 2);// 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,3); //print set temp to lcd
lcd.print("Set Temp: 80 ");
lcd.print((char)223);
lcd.print("F");
// If the temperature is highher than the set point, run the fans.
// Fans reach full speed then temperature is more than 10°F above setpoint.
analogWrite(TIP120pin, constrain( (tempF - setPointF) * 25, 0, 255));
}
Would I be able to make the fans start up at 255 for about 5 secs then reduce speed according to temp? I tried adding this before the final line but it didn't work
Perhaps a PID control loop would produce better results than an arbitrary 5-second burst of full speed. See: Arduino Playground - PIDLibrary
The PID loop will take the current temperature and setpoint temperature as inputs and will produce the PWM value for the fans as output. It will track the difference between the current temperature and setpoint and adjust the fans so that the temperature stays close to the setppoint. As the temperature approaches the setpoint (but still below it) the fans will come on to try to prevent the temperature from going above the setpoint. As the temperature drops the fans will slow down.
The issue I am having now is that when the fans try to come on at low speeds, sometimes they will not turn. My thought was to have them initially begin at full speed then scale back down after a few seconds. I am just not sure what to add to make this occur. I am still using the sketch above. Some one please help. Thanks in advance.
mrob73:
The issue I am having now is that when the fans try to come on at low speeds, sometimes they will not turn.
You could just ignore the problem. If the temperature rises more then more power will be sent to the fan.
You could set a minimum output other than 0. Find the PWM value that is sufficient to start the fan and use that as the low end of the control range. For example if you determined that the fan will not start for values below 52 you could make the output range 0 to 203. If the control value is 0 use 0. For any other value, add 52. That way the PID loop can stop the fan (0) or run the fan a various speeds 1-203 -> 53-255.
This will start the fan at high speed, and ramp it down to the correct speed, slowing the speed every 10 milliseconds.
You have a fundamental problem, though. When tempF is near setPointF, the fan will be turned on and off for short periods of time. It would be better to run the fan for a while if tempF gets above setPointF. Run the fan for longer than the minimum to get back to setPointF. Either run the fan for a fixed time, or run it until tempF is setPointF - 2, for instance.
Or, combine John and PaulS's approaches. Determine by experiment the minimum pwm value that will start the fan and the minimum that will keep it running when it has been started, which is likely less. Use the second value as the minimum you'll accept to run the fan and use the first as the starting point in PaulS' ramp down loop. To be a little safer, you might want to add a little margin to both these values.
Thanks a ton guys that was all very informative. I learned a lot in that little conversation. When I get it all put together and working I will post the sketch. Thanks again.