Variable cannot keep its value

I’m trying to read two DS18B20s and get the difference between them. This is the Hacktronics one-wire sketch. I can display the temperatures OK on LCD and monitor. The variable for that is always tempC. Essentially the problem is that I cannot print tempC twice on the monitor. I get 0.00 and 0.00 for the difference.
Here is the code. The relevant section is the loop and the following void (I think), and I guess it is some silly detail like the type of variable. The sketch compiles OK and everything else works.

#include <OneWire.h>
#include <DallasTemperature.h>
#include <LiquidCrystal.h>

// initialize the library with the numbers of MY interface pins
LiquidCrystal lcd(8,9,14,5,6,7); // patchwire is to A0 (pin14) on this proto
int flag;
// Data wire is on pin 3 
#define ONE_WIRE_BUS 3
// Setup a oneWire instance to communicate with any OneWire devices
OneWire oneWire(ONE_WIRE_BUS);

// Pass our oneWire reference to Dallas Temperature. 
DallasTemperature sensors(&oneWire);

// Assign the addresses of your 1-Wire temp sensors.
DeviceAddress InThermo = {  
  0x28, 0x69, 0xC2, 0xB0, 0x03, 0x00, 0x00, 0X9F };
DeviceAddress OutThermo = { 
  0x28, 0x7A, 0x8B, 0xC0, 0x03, 0x00, 0x00, 0x2F };

//temperature variables
float InTemp;
float OutTemp; 
float diff;
float drain;
float tempC;

void setup(void)
{
  // start serial port
  Serial.begin(9600);

  // set up the LCD's number of columns and rows: 
  lcd.begin(16, 2);
  // Print a message to the LCD.
  lcd.print("temp in     out");    

  // Start up the library
  sensors.begin();
  // set the resolution to 10 bit (good enough?)
  sensors.setResolution(InThermo, 12);
  sensors.setResolution(OutThermo, 12);
}

void loop(void)
{ 
  delay(1000);
  flag = 0;
  //Get the sensor readings. There are two of them
  sensors.requestTemperatures();
  Serial.print("  Input temp : ");
// Go to the srtn, tempC=the sensor. Print it to monitor and LCD This is OK
  printTemperature(InThermo);
//InTemp = the fisrt tempC
  InTemp=tempC;
  Serial.print("   ");
//print tempC----------------I cannot do this!
  Serial.print (tempC);
  flag = 1;
  Serial.print("      Output temp   : ");
// Go to the srtn, tempC=the sensor. Print it to monitor and LCD. This is OK 
  printTemperature(OutThermo);
//OutTemp = the second tempC  
  OutTemp=tempC;
    Serial.print("   ");
//print tempC----------------I cannot do this!
  Serial.print (tempC);
  diff= OutTemp - InTemp;
  Serial.print("      diff  : ");
  Serial.print (diff); 
// No joy here. tempC = 0 on both attempts, hence the diff is 0.00
  Serial.println();
} 

void printTemperature(DeviceAddress deviceAddress)
{
  float tempC = sensors.getTempC(deviceAddress);
  if (tempC == -127.00) {
    Serial.print("Error getting temperature");
  } 
  else {
    Serial.print(tempC);
  }
  lcd.setCursor (1,1);
  if (flag==1)
    (
    lcd.setCursor (11,1)
      );
  lcd.print (tempC); 
}

Thank you

  // set the resolution to 10 bit (good enough?)
  sensors.setResolution(InThermo, 12);
  sensors.setResolution(OutThermo, 12);

Yeah, right.

You have a local variable named tempC and a global variable named tempC. You assign a value to one and try to use/print the other. And you are surprised by the behavior that you see. Why?

I suppose I should have run up a newbie flag. Thanks for the comment, but I'm afraid it is meaningless - which might go some way to explain why I asked the question in the first place.

Variables have scope. You created a global variable, tempC. This variable is available anywhere in the program, to set or get.

You created a local variable, tempC, in printTemperature(). This variable is available ONLY in that function. The value assigned to tempC in printTemperature() is NOT available to any other function. The memory space where the local tempC is stored is reclaimed as soon as printTemperature() ends, destroying the value that was stored there.

Function names should describe what they do. printTemperature() does a lot more than just [u]print[/u] the temperature.

If it really IS to do more than that, it needs a better name. If not, it needs to quit doing the extra stuff.

If you rename the function, consider that a function like getAndPrintTemperature() needs to return a value. This is much better than using a global variable to store the value.

I'd advise that you get rid of the global variables you have, where possible. Obviously, the class instances need to be global, but InTemp, OutTemp, diff, drain, and tempC do not.

Thanks. I was suss about tempC and removed the float from the srtn.

That line was inherited from the original Hacktronics sketch, which just diplayed two temps on the monitor.

I have now been able to print InTemp and OutTemp rather than just tempC, which is rather more to the point, but I still cannot subtract one from the other. Diff prints as 0.00. I am trying to copy the Differduino project www.nateful.com, which seems to get the difference in the same manner.

void loop(void)
{ 
  delay(1000);
  flag = 0;
  //Get the sensor readings. There are two of them
  sensors.requestTemperatures();
  Serial.print("  Input temp : ");
  printTemperature(InThermo);
  InTemp=tempC;
  Serial.print("   ");
  Serial.print (InTemp);
  flag = 1;
  Serial.print("      Output temp   : ");
  printTemperature(OutThermo); 
  OutTemp=tempC;
  Serial.print("   ");
  Serial.print (OutTemp);
  diff = OutTemp - InTemp;
  Serial.print("      diff  : ");
  Serial.print (diff); 
// No joy here. The diff is 0.00
  Serial.println();
} 

void printTemperature(DeviceAddress deviceAddress)
{
tempC = sensors.getTempC(deviceAddress);

Do you see the mistake in these lines?

InTemp=tempC;
...
OutTemp=tempC;
...
diff = OutTemp - InTemp;

:)

Edit: sorry, I got confused by your code! PaulS is right, rename your functions accordingly to what they do, or, you could pass "tempC" as a referenced parameter of the function "printTemperature" so it won't be as confusing as it is now...

I'm not sure what your problem is! Did you modify this line:

float tempC = sensors.getTempC(deviceAddress);

to this:

tempC = sensors.getTempC(deviceAddress);

?

I'm not sure what your problem is!

I'm not either, since you revised, but didn't repost your code.

Try getting both temperatures, saving the tempC value in InTemp and OutTemp as appropriate, then print both values.

It really would be better if you renamed the function and quit using globals the way you are.

tempC changes its value as there are two passes through the srtn printTemperature. OK I’ll change the name.

Yes I modified the line, removing “float”.

The difference problem was self-inflicted. I had a new line

 InTemp=tempC;

added right at the botton, which was not shown in the last post.

Removing this fixed the problem.

Thank you, now to try and get it on Cosm…

//  http://www.hacktronics.com/Tutorials/arduino-1-wire-tutorial.html
//  modernised, compacted, and metricated by Nick Pyner
//  code uses Arduino LCD stuff, for shield on Freetronics EtherTen.
//  Research your own pins!

#include <OneWire.h>
#include <DallasTemperature.h>
#include <LiquidCrystal.h>

// initialize the library with the numbers of MY interface pins
LiquidCrystal lcd(8,9,14,5,6,7); // patchwire is to A0 (pin14) on this proto
int flag;
// Data wire is on pin 3 
#define ONE_WIRE_BUS 3
// Setup a oneWire instance to communicate with any OneWire devices
OneWire oneWire(ONE_WIRE_BUS);

// Pass our oneWire reference to Dallas Temperature. 
DallasTemperature sensors(&oneWire);

// Assign the addresses of your 1-Wire temp sensors.
DeviceAddress InThermo = {  
  0x28, 0x69, 0xC2, 0xB0, 0x03, 0x00, 0x00, 0X9F };
DeviceAddress OutThermo = { 
  0x28, 0x7A, 0x8B, 0xC0, 0x03, 0x00, 0x00, 0x2F };

//temperature variables
float InTemp, OutTemp, diff, drain, tempC;

void setup(void)
{
  // start serial port
  Serial.begin(9600);

  // set up the LCD's number of columns and rows: 
  lcd.begin(16, 2);
  // Print a message to the LCD.
  lcd.print("temp in     out");    

  // Start up the library
  sensors.begin();

  sensors.setResolution(InThermo, 10);
  sensors.setResolution(OutThermo, 10);
}

void loop(void)
{ 
  delay(1000);
  flag = 0;
  //Get the sensor readings. There are two of them
  sensors.requestTemperatures();
  Serial.print("  Input temp : ");
  printTemperature(InThermo);
  InTemp=tempC;
  flag = 1;
  Serial.print("      Output temp   : ");
  printTemperature(OutThermo); 
  OutTemp=tempC;
  diff = OutTemp - InTemp;
  Serial.print("      diff  : ");
  Serial.print (diff); 
// No joy here. The diff is 0.00
  Serial.println();
} 

void printTemperature(DeviceAddress deviceAddress)
{
tempC = sensors.getTempC(deviceAddress);
  if (tempC == -127.00) {
    Serial.print("Error getting temperature");
  } 
  else {
    Serial.print(tempC);
  }
  lcd.setCursor (1,1);
  if (flag==1)
    (
    lcd.setCursor (11,1)
      );
  lcd.print (tempC); 
}