Help with LM35 fan I2C LCD project

Hey guys, noob to all this, I'm having some major trouble with this project, like the I2C simply isn't even turning on - even in the tinkercad simulation! And the 12V DC fan simply wont turn on as well, i have no idea what to do at this point so I thought some of you vets can correct any mistakes. Personally, I really don't see any issues with this but I think i may have short circuited the whole thing since when i tried plugging in my 12V DC adapter it fried, before that I was using a 12V AC adapter (I know it was dumb and i didn't realize it) . I got a new I2C and another 12V DC adapter this time.

Also for some quick background on the topic: I wanted to make a temperature based fan controller using the arduino uno along with an LM35 sensor, as well as a transistor to control the fan's speed. The lcd was supposed to show the temperature and the LED to signify any overheating (above 40 degrees celsius)

Also heres the full code -noob at c too :frowning:

#include <Wire.h>
#include <LiquidCrystal_I2C.h>

LiquidCrystal_I2C lcd(0x27, 16, 2);   //0x27 being the address here

const int tempPin = A0;
const int fanPin = 9;
const int ledPin = 6;

void setup() {
  lcd.begin(16, 2);
  lcd.backlight();

  pinMode(fanPin, OUTPUT);
  pinMode(ledPin, OUTPUT);
}

void loop() {
  // To read and smooth the temp
  int total = 0;
  const int samples = 10;  //Read temp sensor 10 times to smooth them out by averaging
  for (int i = 0; i < samples; i++) {
    total += analogRead(tempPin);
    delay(5);
  }

  float avg = total / (float)samples;
  float voltage = avg * (5.0 / 1023.0);
  float tempC = voltage * 100.0;  //converting voltage to degrees celsius

  // To display on LCD
  lcd.setCursor(0, 0);
  lcd.print("Temp: ");
  lcd.print(tempC, 1);
  lcd.print((char)223); //degree symbol
  lcd.print("C    ");

  // Fan Control Logic
  int pwm = map(tempC, 25, 45, 0, 255);  //mapping temp range from 25-45 Celsius with 25 off and 45 full to 0-255 PWM 
  pwm = constrain(pwm, 0, 255); //so the fan doesn't go outside this range
  if (pwm > 0 && pwm < 100) pwm = 100; //forces the fan to move immediately 

  analogWrite(fanPin, pwm); //sends the PWM value to the transistor

  digitalWrite(ledPin, tempC > 40 ? HIGH : LOW);  //if temp greater than 40 degrees , LED turns on
  delay(500);
}

I'll include the images of both the project irl, and the simulation, not sure if they'll actually upload since I'm new here but i hope they will



Please inform me if the images aren't clear enough, i can also send the simulation's schematic if needed

Hi, @turtlesfan
Welcome to the forum.

Can you please post a copy of your circuit, a picture of a hand drawn circuit in jpg, png?
Hand drawn and photographed is perfectly acceptable.
Please include ALL hardware, power supplies, component names and pin labels.

How are you powering the motor?

Can I suggest you start by getting "Hello World" in the LCD display.
NOTHING else.
Forget you code for the moment, and only have the LCD connected,
The LCD library you are using has example codes.
Get the LCD working first in the real world.
Then reading the temperature sensor.
Get it working and displaying on the LCD.
THEN get the motor working, just turning it ON and OFF.
Then combine it with your other code.

You will have more success in building your code in stages and getting each stage to work before combining them.

Tom.... :smiley: :+1: :coffee: :australia:

sure, i think this is how you want it...?


As for all the hardware:
LM35 sensor
arduino uno
2n2222 transistor
12V DC fan
16*2 LCD I2C
1kohm resistor and a 220Ohm , 10 microfarad capacitor
1n4007 diode, LED
12V DC adapter

Also this might be helpful but i was using a 12 V AC adapter instead previously, and the fan and lcd were actually working yesterday but only for a single run, after that they both died. The lcd i believe i accidentally messed around with one of its wires whilst it was powered on , and for the fan i think the AC adapter may have had something to do with it, although the DC adapter being fried afterwards still confuses me.

Also, I'll try out your suggestions with powering the LCD in just a moment.

Edit: THE LCD IS WORKING NOW???!!! ILL TRY AT IT FOR A BIT AND SEE IF IT WILL FINALLY WORK!!

EDIT 3: good news, temperature sensor works! bad news... i might be a little uncertain on my final fan circuit... will upload the picture of the final circuit on another reply in just a minute bc of the 3 picture limit:

What is the working current of this fan?
The 2N2222 suport max 600 mA.

The 2N2222 has a gain of ~50 (average).
With the 1K resistor at the base you will have about 5mA at the base/emitter.
With a gain of ~50, you will have ~250 mA collector/emitter.

It says its 100mA.

Also here are the images of the final circuit as promised :


Do you guys think theres anything wrong with the wiring? So far from the second "update " with the LM35, now im just installing the fan and for that i installed the transistor , resistor , diode, led and capacitor. I also first connected two wires from the ground and VIN on the arduino to the bottom side respective rails.

With the transistor (which im pretty sure with the 2n2222 model when its facing me flat side its emitter base collector left to right), the emitter is connected to the GRND, the base is connected to a 1kOhm resistor that connects to a wire that then connects to arduino pin 9, as for the collector, it is connected to the negative (black) wire of the fan from "behind", and from the front a diode was connected that was also connected in series with the fans positive (red wire), that was then also connected in series with a wire that connects to VIN rail, now over here i have a capacitor connected across that wire too at the VIN rail.

As for the LED, its short leg (cathode), is connected to the ground rail with a wire, the long leg (anode) is connected with a 220 Ohm resistor that is then connected with a wire to arduino pin 6.

Also, last thing that im most worried about is this adapter, it says AC-DC so i assume that the positive side means DC ? And is this configuration correct? Also do i connect it to the wall and avoid cord extenders?

please help me with this last part!!!

Do you have a DMM? Digital MultiMeter?

Where in your circuit diagram have you got the power supply connected?

Tom.... :smiley: :+1: :coffee: :australia:

Hi tom, it all worked out just fine in the end, I yolod it and it straight up worked this time, thank you for the help!

uhhhh this is a bit awkward coming back after thinking I have done it all but it turns out that my fan is producing some sort of electric noise that is messing up the lm35 sensors readings. Like, before i powered on the fan it could read the temperature well at a stable 21-22 degrees celsius, but after i powered it on with a 12V DC adapter to the arduino uno the readings become very unstable.

Actually, my lm35 sensor was also unstable for a bit until I added in a 10 microfarad ceramic capacitor (i added in another in parallel for extra measure), so I thought I could possibly do the same with the fans wires but im unsure how to go about it.

The circuit is pretty much the same as the last picture except a capacitor across the LM35 as well as the capacitor over the railings being removed. Sorry for rushing to conclusions earlier, I was so tired over this that I didnt fully check it lol. Also to answer your question i do not have one though i could go out and buy one later, and the power supply is connected to the arduino unos barrel jack.

Look closely at the gnd wiring of your project.
Get the gnd connection of the Fan as close as possible to the gnd of the UNO.

It sounds like your LM35 is sharing a considerable length of gnd circuit wiring with the fan.

Tom.... :smiley: :+1: :coffee: :australia:

By the fan GND you mean the yellow wire connected to the transistors emitter right? Well I moved it but it seems the lm35 is still functioning weirdly and not reading the real ambient temperature. Also, minor change but I had to tape the breadboard and other stuff down.

Hi,
Yes that's what I meant.

If you leave the fan disconnected, I understand the fault does not occur?
Did you place the capacitor between gnd and the LM35 signal wire?
Are the capacitors as close to the LM35 as possible.

Tom.... :smiley: :+1: :coffee: :australia:

Yes, if I run a code where it detects the temperature only it works fine, if I power on the circuit (with the fan and everything) with only a USB it also works fine- issue being that since its only 5V its not powering on fully. The main issue starts after i plug in the DC power adapter to power on the fan fully.

Also I added in a 1k Ohm resistor to the output of the LM35 in case it might work and added some more stuff into the code :

#include <LiquidCrystal_I2C.h>

//  LCD Setup 
LiquidCrystal_I2C lcd(0x27, 16, 2);  //address is 0x27

// Pin Definitions 
const byte sampleBin = 8;
const int tempPin = A0;     // LM35 out
const int fanPin = 9;       //  PWM control
const int ledPin = 6;       // LED

// Calibration Constants 
const int8_t fudge = 90;      // Adjust this for calibration (±5~10 usually fine)
const int kAref = 1090;       // Analog reference voltage in mV (1.1V = 1100mV)
const int kSampleBin = sampleBin * 1000; 

//  Temperature&Controlvars 
int tempC, tempF;
int pwm;
bool fanOn = false;
uint32_t temp = 0, start = 0;
const int interval = 500;  // Refresh rate 

void setup() {
  analogReference(INTERNAL);
  analogRead(tempPin);  // Dummy read

  // Pre-fill temp with average of 8 samples
  for (int i = 0; i < sampleBin; i++)
    temp += analogRead(tempPin);

  lcd.init();
  lcd.backlight();

  pinMode(fanPin, OUTPUT);
  pinMode(ledPin, OUTPUT);
  Serial.begin(9600);
}

void loop() {
  if (millis() - start > interval) {
    start = millis();

    //  average of samples
    temp -= (temp / sampleBin);
    temp += analogRead(tempPin);

    // Convert to °C 
    tempC = temp * kAref / (kSampleBin + fudge);
    tempF = (tempC * 18 + 3200) / 10;

    // LCD Display 
    lcd.setCursor(0, 0);
    lcd.print("Temp: ");
    lcd.print(tempC / 10);
    lcd.print(".");
    lcd.print(tempC % 10);
    lcd.print((char)223);
    lcd.print("C    ");

    // Fan Control with Hysteresis 
    if (!fanOn && tempC >= 160) {       // 16.0°C
      fanOn = true;
    } else if (fanOn && tempC <= 140) { // 14.0°C
      fanOn = false;
    }

    pwm = fanOn ? map(tempC, 150, 450, 100, 255) : 0;
    pwm = constrain(pwm, 0, 255);
    analogWrite(fanPin, pwm);

    //  Overheat LED 
    digitalWrite(ledPin, tempC > 400 ? HIGH : LOW); // 40.0°C threshold

    // Serial Debug 
    Serial.print("ADC: ");
    Serial.print(analogRead(tempPin));
    Serial.print(" | Temp: ");
    Serial.print(tempC / 10);
    Serial.print(".");
    Serial.print(tempC % 10);
    Serial.print(" C | Fan PWM: ");
    Serial.println(pwm);
  }
}

Hi,
Can I suggest you rebuilt the LM35 circuit on the other side of the centre of the board, not on the side of the fan 12V bus.
I can't see it directly, but is the transistor that switches the fan on the side of centre where the 12V fan wiring is?

Also some 0.1uF capacitors on the board, one on the 12V BUS and another on the 5V side.

Another across the Vcc and gnd pins AT the LM35 might help.

Tom.... :smiley: :+1: :coffee: :australia:

Well... I tried to switch them as you asked, lm35 circuit on the other side next to the arduino 5v rail, transistor on the side of the 12V rail. However, I dont have any 0.1microfarad capacitors at the moment, only two 1microfarad, and a dozen 100microfarad ones (ceramic and electrolytic).

This is how the circuit looks like rn :



I believe the issue may be from my power supply , apparently, 1A is bad and Im pretty sure this is an unregulated power supply

Its a bit late out where I live but tomorrow morning i'll try to find a suitable power supply and update you

Hi,
What voltage do you get when you measure the output?

Tom.... :smiley: :+1: :coffee: :australia:

The steps for succesfully using an analogue LM35 temp sensor:

  1. Give the LM35 it's own (not shared) ground to the Uno.
  2. Switch default analogreference to the internal reference of the Uno, for a supply independent temp readout and a 5x higher resolution (to 0.1C instead of 0.5C).

A digital temp sensor, like the DS18B20 is a much easier solution.
Leo..

Im sorry but what do you mean specifically by output? I measured the adapter directly and got 12.44V.

Also, when i replaced this new adapter, the fan now works and its spinning but its like not exactly reacting to the temperature anymore? like the readings are all still wild when i connect the power adapter even if i try to pinch the LM35 its still going crazy jumping from 3 to 30 degrees celsius, with the fan running at a normal rate.

I already gave it its own ground on the arduino pin (the one above pin 13), what am i supposed to measure here exactly? Ive already been asked to measure some output but I have no idea what it is...? I measured the capacitors voltage because its on the VIN rail and got 11.66V

Also arent i already doing the things youre talking about in this current code? :

#include <LiquidCrystal_I2C.h>

//  LCD Setup 
LiquidCrystal_I2C lcd(0x27, 16, 2);  //address is 0x27

// Pin Definitions 
const byte sampleBin = 8;
const int tempPin = A0;     // LM35 out
const int fanPin = 9;       //  PWM control
const int ledPin = 6;       // LED

// Calibration Constants 
const int8_t fudge = 90;      // Adjust this for calibration (±5~10 usually fine)
const int kAref = 1090;       // Analog reference voltage in mV (1.1V = 1100mV)
const int kSampleBin = sampleBin * 1000; 

//  Temperature&Controlvars 
int tempC, tempF;
int pwm;
bool fanOn = false;
uint32_t temp = 0, start = 0;
const int interval = 500;  // Refresh rate 

void setup() {
  analogReference(INTERNAL);
  analogRead(tempPin);  // Dummy read

  // Pre-fill temp with average of 8 samples
  for (int i = 0; i < sampleBin; i++)
    temp += analogRead(tempPin);

  lcd.init();
  lcd.backlight();

  pinMode(fanPin, OUTPUT);
  pinMode(ledPin, OUTPUT);
  Serial.begin(9600);
}

void loop() {
  if (millis() - start > interval) {
    start = millis();

    //  average of samples
    temp -= (temp / sampleBin);
    temp += analogRead(tempPin);

    // Convert to °C 
    tempC = temp * kAref / (kSampleBin + fudge);
    tempF = (tempC * 18 + 3200) / 10;

    // LCD Display 
    lcd.setCursor(0, 0);
    lcd.print("Temp: ");
    lcd.print(tempC / 10);
    lcd.print(".");
    lcd.print(tempC % 10);
    lcd.print((char)223);
    lcd.print("C    ");

    // Fan Control with Hysteresis 
    if (!fanOn && tempC >= 160) {       // 16.0°C
      fanOn = true;
    } else if (fanOn && tempC <= 140) { // 14.0°C
      fanOn = false;
    }

    pwm = fanOn ? map(tempC, 150, 450, 100, 255) : 0;
    pwm = constrain(pwm, 0, 255);
    analogWrite(fanPin, pwm);

    //  Overheat LED 
    digitalWrite(ledPin, tempC > 400 ? HIGH : LOW); // 40.0°C threshold

    // Serial Debug 
    Serial.print("ADC: ");
    Serial.print(analogRead(tempPin));
    Serial.print(" | Temp: ");
    Serial.print(tempC / 10);
    Serial.print(".");
    Serial.print(tempC % 10);
    Serial.print(" C | Fan PWM: ");
    Serial.println(pwm);
  }
}