Arduino UNO with 18B20 temp sensor reading negative temperatures.

I wrote a program to monitor my freezer temperatures using a 18B20 sensor, a UNO and a 4x20 LCD.
It works ok except negative temperatures don’t come out correctly.

I read several posts about how to correct this problem but have not figured out how to change my code to fix the problem.

  • 8/2/2019 Dallas OneWire 18B20 temperature sensor freezer alarm.
  • Works OK.
  • ****** USE TWI ******
    */

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

// Data wire is plugged into port 2 on the Arduino
#define ONE_WIRE_BUS 2

// Setup a oneWire instance to communicate with any OneWire devices (not just Maxim/Dallas temperature ICs)
OneWire oneWire(ONE_WIRE_BUS);

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

// arrays to hold device address
DeviceAddress insideThermometer;

//#include “LiquidCrystal_I2C.h”
#include “LiquidTWI.h”
LiquidTWI lcd(0);

//#include <LiquidCrystal_I2C.h>
//LiquidCrystal_I2C lcd(0x27,20, 4); // set the LCD address to 0x27 for a 16 chars and 2 line display

int ledR = 10; // red, door open led
int ledG = 11; // green, door closed led
int beep = 7; // door open piezo

void setup(void)
{
Serial.begin(9600);
Serial.println(“sketch_aug05a_2019_18B20_1_Freezer_V15”);

// lcd.init();
// lcd.backlight();
lcd.begin(20, 4);
// start serial port

pinMode(ledR, OUTPUT);
pinMode(ledG, OUTPUT);

// locate devices on the bus
Serial.print(“Locating devices…”);
sensors.begin();
Serial.print(“Found “);
Serial.print(sensors.getDeviceCount(), DEC);
Serial.println(” devices.”);

// report parasite power requirements
Serial.print("Parasite power is: ");
if (sensors.isParasitePowerMode()) Serial.println(“ON”);
else Serial.println(“OFF”);

// assign address manually. the addresses below will beed to be changed
// to valid device addresses on your bus. device address can be retrieved
// by using either oneWire.search(deviceAddress) or individually via
// sensors.getAddress(deviceAddress, index)
//insideThermometer = { 0x28, 0x1D, 0x39, 0x31, 0x2, 0x0, 0x0, 0xF0 };

// Method 1:
// search for devices on the bus and assign based on an index. ideally,
// you would do this to initially discover addresses on the bus and then
// use those addresses and manually assign them (see above) once you know
// the devices on your bus (and assuming they don’t change).
if (!sensors.getAddress(insideThermometer, 0)) Serial.println(“Unable to find address for Device 0”);

// show the addresses we found on the bus
Serial.print("Device 0 Address: ");
printAddress(insideThermometer);
Serial.println();

// set the resolution to 9 bit (Each Dallas/Maxim device is capable of several different resolutions)
sensors.setResolution(insideThermometer, 9);

Serial.print("Device 0 Resolution: ");
Serial.print(sensors.getResolution(insideThermometer), DEC);
Serial.println();
}

// function to print the temperature for a device
void printTemperature(DeviceAddress deviceAddress)
{
float tempC = sensors.getTempC(deviceAddress);
Serial.print(" Temp C: “);
Serial.print(tempC);
Serial.print(” Temp F: “);
Serial.println(DallasTemperature::toFahrenheit(tempC)); // Converts tempC to Fahrenheit
Serial.println(” ");
delay(1000);

int tempF = ((1.8*tempC)+32.0);

if (tempF > 25.0)
{ lcd.clear();
lcd.setCursor(0, 1);
lcd.print(“TEMP IS TOO HIGH”);
lcd.setCursor(2,0);
lcd.print("Temp Is ");
lcd.setCursor(11,0);
lcd.print(tempF);

digitalWrite( ledG, LOW);
digitalWrite( ledR, HIGH);
noTone(7);
tone(7,5000,750);
delay(0);
delay(750);
digitalWrite( ledR, LOW);

}

else {

noTone(7);

lcd.clear();
lcd.setCursor(3,0);
lcd.print("Temp Is ");
lcd.setCursor(12,0);
lcd.print(tempF);
Serial.println(tempF);
lcd.setCursor(0,1);
lcd.print(“Set Point = 14”);
digitalWrite( ledR, LOW);
digitalWrite( ledG, HIGH);
delay(1000);
digitalWrite( ledG, LOW);

//delay(1000);
}

}

void loop(void)
{

// call sensors.requestTemperatures() to issue a global temperature
// request to all devices on the bus
Serial.print(" Requesting 18B20 temperature…");
sensors.requestTemperatures(); // Send the command to get temperatures
Serial.println(" DONE");

// It responds almost immediately. Let’s print out the data
printTemperature(insideThermometer); // Use a simple function to print out the data

}

// function to print a device address
void printAddress(DeviceAddress deviceAddress)
{
for (uint8_t i = 0; i < 8; i++)
{
if (deviceAddress < 16) Serial.print(“0”);
_ Serial.print(deviceAddress*, HEX);_
_
}_
_
}*_

63 posts and you still can't put your code inside code tags? Help yourself by making it easier for people to help you.

Also "negative temperatures don't come out correctly" doesn't tell us what is wrong. Do they come out in Roman numerals? upside down? Missing a minus sign? Making people guess is not good for debugging.

First guess is you are using the wrong number ‘type’

int tempF = ((1.8*tempC)+32.0);

Humm ‘int’ will not show negative numbers.

Use Google :wink:

C++ Arduino number type

To BLH64.

I doubt that I have posted more than a half dozen questions on here over the years.
I used the code icon and thought everything was good to go. But then it didn’t look right but there seemed to be no way to reverse what I had so I let it be knowing that I would get burned for it.

I apologize for my transgression.

To larryd.

What I get now are various odd numbers not related to the true temperature reading when the freezer is at zero or below. Above zero temp in the freezer gives me the proper reading on my LCD.

Fixes on the internet talk about reading msb and lsb from the 18B20 as that sets the reading as negative or positive. But as of yet I haven’t figured out how to do that.

And that is why I am on here now.

I will try your suggestion of changing my number type from int to char.

Thanks.

I will try your suggestion of changing my number type from int to char.

int tempF = ((1.8*tempC)+32.0);

Try:

unsigned int tempF = ((1.8*tempC)+32.0);

Or:

float tempF = ((1.8*tempC)+32.0);