I am working on a controller which is supposed to control heater light and fans this system has Arduino Nano integrated in it and has a nokia display and menu system that lets user set the threshold values for the above mentioned devices. The home screen of this menu system is supposed to display temperature from two different LM35 connected on A0 and A1 respt. everything works fine but the temperature that my LM35 gives is not stable and gives some lot of garbage and meaningless values.
The code is attached below as it exceeds the word limit.
Vcc of both LM35 goes in 5V not from arduino but from onboard power supply. GND to the circuit GND made common and sensor pin to A0 of one sensor and to A1 of other sensor.
Did you run a small testcode that does nothing more than showing the temperature as
raw ADC-value and as caclulated centigrade degree?
The LM35 is an analog sensor. with a low voltage at 20°C = 0,2V
How long are the wires from Sensor to Arduino? Did you use a shielded wire to protect the signal against EMV/electromagnetic noise?
is there a special reason for you to use this analog sensor?
I prefed digital sensors like the DS18B20. As the signal is transferred digital from sensor to microcontroller which is much more robust against EMV / electromagnetic noise,
There are libraries available that make the use of this sensors quite easy.As they are onewire-sensors only one digital IO-pin is requiered to drive them. Additional +5V and GND
jimLee:
Are the LM35s and/or their wires submersed in water? Even encapsulated, that can make them go bananas.
-jim lee
No sir, LM 35 aren't submersed in water nor encapsulated. one of the LM35 connected to A1 is on board and the other one stays off board with wires of about 6 inches long without shielded wires
Did you run a small testcode that does nothing more than showing the temperature as
raw ADC-value and as caclulated centigrade degree?
The LM35 is an analog sensor. with a low voltage at 20°C = 0,2V
How long are the wires from Sensor to Arduino? Did you use a shielded wire to protect the signal against EMV/electromagnetic noise?
is there a special reason for you to use this analog sensor?
I prefed digital sensors like the DS18B20. As the signal is transferred digital from sensor to microcontroller which is much more robust against EMV / electromagnetic noise,
There are libraries available that make the use of this sensors quite easy.As they are onewire-sensors only one digital IO-pin is requiered to drive them. Additional +5V and GND
best regards Stefan
Hello Stefan,
The offboard sensor is connected to A0 it displays negative values and the onboard connected on A1 shows positive values. Both keeps on running like a stop watch
I have a test code but I didn't thought of running it.
The offboard sensor is connected with regular unshielded wires which are around 6 inches long.
#include <SPI.h>
#include <Adafruit_GFX.h>
#include <Adafruit_PCD8544.h>
// Declare LCD object for software SPI
// Adafruit_PCD8544(CLK,DIN,D/C,CE,RST);
Adafruit_PCD8544 display = Adafruit_PCD8544(8, 9, 10, 11, 12);
const int sensor1 = A1; // Assigning analog pin A1 to variable 'sensor'
int tempc1; //variable to store temperature in degree Celsius
int vout1; //temporary variable to hold sensor reading
const int sensor2 = A0; // Assigning analog pin A1 to variable 'sensor'
int tempc2; //variable to store temperature in degree Celsius
int vout2; //temporary variable to hold sensor reading
void setup()
{
Serial.begin(9600);
//Initialize Display
display.begin();
// you can change the contrast around to adapt the display for the best viewing!
display.setContrast(57);
// Clear the buffer.
display.clearDisplay();
// Display Text
display.setTextSize(1);
display.setTextColor(BLACK);
display.setCursor(10,0);
display.println("TEMPERATURE");
display.drawFastHLine(0,10,83,BLACK);
vout1 = analogRead(sensor1);
vout1 = (vout1*500)/1023;
tempc1 = vout1; // Storing value in Degree Celsius
display.setTextSize(1);
display.setTextColor(BLACK, WHITE);
display.setCursor(5, 15);
display.print("Temp1:");
display.setTextSize(2);
display.setCursor(5, 25);
display.print(tempc1);
vout2 = analogRead(sensor2);
vout2 = (vout2*500)/1023;
tempc2 = vout2; // Storing value in Degree Celsius
display.setTextSize(1);
display.setTextColor(BLACK, WHITE);
display.setCursor(47, 15);
display.print("Temp2:");
display.setTextSize(2);
display.setCursor(47, 25);
display.print(tempc2);
display.display();
delay(2000);
display.clearDisplay();
}
void loop()
{}
and it works completely fine. Shows stable values. but when I try to embed it in my main project code the values becomes gibberish
can you answer the question #1 about the power supply and the wiring of the relays - if any?
if you have a drop in the voltage - not enough to crash the arduino, but enough to impact AREF, analogRead() will go nuts as its reference won't be 5V anymore.
J-M-L:
can you answer the question #1 about the power supply and the wiring of the relays - if any?
if you have a drop in the voltage - not enough to crash the arduino, but enough to impact AREF, analogRead() will go nuts as its reference won't be 5V anymore.
I answered it. Again, my power supply is 12V 1amp. No relays, BJT BC547 and power BJT BD139 both are NPN general purpose transistors
Vcc of both LM35 goes in 5V not from arduino but from onboard power supply. GND to the circuit GND made common and sensor pin to A0 of one sensor and to A1 of other sensor.
#ifndef LM35_H
#define LM35_H
/*
This is a little class to run the TI-LM35 temp
sensing chip from an analog pin on an Arduino.
Constructor takes a pin number.
Foe example : LM35 mySensor(A2);
When you want a reading just call either tempC()
for centigrade or tempF() for Farenheight.
This assumes you have the sensor hooked directly to
5V & Ground with the data out pin conected to the
analog input on your Arduino. No fancy circuits,
just the 3 wires.
Enjoy!
-jim lee
*/
class LM35 {
public:
LM35(int inPin);
~LM35(void);
float centToDegF(float cent);
float tempC(void);
float tempF(void);
private:
int pin;
};
#endif
The .cpp file
#include "LM35.h"
#include <mapper.h>
// We all need the mappers and they are always the same. So just
// make up the two and share em.
mapper intToVolts(0,1023,0,5.0); // From Arduinoland..
mapper voltsToTemp(0,1.5,0,150); // From the LM35 datasheet.
// Constructor, saves off our input pin.
LM35::LM35(int inPin) { pin = inPin; }
// Destructor, nothing to see here..
LM35::~LM35(void) { }
// How to convert centagratde to Farenheight. From the web.
float LM35::centToDegF(float cent) { return (cent * 1.8) + 32; }
// This is the only call that actually talks to the sensor.
// Returns the temp. in centagrade.
float LM35::tempC(void) {
unsigned int count = analogRead(pin);
double volts = intToVolts.Map(count);
return voltsToTemp.Map(volts);
}
// To get Farenheight we first grab centagrade then convert
// the value. If you want, you can do this yourself using
// the centToDegF(tempC); function.
float LM35::tempF(void) { return centToDegF(tempC()); }
You'll need the float mapper class found in this library here : LC_baseTools
Using default Aref with an LM35 is asking for trouble, especially with a Nano on USB power.
Not only will the result be varying with supply variations (other devices that draw varying currents),
but also the resolution will suffer (0.5C steps at best).
Analogue sensors, like the LM35/TMP36, are a pain to use. Go digital (I2C) if you can.
That said, there are some rules.
Decouple the supply of the LM35, close to the LM35.
Don't share ground with anything else (breadboard). LM35 ground must go directly to a Nano ground pin.
(power can come from the 5volt pin, no need to use stable/external power)
Use shielded wiring for longer runs.
Put this in setup: analogReference(INTERNAL); // switch to 1.1volt Aref
Any LM35 code without that line can't be trusted (written by a somebody who doesn't know how).
Only then can you expect a ~5-100C display with 0.1C resolution.
Leo..
The point I mentioned was, the test code posted below, works completely fine when it is in void setup, if the same code is moved to void loop, the same problem occurs with this one too
#include <SPI.h>
#include <Adafruit_GFX.h>
#include <Adafruit_PCD8544.h>
// Declare LCD object for software SPI
// Adafruit_PCD8544(CLK,DIN,D/C,CE,RST);
Adafruit_PCD8544 display = Adafruit_PCD8544(8, 9, 10, 11, 12);
const int sensor1 = A1; // Assigning analog pin A1 to variable 'sensor'
int tempc1; //variable to store temperature in degree Celsius
int vout1; //temporary variable to hold sensor reading
const int sensor2 = A0; // Assigning analog pin A1 to variable 'sensor'
int tempc2; //variable to store temperature in degree Celsius
int vout2; //temporary variable to hold sensor reading
void setup()
{
Serial.begin(9600);
//Initialize Display
display.begin();
// you can change the contrast around to adapt the display for the best viewing!
display.setContrast(57);
// Clear the buffer.
display.clearDisplay();
// Display Text
display.setTextSize(1);
display.setTextColor(BLACK);
display.setCursor(10,0);
display.println("TEMPERATURE");
display.drawFastHLine(0,10,83,BLACK);
vout1 = analogRead(sensor1);
vout1 = (vout1*500)/1023;
tempc1 = vout1; // Storing value in Degree Celsius
display.setTextSize(1);
display.setTextColor(BLACK, WHITE);
display.setCursor(5, 15);
display.print("Temp1:");
display.setTextSize(2);
display.setCursor(5, 25);
display.print(tempc1);
vout2 = analogRead(sensor2);
vout2 = (vout2*500)/1023;
tempc2 = vout2; // Storing value in Degree Celsius
display.setTextSize(1);
display.setTextColor(BLACK, WHITE);
display.setCursor(47, 15);
display.print("Temp2:");
display.setTextSize(2);
display.setCursor(47, 25);
display.print(tempc2);
display.display();
delay(2000);
display.clearDisplay();
}
void loop()
{}
if I move the code in loop and comment out output from any one sensor then too it works completely fine. the code works completely fine if either:
when the code is in void setup
or
If the code is in void loop any one of the sensor should be commented off.
Is this has to be a programming problem? or a hardware problem?
int vout1; //temporary variable to hold sensor reading
int vout2; //temporary variable to hold sensor reading
pinMode(sensor1, INPUT);
pinMode(sensor2, INPUT);
vout1 = analogRead(sensor1);
vout1 = (vout1*500)/1023;
vout2 = analogRead(sensor2);
vout2 = (vout2*500)/1023;
Add this to setup().
analogReference(INTERNAL);
Change this
tempc1 = vout1; // Storing value in Degree Celsius
to
tempc1 = analogRead(sensor1) * 0.1039; // change last digit(s) to calibrate, if needed
and
tempc2 = vout2; // Storing value in Degree Celsius
to
tempc2 = analogRead(sensor2) * 0.1039; // change last digit(s) to calibrate, if needed