First of all, I would like to apologise if this is posted in the wrong place. I have been reading these forums to try and get my fan circuit working but no luck.
I want to control a DC fan with an LM35 and an Arduino Uno. The LM35 sensor is going to be mounted to an LED heatsink and I would like to keep the temperature at a set point.
I have tried the circuit with two fans and had no luck. The fan that I am currently using is: 12V DC Fan
I have attached my circuit schematic, the code that I have used is as follows:
int tempPin = A0; // the output pin of LM35
int fan = 13; // the pin where fan is
int led = 8; // led pin
int temp;
int tempMin = 20; // the temperature to start the fan
int tempMax = 50; // the maximum temperature when fan is at 100%
int fanSpeed;
void setup() {
pinMode(fan, OUTPUT);
pinMode(led, OUTPUT);
pinMode(tempPin, INPUT);
analogReference(INTERNAL);
Serial.begin(9600);
}
void loop() {
temp = readTemp(); // get the temperature
if(temp < tempMin) { // if temp is lower than minimum temp
fanSpeed = 0; // fan is not spinning
digitalWrite(fan, LOW);
}
if((temp >= tempMin) && (temp <= tempMax)) { // if temperature is higher than minimum temp
fanSpeed = map(temp, tempMin, tempMax, 100, 255); // the actual speed of fan
analogWrite(fan, fanSpeed); // spin the fan at the fanSpeed speed
}
Serial.print("TEMP = ");
Serial.print(temp);
Serial.println("DEG C");
delay(500);
}
int readTemp() { // get the temperature and convert it to celsius
temp = analogRead(tempPin);
return temp * 0.107421875;
}
When I power the circuit on the fan is not spinning. Once the temperature goes above the minimum temperature set the fan goes to 100% output, it appears to have no modulation.
The temperature sensor is working correctly and displays the correct value in the Serial Monitor.
Can I connect the PWM signal cable to the PWM pin and the +/- pins to +/- 12V DC?
I see that the fan has a relatively high start up voltage of 7V. Could I set the minimum value in the map function to the equivilent value? In my mind that would be (255/12V)*7V
You are using the analogReference(INTERNAL) which is a 1.1V MAX range. The LM335 outputs 10 mV/deg C. You are then multiplying THAT value by 0.107421875. (which you later use for the MAP function).
If the temp were 100 dec C, (for example) the LM35 would return 1V which you then multiply by 0.107421875 which would give you 0.107 for the MAP function. I have no idea why you are using the
INTERNAL analog reference than cannot accept a value greater than 1.1V but IMO you should be using
the DEFAULT reference.
raschemmel:
I'm saying you CANNOT read ANY voltage GREATER than 1.1V from the LM35 using INTERNAL analog reference.
So with my LM35 connected to 5V DC I am missing a lot of range or reducing the resolution by using 1.1V as a reference? Should I be feeding a clean 1.1V DC to the AREF pin?
Do the math. The LM35 output 10mV /per deg C . You are using an UNO. The DEFAULT analog reference is
5V. WHY are you NOT using the DEFAULT analog reference ? I don't understand why you are doing what you are doing. Change the analog reference to DEFAULT. But BEFORE you do that , MEASURE the voltage or at
LEAST post the values you are receiving for the INTERNAL analog reference.
From background reading 1.1V reference gives a more accurate reading (if you ingnore the 0.5 deg tolerance of the LM35).
Do the math
Temp = 110 deg C. * 0.01 V = 1.1V (the MAXIMUM input voltage when using INTERNAL reference).
My point ? If the thing you are measuring will NEVER exceed 110 deg C, then it is perfectly fine to use the
INTERNAL analog reference. Show me in your previous posts where you told us the MAXIMUM temperature you would need to measure . Consequently, I have no idea if your UUT will exceed 110 degrees.
The LM35 sensor is going to be mounted to an LED heatsink and I would like to keep the temperature at a set point.
I have no idea how hot that led can get.
Of course you could use a voltage divider but that's kind of lame when you can just change the analog reference. When you tell us what the maximum temp will be we can decide if what you are doing is appropriate. So far , I haven't seen it. If you have known all along it would never exceed 110 deg and just neglected to mention it, then I would say you should have mentioned that is why you are using INTERNAL reference.
If I were you I would just get rid of all the IF statement conditional stuff and simply :
fanSpeed = (temp * 5);
and forget the min/max stuff. The result is the same. For a temp of 20 deg C, the fanspeed =100
For a temp of 50 deg C the fanspeed = 250. That' close enough and at least it's better than what you have now. Keep it simple. I don't know why your code doesn't work but that's what I would do with my limited programming experience.