Should be just a simple fan control but need some help

Okay so I’m trying to make a simple fan controller based on the temperature that a LM35 reads. My issue is that upon supplying the circuit with the 12v, the readings from the LM35 instantly become inaccurate. I have an optocoupler to create complete isolation from the 12v supply so i don’t understand why, or how this is happening. the LM35 and code uses voltage to sense temperature so i can only assume some how the voltage is leaking to the sensor. The fan I have does react to the temperature with my sketch, just the temperature itself is completely out of whack. Ive added a picture of my schematic as well as the code just incase its in the coding but i doubt it. I would like to say I’ve only been making arduino projects for a few months now so my knowledge is limited so i could be missing something very simple. any help is appreciated !
Im using an arduino pro mini 5v by the way just so you all know the hardware :slight_smile:

/*
Simple Temperature uses the lm35 in the basic centigrade temperature configuration
*/
float temp;
int cels = 20;
int tempPin = 2; // analog input pin
int sampleTime = 5000; // 1 second dafault
int fan =5;

//3, 5, 6, 9, 14, 15 PWM PINS
//200mA MAX ENTIRE BOARD, 150mA MAX WHEN RAW POWERED
// 16 = miso, 17= sck

void setup() {

Serial.begin(9600);
//analogWrite(pwm, 0);

pinMode(fan, OUTPUT);

}

void loop() {
//gets and prints the raw data from the lm35
temp = analogRead(tempPin);
// Serial.print("RAW DATA: “);
Serial.print (temp);
Serial.println(” ");
//converts raw data into degrees celsius and prints it out
// 500mV/1024=.48828125
cels = temp * 0.48828125;
Serial.print("CELSIUS: “);
//Serial.print(temp);
Serial.print(cels);
Serial.println(”*C ");
//converts celsius into fahrenheit
// temp = temp *9 / 5;
// temp = temp + 32;
// Serial.print(“FAHRENHEIT: “);
// Serial.print(temp);
// Serial.println(”*F”);

if(cels <26 )
{
//analogWrite(9,0);
digitalWrite(fan, LOW);
//lcd.print("Fan OFF ");
delay(100);
}

else if(cels==26)
{
//
digitalWrite(fan, HIGH);
//analogWrite(pwm, 51);
// lcd.print("Fan Speed: 20% ");
delay(100);
}

else if(cels==27)
{
digitalWrite(fan, HIGH);
// analogWrite(pwm, 102);
// lcd.print("Fan Speed: 40% ");
delay(100);
}

else if(cels==28)
{
// analogWrite(pwm, 153);
digitalWrite(fan, HIGH);
// lcd.print("Fan Speed: 60% ");
delay(100);
}

else if(cels==29)
{
digitalWrite(fan, HIGH);
//analogWrite(pwm, 204);
//lcd.print("Fan Speed: 80% ");
delay(100);
}
else if(cels>29)
{
digitalWrite(fan, HIGH);
//analogWrite(pwm, 0);
// lcd.print("Fan Speed: 100% ");
delay(100);
}
delay(2000);
}

Have you heard the word "ratiometric" before ? Some sensors have an analog output signal that is ratiometric. In that case it does not matter of the 5V changes, the value returned by analogRead() will be the same value.

The LM35 however, outputs an absolute voltage and the Arduino uses the 5V as reference. To be precise: the reference is default the Vcc of the ATmega328P microcontroller. When the 5V of the Arduino lowers to 4.5V, then the Arduino thinks that the temperature rises.

Because it is an analog signal, it can get electrical noise.

Do you have the circuit on a breadboard ? With a single GND wire ? Try to put the LM35 on its own breadboard. Or make a seperate part for the LM35 with its own GND wire to the Arduino. Or place everything in a different location on the breadboard, because they can have bad contacts.

You could use the internal voltage reference of 1.1V of the Arduino Pro Mini, or you can move forward and use a DS18B20.

A DS18B20 is very cheap and it communicates with the Arduino via a digital protocol. It is independent of voltages, it just returns the temperature.

/*
Simple Temperature uses the lm35 in the basic centigrade temperature configuration
*/
float temp;
int cels = 20;
int tempPin = 2; // analog input pin
int sampleTime = 5000; // 1 second dafault
int fan =5;

//3, 5, 6, 9, 14, 15 PWM PINS
//200mA MAX ENTIRE BOARD, 150mA MAX WHEN RAW POWERED
// 16 = miso, 17= sck

void setup() {

Serial.begin(9600);
//analogWrite(pwm, 0);

pinMode(fan, OUTPUT);

// put your setup code here, to run once:

}

void loop() {
// put your main code here, to run repeatedly:
//gets and prints the raw data from the lm35
temp = analogRead(tempPin);
// Serial.print("RAW DATA: “);
Serial.print (temp);
Serial.println(” ");
//converts raw data into degrees celsius and prints it out
// 500mV/1024=.48828125
cels = temp * 0.48828125;
Serial.print("CELSIUS: “);
//Serial.print(temp);
Serial.print(cels);
Serial.println(”*C ");
//converts celsius into fahrenheit
// temp = temp *9 / 5;
// temp = temp + 32;
// Serial.print(“FAHRENHEIT: “);
// Serial.print(temp);
// Serial.println(”*F”);

if(cels <26 )
{
//analogWrite(9,0);
digitalWrite(fan, LOW);
//lcd.print("Fan OFF ");
delay(100);
}

else if(cels==26)
{
//
digitalWrite(fan, HIGH);
//analogWrite(pwm, 51);
// lcd.print("Fan Speed: 20% ");
delay(100);
}

else if(cels==27)
{
digitalWrite(fan, HIGH);
// analogWrite(pwm, 102);
// lcd.print("Fan Speed: 40% ");
delay(100);
}

else if(cels==28)
{
// analogWrite(pwm, 153);
digitalWrite(fan, HIGH);
// lcd.print("Fan Speed: 60% ");
delay(100);
}

else if(cels==29)
{
digitalWrite(fan, HIGH);
//analogWrite(pwm, 204);
//lcd.print("Fan Speed: 80% ");
delay(100);
}
else if(cels>29)
{
digitalWrite(fan, HIGH);
//analogWrite(pwm, 0);
// lcd.print("Fan Speed: 100% ");
delay(100);
}
delay(2000);
}

Hi, Welcome to the forum.

Please read the first post in any forum entitled how to use this forum. http://forum.arduino.cc/index.php/topic,148850.0.html then look down to item #7 about how to post your code. It will be formatted in a scrolling window that makes it easier to read.

What is the problem?

Thanks.. Tom.. :)

There is an answer in your other post.

Please don't cross post.

Threads merged.