Temperature sensor gives weird readings when servo motor is attached, why?

Hi everybody,

I am new to electronics and am just starting with the Arduino Starter Kit. I did the first several projects and decided to combine some of them, namely “Love-o-Meter” and “Mood Cue”. I want to set the base temperature to 27 degrees C and for every 2 degrees above that, I want the servo to move 45 degrees. The code is posted below (it’s basically a combination of the example code for the two projects).

When I uploaded the sketch to Arduino, the motor arm started moving immediately left and right. I opened the Serial Monitor and saw temperature readings varying by about 30 degrees C (24, 57, 31, 43 etc.), one after the other. I disconnected the motor, leaving only the temperature sensor and serial monitor working, and everything started working properly (constant sensor readings of about 144, volts at about 0.70 and temperature at about 20 degrees). I connected the servo motor again and the weird values started appearing again, causing the motor arm to move rapidly left and right.

I searched the forum and find several topics about similar problems and tried the proposed solutions there; I changed the analog input pin to A3 (it was at A0) – no change. Then I changed the delay at the end from 15 to 1000ms and that partially solved the problem – now I get readings at 1s intervals, which are fairly constant, but still are about 4 degrees C higher than the actual room temperature, measured when the servo is disconnected. The shorter delay I put, the weirder the readings get. It crossed my mind that the problem may be with some excess electricity in the circuit, so I put an extra capacitor alongside the temperature sensor – no change.

Can someone explain what is going on here?

Thank you in advance.

The code:

#include <Servo.h>
Servo myServo;
int angle;
const int sensorPin = A3;
const float baselineTemp = 27.0;

void setup() {
  myServo.attach(9);
  Serial.begin(9600);
}

void loop() {
  int sensorVal = analogRead(sensorPin);
  Serial.print("Sensor Value: ");
  Serial.print(sensorVal);
  float voltage = (sensorVal/1024.0)*5.0;
  Serial.print(", Volts: ");
  Serial.print(voltage);
  Serial.print(", degrees C: ");
  float temperature = (voltage - .5) * 100;
  Serial.println(temperature);

  if (temperature < baselineTemp) {
    angle = 0;
  }
  else if (temperature >= baselineTemp && temperature < baselineTemp+2) {
    angle = 45;
  }
  else if (temperature >= baselineTemp+2 && temperature < baselineTemp+4) {
    angle = 90;
  }
  else if (temperature > baselineTemp+4) {
    angle = 135;
  }
  myServo.write(angle);
  delay(1000);
  }

Hard to say what the issue is right now. Maybe possible to trace the issue if you show exactly how your hardware is connected together. This means include motor, arduino, and all devices used ----- showing complete wiring between devices and components.

Are you powering the servo from the Arduino 5V? If so, the servo draws enough current to change the supply voltage. The default reference for analogRead is the supply. So, if the analog reference (supply voltage) is bouncing around, how can you get accurate analog reads? You need to power the servo with its own supply.

groundFungus:
So, if the analog reference (supply voltage) is bouncing around, how can you get accurate analog reads?

Depends on the sensor used - the beauty of using Vcc as reference is that when sensing temperature with a thermistor it doesn't matter how it bounces around.
OP doesn't seem to be using a thermistor, but s/he does use the direct analog reading for temperature. So without knowing what exact sensor they use, it's hard to say whether this is the cause of the measurement error.

Anyway I agree that it's most likely a power issue. The servo should have its separate supply - may come from the same wall wart, but wired separately.

Yes, the servo is connected to 5V. The temperature sensor came with the Arduino Starter Kit - TMP36. Can I use a 9V battery for external power supply? I just finished project no. 6, I haven’t yet reached the projects with external power supply. Do I connect the load directly to the breadboard’s “+” and “-”, like when I’m using 5V? Do I need to use a diode? BTW, I tried using the different Arduino power supplies for the servo and temperature sensor (the sensor to 3.3V and servo to 5V), but got the same problems. Also, with this setup and no load, the sensor reads 23 degrees C with 3.3V, and 21 degrees C with 5V.
About drawing a diagram - what program do I use for that?

Can I use a 9V battery for external power supply?

Yes, but not for long. The 9V rectangular battery is a great deal - for the manufacturer and retailer, but NOT for the consumer. They have the least current/$ of any battery made.

I connected the servo to a 9V battery and it works fine now in the sense that I get constant temperature readings. The only issue remaining is that the sensor reads a room temperature that's about 3 degrees C higher when the servo is connected than when it's not. Battery/servo GND is connected to Arduino GND. Is this a sensor problem?

Fair chance it's a power supply problem. Servos can easily draw more power than a standard 9V battery can supply.

For the servo, use a 5 to 6V power supply capable of supplying at least 1 Ampere. A 4xAA battery pack works well, and connect all the grounds together.

9V block batteries are for smoke alarms and are not useful for anything related to Arduino.

What if you're building an Arduino based smoke detector? :wink:

Freerider:
I connected the servo to a 9V battery and it works fine now in the sense that I get constant temperature readings. The only issue remaining is that the sensor reads a room temperature that's about 3 degrees C higher when the servo is connected than when it's not. Battery/servo GND is connected to Arduino GND. Is this a sensor problem?

Good chance you may cook the servo with 9V, most are made for a maximum of around 6V.

Freerider:
About drawing a diagram - what program do I use for that?

No program required. Just use a piece of paper, a pencil, your brain, google…how to draw a schematic diagram, an eraser :), and a camera. Then post a pic of your schematic.

Something to keep in your pocket for the future (or now)… @Wawa’s advice, explanation, and code in this post: Getting more precision out of TMP36 temperature sensor His code is more compact in this post (no LCD code), but explanation/discussion is shorter.

Freerider:
About drawing a diagram - what program do I use for that?

For simple circuits pen and paper will do great, but especially if you plan to do this more and want more complex circuits do take the time to learn a proper CAD program, such as KiCAD or EagleCAD. Both also allow you to help design PCBs, using KiCAD myself, a great help in laying out protoboards as well.

One word, noise.

Here is a diagram of the circuit as it was last time I tried it.

Next time, there will be 4xAA battery pack instead of the 9V one.
Indeed the max listed voltage for the servo is 6V, good thing that it wasn't burned by the 9V.
@DaveEvans Thanks for the info. I didn't know yet what AREF was for, so I read the tutorial. I'll read more in-depth and try the code when I have more time on my hands and post the result.

I got a 4xAA-battery pack to replace the 9V battery, but the voltage was 6,44 V, so I used only 3 batteries (in series), which are 4,83 V, ~4,50 A. I also connected the sensor to 3,3 V this time, as it is in Wawa’s code.
I also used internal Aref and Wawa’s example code. However, I get normal temperature readings only when the battery for the servo is connected (~23°C room temperature), and wrong varying readings when it’s not (~8-20°C).
What’s even worse, when I completely disconnect the servo circuit from the Arduino, I get temp readings of -36°C.
So, in short, my guess is the sensor is cooked from when I used a 9V battery for the servo.

The code:

#include <Servo.h>
Servo myServo;
int angle;
unsigned int total;
const float baselineTemp = 27.0;
float temperature;

void setup() {
  analogReference(INTERNAL);
  myServo.attach(9);
  Serial.begin(9600);
}

void loop() {
  total = 0; // reset total
  for (int x = 0; x < 64; x++) { // 64(max) analogue readings for averaging
    total += analogRead(A0); // add each value
  }
  temperature = total * 0.001632 - 50.0; // Calibrate temp by changing the last digit(s) of 0.001632
  
  Serial.print("The temperature is: ");
  Serial.print(temperature);
  Serial.println(" degrees Celsius.");
  
  if (temperature < baselineTemp) {
    angle = 0;
  }
  else if (temperature >= baselineTemp && temperature < baselineTemp+2) {
    angle = 45;
  }
  else if (temperature >= baselineTemp+2 && temperature < baselineTemp+4) {
    angle = 90;
  }
  else if (temperature > baselineTemp+4) {
    angle = 135;
  }
  myServo.write(angle);
  delay(1000);
}

Update: The TMP36 sensor is OK, I replaced it with a brand new one and had the same results.

The circuit works now. To cut a long story short:

I had on the board only the simple circuit with only the sensor attached.
After it turned out that the sensor works OK, I thought maybe there was something wrong with the analog input on A0. I hooked up a pot in place of the sensor and kept the same code in memory. On serial monitor it returned correct values from 0 to1023, depending on how much I turned the pot.

I measured the voltage on the central pin with a multimeter (left and right pin to 3xAA battery pack) and it was 0,68V, which translates to 18°C, which was about right at the time (I like to keep it a little cool in the room).

I tried several example programs (the one I posted in the beginning, leaving only the TMP36 code, this, this) from the Net. All of them returned negative temperatures. I read many discussions and explanations. Looks like a lot of people have issues with this sensor. Here it says they solved the problem by placing a 1kΩ resistor between middle pin and GND and suggest using a 47kΩ one. Since I don’t have 47kΩ, I tried with 1kΩ and 10kΩ - negative temps again.

Then I read this and this. I followed all the recommendations in the second link (except connecting to 3.3V, since they are using Spark Core, not Arduino). This is what solved the problem for me.

The steps that helped the most: placing the 0.01uF cap between middle pin and GND, placing the 100nF cap between anode and GND (which I did in the beginning, but with a 100uF one) and (remarkably) using the shortest possible wire to connect the sensor to A0.

Finally, I have constant temperature readings that don’t change when I remove the battery. The sensor reads 22 - 23°C and the room temperature, measured with a plain old mercury thermometer, is 21.50°C. Good enough.

I am a beginner with electronics and only wanted to measure the temperature in the room, which seemed a simple enough task. Instead, I feel like I’ve been thrown at the deep end...:). Which is not so bad after all, hehehe.

Which is not so bad after all,

Good attitude! There is a lifetime of learning ahead, if you wish.