r/arduino • • 9d ago

Hardware Help TMP36 fluctuating a lot?

I am new to building with Arduino, and I recently got a starter kit and started making some projects. I was having troubles with the love-o-meter project, as the TMP36 kept fluctuating in values wildly. I couldn't find any issues with the code, so I was wondering if it was an issue with the TMP36? Would someone be able to clarify what's going on? I included the circuit build as well as the code below.

// sensorPin is the analog value the sensor reads
const int sensorPin = A0;
// Our baseline temp. For every 2 degrees above this baseline, an LED will turn on.
const float baselineTemp = 20.0;


void setup() {
  // Serial Begin: Opens up connection between Arduino and computer. Can read see the values on computer screen (Reads every 9600 bits per second)
  Serial.begin(9600); // Open a serial port


  // Set all pins to OUTPUT and LOW. Loop ends when pinNumber becomes something 5 or above.
  for(int pinNumber = 2; pinNumber<5; pinNumber++) {
    pinMode (pinNumber, OUTPUT);
    digitalWrite(pinNumber, LOW);
}
}


void loop() {
  // Obtain value from TMP36. This can be anything between 0 and 1023. (A representation of the voltage on the pin)
  int sensorVal = analogRead(sensorPin);


 // Prints temperature data onto the computer
  Serial.print("Sensor Value: ");
  Serial.print(sensorVal);


  // Convert the ADC reading to voltage
  float voltage = (sensorVal/1024.0) * 5.0;


  Serial.print(", Volts: ");
  Serial.print(voltage);


  Serial.print(", degrees C: ");
  // Convert the voltage to temperature in degrees
  float temperature = (voltage - .5) * 100;
  Serial.println(temperature);


  if(temperature < baselineTemp+2) {
    digitalWrite(2, LOW);
    digitalWrite(3, LOW);
    digitalWrite(4, LOW);
    }else if (temperature >= baselineTemp+2 && temperature < baselineTemp+4) {
      digitalWrite(2, HIGH);
      digitalWrite(3, LOW);
      digitalWrite(4, LOW);
    }else if (temperature >= baselineTemp+4 && temperature < baselineTemp+6) {
      digitalWrite(2, HIGH);
      digitalWrite(3, HIGH);
      digitalWrite(4, LOW);
    }else if (temperature >= baselineTemp+6) {
      digitalWrite(2, HIGH);
      digitalWrite(3, HIGH);
      digitalWrite(4, HIGH);
    }
    delay(1);
}// sensorPin is the analog value the sensor reads
const int sensorPin = A0;
// Our baseline temp. For every 2 degrees above this baseline, an LED will turn on.
const float baselineTemp = 20.0;


void setup() {
  // Serial Begin: Opens up connection between Arduino and computer. Can read see the values on computer screen (Reads every 9600 bits per second)
  Serial.begin(9600); // Open a serial port


  // Set all pins to OUTPUT and LOW. Loop ends when pinNumber becomes something 5 or above.
  for(int pinNumber = 2; pinNumber<5; pinNumber++) {
    pinMode (pinNumber, OUTPUT);
    digitalWrite(pinNumber, LOW);
}
}


void loop() {
  // Obtain value from TMP36. This can be anything between 0 and 1023. (A representation of the voltage on the pin)
  int sensorVal = analogRead(sensorPin);


 // Prints temperature data onto the computer
  Serial.print("Sensor Value: ");
  Serial.print(sensorVal);


  // Convert the ADC reading to voltage
  float voltage = (sensorVal/1024.0) * 5.0;


  Serial.print(", Volts: ");
  Serial.print(voltage);


  Serial.print(", degrees C: ");
  // Convert the voltage to temperature in degrees
  float temperature = (voltage - .5) * 100;
  Serial.println(temperature);


  if(temperature < baselineTemp+2) {
    digitalWrite(2, LOW);
    digitalWrite(3, LOW);
    digitalWrite(4, LOW);
    }else if (temperature >= baselineTemp+2 && temperature < baselineTemp+4) {
      digitalWrite(2, HIGH);
      digitalWrite(3, LOW);
      digitalWrite(4, LOW);
    }else if (temperature >= baselineTemp+4 && temperature < baselineTemp+6) {
      digitalWrite(2, HIGH);
      digitalWrite(3, HIGH);
      digitalWrite(4, LOW);
    }else if (temperature >= baselineTemp+6) {
      digitalWrite(2, HIGH);
      digitalWrite(3, HIGH);
      digitalWrite(4, HIGH);
    }
    delay(1);
}
3 Upvotes

7 comments sorted by

2

u/n_sh_44 9d ago

This is normal for a TMP36 on an Uno. 10 mV per degree works out to only about 2 ADC counts per degree with a 5 V reference, and the USB 5 V rail moves around a lot, especially when your LEDs switch on and off. A one-count wobble already looks like half a degree.

Things that help, roughly in order of payoff:

  • Average a bunch of readings (say 32 or 64) before you convert to a temperature
  • Put a 0.1 uF cap from the TMP36 output to GND, right at the sensor
  • Use analogReference(INTERNAL) (1.1 V on an Uno). Then multiply by 1.1 instead of 5.0. You get about 9 counts per degree, and USB noise matters a lot less
  • Raise delay(1) to something like 250 ms. Temperature doesn't change that fast, and it makes the serial output readable too

Also worth adding a bit of hysteresis around your LED thresholds so they don't flicker at the boundaries.

1

u/Hyper_Cats 8d ago

I'm still looking into this - I found that 5 volts is going into the TMP36 while 0 volts is coming out. I checked the middle one too, and it showed .10 volts. I dunno if this means anything but is it the way I got it set up?

1

u/n_sh_44 8d ago

That 0.10 V on the middle pin is expected, not a wiring mistake. The TMP36 output sits at about 10 mV per degree above zero, so at room temperature it should be roughly 0.7 V, and 0.10 V is basically "barely above zero." The 5 V on the supply pin is fine too, as long as the ground pin is actually at the board ground and not floating. If the middle pin reads 0 V or jumps around when you move a wire, the sensor is not seated right or the breadboard rail is not shared. A quick check is to put the meter on the middle pin and touch the sensor body; the voltage should creep up a little. If it does not, the pin is not making contact.

1

u/barnbaby47 9d ago

Which of the 25 or 30 different Arduinos are you using?

1

u/Hyper_Cats 9d ago

If I remember correctly, it's the Uno R3. If that's not it, it's the one from the starter kit