Pages: [1]   Go Down
Author Topic: Help modifying DS18B20 sample code to activate a relay  (Read 1548 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Newbie
*
Karma: 0
Posts: 13
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hello everyone. I've got my Arduino setup and functioning properly. I've just setup two DS18B20 digital temp sensors and they work just fine. What I'm trying to do now is modify the code so that if the insideTemp is > 100F then I turn on a relay.

Ideally I'd like to be able to do something like below, but when I do it's not happy for some reason.

if (insideTemperature > 100)
{
  Serial.print("It's hot!");
}

Here is the current code. It's just stock code I found somewhere.

Code:
// This Arduino sketch reads DS18B20 "1-Wire" digital
// temperature sensors.
// Tutorial:
// http://www.hacktronics.com/Tutorials/arduino-1-wire-tutorial.html

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

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

// 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.
// See the tutorial on how to obtain these addresses:
// http://www.hacktronics.com/Tutorials/arduino-1-wire-address-finder.html

DeviceAddress insideThermometer = { 0x28, 0x4C, 0xF0, 0x4A, 0x04, 0x00, 0x00, 0xD5 };
DeviceAddress outsideThermometer = { 0x28, 0x79, 0x35, 0x4A, 0x04, 0x00, 0x00, 0x23 };
DeviceAddress dogHouseThermometer = { 0x28, 0x59, 0xBE, 0xDF, 0x02, 0x00, 0x00, 0x9F };

void setup(void)
{
  // start serial port
  Serial.begin(9600);
  // Start up the library
  sensors.begin();
  // set the resolution to 10 bit (good enough?)
  sensors.setResolution(insideThermometer, 10);
  sensors.setResolution(outsideThermometer, 10);
  sensors.setResolution(dogHouseThermometer, 10);
}

void printTemperature(DeviceAddress deviceAddress)
{
  float tempC = sensors.getTempC(deviceAddress);
  if (tempC == -127.00) {
    Serial.print("Error getting temperature");
  } else {
    Serial.print("C: ");
    Serial.print(tempC);
    Serial.print(" F: ");
    Serial.print(DallasTemperature::toFahrenheit(tempC));
  }
}

void loop(void)
{
  delay(2000);
  Serial.print("Getting temperatures...\n\r");
  sensors.requestTemperatures();
  
  Serial.print("Inside temperature is: ");
  printTemperature(insideThermometer);
  Serial.print("\n\r");
  Serial.print("Outside temperature is: ");
  printTemperature(outsideThermometer);
  Serial.print("\n\r");
  Serial.print("Dog House temperature is: ");
  printTemperature(dogHouseThermometer);
  Serial.print("\n\r\n\r");
}
« Last Edit: February 15, 2013, 10:58:18 am by scotty562 » Logged

Poole, Dorset, UK
Offline Offline
Edison Member
*
Karma: 50
Posts: 2199
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Why do you think you need "one wire" it's a communication protocol! Why not digitalWrite() don't forget the diode on the relay!.

Mark
Logged

Global Moderator
UK
Offline Offline
Brattain Member
*****
Karma: 290
Posts: 25731
I don't think you connected the grounds, Dave.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

...or the buffer to drive the relay.
Logged

"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.

Offline Offline
Newbie
*
Karma: 0
Posts: 13
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I guess I don't understand. The DS18B20 tutorials I found say I need the one wire library to make this temp sensor work. That's why I thought I needed it. I'm not clear on the buffer to drive the relay either. The 5v of the arduino is enough to make it click.

Edit: Never mind. I think my title showed my ignorance so I edited it to be more clear.
Logged

Global Moderator
UK
Offline Offline
Brattain Member
*****
Karma: 290
Posts: 25731
I don't think you connected the grounds, Dave.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
The 5v of the arduino is enough to make it click
5v isn't the problem, current is the problem.
Most relays are going to draw more current than an Arduino I/O pin can safely supply.

Have a look at some of the interfacing examples over at the Playground.
Logged

"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.

New Jersey
Offline Offline
Faraday Member
**
Karma: 65
Posts: 3638
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
The DS18B20 tutorials I found say I need the one wire library to make this temp sensor work. That's why I thought I needed it
You do need it, at least unless you want to handle to protocol yourself. It looks fine as you now have it.

As to switching your relay, you may need to do a little refactoring; having the temperature read inside the print routine makes it awkward to control your fan since only one temp sensor's reading  should be allowed to control the fan. One solution would be to have the print function return the temperature it read. Less elegant would be to read the inside temp again after displaying the results and put your fan controlling if statements there.
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 13
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
Less elegant would be to read the inside temp again after displaying the results and put your fan controlling if statements there.

That sounds like a good idea. Would you mind giving me an example? The following doesn't work.

if (printTemperature(insideThermometer) > 100)
{
  Serial.print("It's hot!");
}
Logged

New Jersey
Offline Offline
Faraday Member
**
Karma: 65
Posts: 3638
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

You need to change the return type of the print routine from void to float and add return tempC; at the bottom of the function.
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 13
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Ok thanks for your help. I'll play with it tonight and see what I can come up with.
Logged

Seattle, WA USA
Offline Offline
Brattain Member
*****
Karma: 601
Posts: 48543
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
You need to change the return type of the print routine from void to float and add return tempC; at the bottom of the function.
When you do that, and I agree that it is necessary, give serious thought to renaming the function. printTemperature() should not return a value, at least not the temperature that it printed.
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 13
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Sweet I got it working like I want. It's a rough draft, but this definitely got me past where I was stuck. Next is to figure out the relay. Thanks everyone.

Code:
// This Arduino sketch reads DS18B20 "1-Wire" digital
// temperature sensors.
// Tutorial:
// http://www.hacktronics.com/Tutorials/arduino-1-wire-tutorial.html

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

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

// 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.
// See the tutorial on how to obtain these addresses:
// http://www.hacktronics.com/Tutorials/arduino-1-wire-address-finder.html

DeviceAddress insideThermometer = { 0x28, 0x4C, 0xF0, 0x4A, 0x04, 0x00, 0x00, 0xD5 };
DeviceAddress outsideThermometer = { 0x28, 0x79, 0x35, 0x4A, 0x04, 0x00, 0x00, 0x23 };
DeviceAddress dogHouseThermometer = { 0x28, 0x59, 0xBE, 0xDF, 0x02, 0x00, 0x00, 0x9F };

void setup(void)
{
  // start serial port
  Serial.begin(9600);
  // Start up the library
  sensors.begin();
  // set the resolution to 10 bit (good enough?)
  sensors.setResolution(insideThermometer, 10);
  sensors.setResolution(outsideThermometer, 10);
  sensors.setResolution(dogHouseThermometer, 10);
}

float printTemperature(DeviceAddress deviceAddress)
{
  float tempC = sensors.getTempC(deviceAddress);
  if (tempC == -127.00) {
    Serial.print("Error getting temperature");
  } else {

  }
 return tempC;
}

void loop(void)
{
 
  Serial.print("Getting temperatures...\n\r");
  sensors.requestTemperatures();
  float collector = printTemperature(insideThermometer);
  float tank = printTemperature(outsideThermometer);
 
  if (collector > 5)
  {
    Serial.print("Temp of collector is: ");
    Serial.print(DallasTemperature::toFahrenheit(collector));
    Serial.print("F ");
    Serial.print(collector);
    Serial.print("C");
    Serial.print("\n\r");
  }

  if (tank > 5)
  {
    Serial.print("Temp of collector is: ");
    Serial.print(DallasTemperature::toFahrenheit(tank));
    Serial.print("F ");
    Serial.print(tank);
    Serial.print("C");
    Serial.print("\n\r");
  delay(30000);
  }

}


Logged

Seattle, WA USA
Offline Offline
Brattain Member
*****
Karma: 601
Posts: 48543
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

So. printTemperature() has a side effect of returning the temperature printed. Bad idea.

The function name should reflect what the function does. There is no real reason to have a separate function to print the temperature.
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 13
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I just renamed the function to getTemperature.

I would like to have float collector = printTemperature(insideThermometer); not need a separate function to work. I'd like to be able to say: float collector = value of sensor1, but my lack of programming knowledge inhibits this. For what I'm doing it doens't really bother me that much as it's functional. Although it would be nice to know how to do it.

For the relay control I got one of these: http://www.powerswitchtail.com/Pages/default.aspx should be good to go once that gets here.
Logged

Seattle, WA USA
Offline Offline
Brattain Member
*****
Karma: 601
Posts: 48543
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
I would like to have float collector = printTemperature(insideThermometer); not need a separate function to work. I'd like to be able to say: float collector = value of sensor1, but my lack of programming knowledge inhibits this. For what I'm doing it doens't really bother me that much as it's functional. Although it would be nice to know how to do it.
You mean like this?
Code:
  float tempC = sensors.getTempC(deviceAddress);
That's the important line of code from the function.
Logged

Pages: [1]   Go Up
Jump to: