Hello,
I'm really not very good at the electronics side of things and could use some help understanding where my problem lies
I have built a remote temperature sensing circuit using an LM335. It seemed to work fine on the breadboard but when I have taken it apart on soldered it onto 10m of speaker wire it seems to behave oddly. I say it worked fine on the breadboard but my problem only seems to emerge when I try to take temperature readings above 45 degrees.
This is the speaker wire I have used
http://www.ebay.co.uk/itm/290585436641
I think this is 21Awg
According to this site
http://www.cirris.com/testing/resistance/wire.html
10m (32.808399 feet) of 21 awg wire should have a wire resistance of 0.42 ohms
This is the circuit I have built

It has the 2.2kohn resistor at the Arduino end so basically it goes
5v --> resistor --> One short wire to analog pin
L--> 10m wire --> to the middle pin of the LM335.
Then the ground directly out --> to 10m of wire --> right pin of the LM335
I say it worked fine on the breadboard but in truth I didn't fully test it as I couldn't find a way to get the test temperatures up much above 38 easily without squashing the sensor so this is the first time I have really tested it.
The problem is when I place a hot teapot on top of the sensor, the temperature climbs to 45 degrees then it shows -40. I'm really not sure if I have an electrical problem or if I have done something stupid in my code. My code is at the bottom of this post
So, questions for the clever forum members please. I am happy to supply further readings
1.) I am assuming I have wired it correctly as I get a sensible sounding reading. As this is a diode if I wired it back to front I don't think I would get anything
2.) Similarly I am sure I have only used the two rightmost pins (I have clipped off the adjustment pin on the left of the image when the flat part is facing me)
3.) Is it my electronics or was it something in my code all along which I didnt spot up until now
void GetAverageTemps() // Function to get average temperatures on Pool & Panel in oC. Takes 1 second
{
PanelTemp=0; // Reset the Panel Temp variable
PoolTemp=0; // Reset the Pool Temp variable
int PanelADCAvg=0; // variable to hold Panel ADC Averages
int PoolADCAvg=0; // variable to hold Pool ADC Averages
for (int i=1; i <=50; i++) // Loop to get 50 values
{
delay(10); // Delay 10ms to allow ADC to recover between reads
PanelADCAvg=PanelADCAvg + analogRead(0); // Read in 50 Panel ADC Readings
}
for (int i=1; i <=50; i++) // Loop to get 50 values
{
delay(10); // Delay 10ms to allow ADC to recover between reads
PoolADCAvg=PoolADCAvg + analogRead(1); // Read in 50 Pool ADC Readings
}
PanelADCAvg = (PanelADCAvg/50); // Work out the average Panel ADC reading
PoolADCAvg = (PoolADCAvg/50);
PanelTemp=(((PanelADCAvg * 4.965 * 100.0)/1024)-273.15)+config.PanelTempAdj; // Convert the PanelADCAvg to a temperature in oC and add any adjustment
PoolTemp=(((PoolADCAvg * 4.965 * 100.0)/1024)-273.15)+config.PoolTempAdj; // Convert the PoollADCAvg to a temperature in oC and add any adjustment
PanelTemp=(PanelTemp*4); // Round the output to the nearest .25
PanelTemp=round(PanelTemp);
PanelTemp=PanelTemp/4;
PoolTemp=(PoolTemp*4); // Round the output to the nearest .25
PoolTemp=round(PoolTemp);
PoolTemp=PoolTemp/4;
PoolTemp=(constrain(PoolTemp,-40.00,100.00)); // Limit the range of values to the LM335Z range
PanelTemp=(constrain(PanelTemp,-40.00,100.00)); // Limit the range of values to the LM335Z range
}
NotesA couple of notes on the above. The reason I use 4.965 in the calculation is because I measure the arduino putting out between 4.96 and 4.97v on the 5v pin.
Ignore config.PoolTempAdj &config.PanelTempAdj. These are values used to trim the sensors (due to natural differences in manufacturing) For this code you can assume they are set to zero
ADDENDUMI suspect I see my problem but I can't test it right now as I am at work so I would still appreciate some input. I think the problem may be in code.
A typical output for the LM335 at 25 degrees should be 2.98v. From memory I think this equates to an ADV value of 611 so I will use this for the example.
I take 50 readings and store them in an int called PanelADCAvg. 50 * 611 = 30550
I then divide this by 50 to get to my average. In this example its 611
I then run this calculation:
PanelTemp=(((PanelADCAvg * 4.965 * 100.0)/1024)-273.15)+config.PanelTempAdj
Which is ((611 * 4.965 *100.0)/1024)-273.15) =23.101 degrees c
The above is slightly lower than I stated. Perhaps I was wrong on the 611 = 25v when using 4.965 but no matter
An ADC read of 656 is around 45 degrees (Where the problem occurs)
So I take my 50 readings and store them in an int called PanelADCAvg. 50 * 656 = 32800
Obviously an int variable will roll over to negative when it gets above 32767
Whilst I am expecting PanelADCAvg to be 32800/50=656 in reality its actually -33/50=-0.66
Because an int can't hold a floating point -0.6 becomes -1
So whereas I think my calculation will be:
((656 * 4.965 *100.0)/1024)-273.15) =44.92 degrees c
it is actually
((-1 * 4.965 *100.0)/1024)-273.15) =-273.635 degrees c
I then do a bit of rounding to take this to -273.50 degrees c
And then finally I constrain it to the range of the LM335 (-40 to +100)
So when I go above 45 degrees I get a figure of -40 all because I used int instead of unsigned int
Do you agree? Or is there something else I am missing.