DS18B20 - temperature sensor code Help Request

Greetings,

I recently purchased a few Temperature sensors - DS18B20. I am using an uno r3
I found some code and modified it to display an alarm and to display on an LCD.

  1. I have the code sensing 2 DS18B20 temp sensors (the temp readings are good) and it is displaying the temperature on an lcd 16/2.
  2. I have managed to figure out how to display on the LCD when an over-temp occurs and to turn on a led but it is not working the way I want it to.

PROBLEM:

  1. The code below results in the word “ALARM” on my lcd when over temp occurs but my over temp LED blinks, instead of being on steady during the alarm. (it is wired to a relay which turns on a fan, so it must not blink during the alarm period, as the fan must be on continuous to cool down the over-temp device and preferably stay on for at least a minute after temp returns to normal)

  2. I have 2 temp sensors , i would like to be able to Display which Sensor has the alarm and display it on the LCD (during the alarm period.)

Help figuring out the code would be appreciated
Thanks
joe

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

LiquidCrystal_I2C lcd(0x27,16,2); // set the LCD address to 0x27  16/2
// LiquidCrystal_I2C lcd(0x27,20,4); // set the LCD address to 0x27  20/4

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

// 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);

DeviceAddress insideThermometer = { 
  0x28, 0x25, 0x33, 0xDC, 0x03, 0x00, 0x00, 0x7E };
DeviceAddress outsideThermometer = { 
  0x28, 0x67, 0x3D, 0xDC, 0x03, 0x00, 0x00, 0xC7 };


void setup(void)
{
  pinMode(7, OUTPUT); //pin selected to control OVER TEMP LED / fan

  // Start up the library
  sensors.begin();
  // set the resolution to 10 bit (good enough?)
  sensors.setResolution(insideThermometer, 10);
  sensors.setResolution(outsideThermometer, 10);

  // alarm when temp is higher than 28C
  sensors.setHighAlarmTemp(insideThermometer, 28);

  // alarm when temp is lower than -10C
  sensors.setLowAlarmTemp(insideThermometer, -10);

  // alarm when temp is higher than 26C
  sensors.setHighAlarmTemp(outsideThermometer, 26);

  // alarm when temp is lower than 15C
  sensors.setLowAlarmTemp(outsideThermometer, 15);

  lcd.init(); // initialize the lcd
  lcd.backlight();
  lcd.clear(); // start with a blank screen
}

void printTemperature(DeviceAddress deviceAddress) // DISPLAY ERROR IF DEVICE IS NOT FOUND
{
  float tempC = sensors.getTempC(deviceAddress);
  if (tempC == -127.00) {
    lcd.print("Error");
  } 
  else 
  {
    lcd.print(tempC);
    lcd.print("/");
    lcd.print(DallasTemperature::toFahrenheit(tempC));
  }
}

void loop()
{
  delay(200);
  sensors.requestTemperatures();
  if (sensors.hasAlarm()) // check to see if there is an alarm
  {
    lcd.setCursor(0,0);
    lcd.print(" HighTemp Alarm");
    digitalWrite(7, HIGH); // turn on over-temp light
  }
  // call alarm handler function defined by sensors.setAlarmHandler
  // for each device reporting an alarm
  sensors.processAlarms();

  if (!sensors.hasAlarm())
  {
    // if no alarm just print out the current temperature
    //  printTemperature(insideThermometer);
    //  printTemperature(outsideThermometer);

    lcd.setCursor(0,0);
    lcd.print("In: ");
    printTemperature(insideThermometer);
    lcd.setCursor(0,1);
    lcd.print("Out: ");
    printTemperature(outsideThermometer);
    digitalWrite(7, LOW);// overtemp light off
  }


}
  float tempC = sensors.getTempC(deviceAddress);
  if (tempC == -127.00) {
    lcd.print("Error");
  }

So, -126.999 and -127.001 are OK, but -127.000 is a problem. Got it.

You are unconditionally calling sensors.processAlarms(). Why is that? You’ve just checked whether there are any that have an alarm condition, so, shouldn’t this be called only if that test was true?

Personally, I don’t think I’d be using the setHighAlarmTemp(), setLowAlarmTemp(), hasAlarms(), or processAlarms() methods. You get the temperature. Test it yourself. Doing so allows you control over when the pin is turned on, and when it is turned off. Perhaps you want the fan to come on at 28, but not go off until it gets back to 26.

Frankly, I don’t see where you define what the sensors instance is to do when an alarm condition is present.

PaulS:
So, -126.999 and -127.001 are OK, but -127.000 is a problem. Got it.

@PaulS:

// Error Codes
#define DEVICE_DISCONNECTED -127

Yep, -127 is device not connected. -127.001 is just a very cold day. :wink:

Oh, wait. It doesn't go that low:

Measures Temperatures from -55°C to +125°C (-67°F to +257°F)

yep - its crude, but - 127 indicates there is no device and it works - if i unplug the sensor it displays an error - letting me know there is something wrong with that specific sensor or line.

As for getting the temperature and testing it, well obviously that's the problem but figuring out the code to do it is another. If i knew how to get the temp, or its variable then i could probably work from there.

Anyone else who can help with some code to get me started?

Thanks joe

Yep, -127 is device not connected

But, that's -127 as an int. It is a float being compared. I never use == when comparing floats.

The error testing code - does not affect the end goal.... so it is not an issue. (just pretend its not there)

Joe

So, where DO you define what to do when an alarm exists?

code checks if there is an alarm:

if (sensors.hasAlarm()) // check to see if there is an alarm
  {
    lcd.setCursor(0,0);
    lcd.print(" HighTemp Alarm"); // print to lcd there is an alarm
    digitalWrite(7, HIGH); // turn on over-temp light / fan

You are safe using == with floats if they have an exact representation (for instance are an integer), but its a bad habit to get into...

Back to the problem - those chips have no hysteresis on their alarm conditions so will flicker for a bit on temperature changing past the threshold slowly. I agree to ignore all that alarm stuff and test the temperature(s) yourself - you can add hysteresis and delay as you see fit and your code will be smaller as you won't drag in all the DallasTemperature library's alarm code.

Hmm, MarkT,

Maybe, A simpler approach like the code below would help the progress

  1. This displays TEMP0 = ACTUAL TEMP on lcd line 0 and TEMP1 = ACTUAL TEMP on lcd line 1 – however i see the 2 fields to the right of the temperature filled with weird characters, but the temps are good

  2. When tempsensor1 goes above 25 , i get Alarm1 on the lcd display - good

  3. Led goes on when an alarm on temp1 occurs but it blinks - it needs to be on only…

Any code suggestions , example to clear these issues would be appreciated

Joe

#include <OneWire.h>

#include <DallasTemperature.h>
#include <LiquidCrystal_I2C.h>
#include <Wire.h>

LiquidCrystal_I2C lcd(0x27,16,2); // set the LCD address to 0x27  16/2
// LiquidCrystal_I2C lcd(0x27,20,4); // set the LCD address to 0x27  20/


// pin connected to sensor
int tempPin = 2;
// define the onewire obj needed for connecting to onewire components
OneWire oneWire(tempPin);
// define dallas obj, makes it easier to read temp
DallasTemperature tempSens(&oneWire);

DeviceAddress insideThermometer = { 
  0x28, 0x25, 0x33, 0xDC, 0x03, 0x00, 0x00, 0x7E };
DeviceAddress outsideThermometer = { 
  0x28, 0x67, 0x3D, 0xDC, 0x03, 0x00, 0x00, 0xC7 };


void setup() {
  // set up the serial console
  Serial.begin(9600);
  pinMode(7, OUTPUT); //pin selected to control OVER TEMP LED /fan off
  digitalWrite(7, LOW);


  lcd.init(); // initialize the lcd
  lcd.backlight();
  lcd.clear(); // start with a blank screen



  // init the temp sensor
  tempSens.begin();

  // set the resolution to 10 bit 
  tempSens.setResolution(insideThermometer, 10);
  tempSens.setResolution(outsideThermometer, 10);

}

void loop() {
  // get the current temperature
  tempSens.requestTemperatures();

  // get the temperature in centigrade
  // index 0 as multiple temp sensors can be connected on same bus

  float t = tempSens.getTempCByIndex(0); / first sensor 0
  Serial.print("TEMP0 = ");
  Serial.println(t);
  lcd.setCursor(0,0);
  lcd.print("TEMP0 = "); 
  lcd.println(t);  //print sensor0 temperature
  delay(100);

  float t1 = tempSens.getTempCByIndex(1);
  lcd.setCursor(0,1);
  lcd.print("TEMP1 = ");
  lcd.println(t1); // print sensor 1 temperature to lcd
  Serial.print("TEMP1= ");
  Serial.println(t1);
  {
//------------------------------------conditions-----------------------
   
    if  (t1 > 25) // IF TEMP ON SENSOR1 IS GREATER THAN 25  set alarm and turn on led / fan
{
    lcd.setCursor(0,1);
    lcd.print("Alarm1= ");
    lcd.setCursor(0,2);
    lcd.println(t1);
    digitalWrite(7,HIGH);
  }
else 
{
digitalWrite(7,LOW); // KEEP LED / FAN OFF
}

}


}

however i see the 2 fields to the right of the temperature filled with weird characters,

try using lcd.print instead of lcd.println

Also, put some debugging serial prints in your temp testing if. It'll illustrate any variation around the 25 degree mark that's apparently causing flashing.

Willbill,

Yep, -the removal of the" ln" got rid of the extra weird characters at the end of the temperatures.. lcd now displays clean temps

Still trying to address the LED blinking problem when i get an alarm

Serial.println is your friend in this case - what temps are you getting while it flashes?

joeman: ... i see the 2 fields to the right of the temperature filled with weird characters, but the temps are good

Try print rather than println. Those weird characters are probably carriage-return + newline.

wildbill: try using lcd.print instead of lcd.println

Och. Ninja'd!

Wildbill,

While monitor the serial port:

With no alarm:

i get temp0 =21.22 temp1= 22.75 - looks good

Wth an alarm (temp over 25): LED BLINKING

TEMP0 = 22.00TEMP1= 27.25Alarm1= 27.25

TEMP0 = 22.00TEMP1= 27.00Alarm1= 27.00

TEMP0 = 22.00TEMP1= 27.00Alarm1= 27.00

TEMP0 = 21.75TEMP1= 26.75Alarm1= 26.75

until it reaches temp of 25 then - alarm goes off / led shuts off

i get temp0 =21.00 temp1= 25.00 - looks good

Still cannot seem to figure a way to stop the blink led and make it steady when it alarms.

Also when i try to change the if (t1 > 25) to if (t1 => 25) i get an error - was trying to change Alarm if temp is = to or greater than 25

Can you post the code you used to generate that output?

Also, how is the LED wired? Hopefully there's a current limiting resistor in there somewhere.

How does it act if you choose a different pin for the LED?

WildBill,

latest code:

With no alarm lcd displays:

TEMP0 = 22.25 ( CURRENT TEMP)
TEMP1 = 22.25 ( CURRENT TEMP)

When alarm occurs on temp1 LCD displays:

TEMP0 = 22.25 ( CURRENT TEMP)
Alarm1 = 29.50 ( CURRENT TEMP) plus Led is blinking

When alarm occurs on temp0 LCD displays:

Alarm0 = 25.50 ( CURRENT TEMP) ---- but “Alarm0” is blinking and led is not blinking
TEMP1 = 22.50 ( CURRENT TEMP)

#include <OneWire.h>

#include <DallasTemperature.h>
#include <LiquidCrystal_I2C.h>
#include <Wire.h>

LiquidCrystal_I2C lcd(0x27,16,2); // set the LCD address to 0x27  16/2
// LiquidCrystal_I2C lcd(0x27,20,4); // set the LCD address to 0x27  20/


// pin connected to sensor
int tempPin = 2;
// define the onewire obj needed for connecting to onewire components
OneWire oneWire(tempPin);
// define dallas obj, makes it easier to read temp
DallasTemperature tempSens(&oneWire);

DeviceAddress insideThermometer = { 
  0x28, 0x25, 0x33, 0xDC, 0x03, 0x00, 0x00, 0x7E };
DeviceAddress outsideThermometer = { 
  0x28, 0x67, 0x3D, 0xDC, 0x03, 0x00, 0x00, 0xC7 };


void setup() {
  // set up the serial console
  Serial.begin(9600);
  pinMode(7, OUTPUT); //pin selected to control OVER TEMP LED
  // digitalWrite(7, LOW);


  lcd.init(); // initialize the lcd
  lcd.backlight();
  //lcd.begin(16,2); // columns, rows. use 16,2 for a 16x2 LCD, etc.
  lcd.clear(); // start with a blank screen



  // initialise the temp sensor

    tempSens.begin();
  // set the resolution to 10 bit (good enough?)
  tempSens.setResolution(insideThermometer, 10);
  tempSens.setResolution(outsideThermometer, 10);

}

void loop() {
  // get the current temperature

  tempSens.requestTemperatures();

  // get the temperature in centigrade
  // index 0 as multiple temp sensors can be connected on same bus

    float t = tempSens.getTempCByIndex(0);

  Serial.print("TEMP0 = ");
  Serial.print(t);
  lcd.setCursor(0,0);
  lcd.print("TEMP0 = ");
  lcd.print(t);
  delay(500);

  float t1 = tempSens.getTempCByIndex(1);
  lcd.setCursor(0,1);
  lcd.print("TEMP1 = ");
  lcd.print(t1);
  Serial.print("TEMP1= ");
  Serial.print(t1);
  //delay(200);

  if  (t  > 29) //sensor0
  {
    lcd.setCursor(0,0);
    Serial.println("Alarm0= ");
    lcd.print("Alarm0= ");
    lcd.setCursor(8,0);
    Serial.println(t);
    lcd.print(t);
    digitalWrite(7,HIGH);
  }

  if  (t1  > 25) //sensor 1
  {
    lcd.setCursor(0,1);
    Serial.println("Alarm1= ");
    lcd.print("Alarm1= ");
    lcd.setCursor(8,1);
    Serial.println(t1);
    lcd.print(t1);
    digitalWrite(7,HIGH);
  }
  else 
  {
    digitalWrite(7,LOW);
  }









}

I tried it using pin 8 ( change code accordingly) - same results.

I am using a 1k resistor for the led -

  1. I decided to replace the led in the same spot. Now led is not blinking and it stays on during a Temp1- alarm1 and goes off with no alarm1 -PERFECT

  2. I added another led for Temp0

  3. When Temp0 goes into alarm0 mode - LED still blinks light - Not good

  4. The lcd display also flashes Temp0 to Alarm0 back and forth - Not good