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.
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.
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:
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)
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
}
}
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.
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?
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.
Maybe, A simpler approach like the code below would help the progress
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
When tempsensor1 goes above 25 , i get Alarm1 on the lcd display - good
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.
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);
}
}