DS18B20

Hi to everyone,

I am really amateur of using Arduino and I have an issue using the DS18B20 temperature sensor.

I have installed the DS18B20 temperature probe in order to take some measurements from the back sheet of a Photovoltaic module. Some times and while the sensor is seems to working fine it sticks to a temperature. There is not a specific temperature that the sensor sticks.

It is possible to fills the internal memory of ATMEGA318 and the code stop running? When I restart the arduino the sensor start taking measurements again.

Regards

Nick

You need to post your code.

post the code of your sketch and we can do an analysis

please also post links to libraries used if not standard?

which version of the IDE are you using?

do you use the DS18B20 in parasite mode?

This is the code

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

// Data wire is plugged into port 6 on the Arduino
#define ONE_WIRE_BUS 10
#define TEMPERATURE_PRECISION 9

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

#include <LiquidCrystal.h>

// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

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

// arrays to hold device addresses
DeviceAddress insideThermometer;                                    //outsideThermometer;

int relay =7;

void setup(void)

{
  pinMode(relay,OUTPUT);

lcd.begin(20, 4);

  // start serial port
  Serial.begin(9600);
  Serial.println("Dallas Temperature IC Control Library Demo");

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

  // locate devices on the bus
  Serial.print("Locating devices...");
  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 };
  //outsideThermometer   = { 0x28, 0x3F, 0x1C, 0x31, 0x2, 0x0, 0x0, 0x2 };

  // 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).
  // 
  // method 1: by index
  if (!sensors.getAddress(insideThermometer, 0)) Serial.println("Unable to find address for Device 0"); 
                           //if (!sensors.getAddress(outsideThermometer, 1)) Serial.println("Unable to find address for Device 1"); 

  // method 2: search()
  // search() looks for the next device. Returns 1 if a new address has been
  // returned. A zero might mean that the bus is shorted, there are no devices, 
  // or you have already retrieved all of them.  It might be a good idea to 
  // check the CRC to make sure you didn't get garbage.  The order is 
  // deterministic. You will always get the same devices in the same order
  //
  // Must be called before search()
  //oneWire.reset_search();
  // assigns the first address found to insideThermometer
  //if (!oneWire.search(insideThermometer)) Serial.println("Unable to find address for insideThermometer");
  // assigns the seconds address found to outsideThermometer
  //if (!oneWire.search(outsideThermometer)) Serial.println("Unable to find address for outsideThermometer");

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

                      // Serial.print("Device 1 Address: ");
                     // printAddress(outsideThermometer);
                    // Serial.println();

  // set the resolution to 9 bit
  sensors.setResolution(insideThermometer, TEMPERATURE_PRECISION);
                                 // sensors.setResolution(outsideThermometer, TEMPERATURE_PRECISION);

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

                                 // Serial.print("Device 1 Resolution: ");
                               // Serial.print(sensors.getResolution(outsideThermometer), DEC); 
                                 // Serial.println();
  
  // set up the LCD's number of columns and rows: 
  
}

// function to print a device address
void printAddress(DeviceAddress deviceAddress)
{
  for (uint8_t i = 0; i < 8; i++)
  {
    // zero pad the address if necessary
    if (deviceAddress[i] < 16) Serial.print("0");
    Serial.print(deviceAddress[i], HEX);
  }
}

// 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.print(DallasTemperature::toFahrenheit(tempC));
  delay(2000);
  
  
}



// function to print a device's resolution
void printResolution(DeviceAddress deviceAddress)
{
  Serial.print("Resolution: ");
  Serial.print(sensors.getResolution(deviceAddress));
  Serial.println();    
}

// main function to print information about a device
void printData(DeviceAddress deviceAddress)
{
  Serial.print("Device Address: ");
  printAddress(deviceAddress);
  Serial.print(" ");
  printTemperature(deviceAddress);
  Serial.println();
}

void loop(void)
{ 
  // call sensors.requestTemperatures() to issue a global temperature 
  // request to all devices on the bus
  //Serial.print("Requesting temperatures...");
  sensors.requestTemperatures();
  //Serial.println("DONE");

  // print the device information
  //printData(insideThermometer);
  //printData(outsideThermometer);
  
    Serial.println(sensors.getTempC(insideThermometer));
  //Serial.println(sensors.getTempC(outsideThermometer));
  Serial.println("   ");
  
  lcd.setCursor(0, 0);
  lcd.print("The Temperature is:");
  lcd.setCursor(0, 2);
  lcd.print("      ");
  lcd.print(sensors.getTempC(insideThermometer));
  lcd.print(" C");
  
  int setpoint = 29;
  int swing = 1; 
  if ( sensors.getTempC(insideThermometer) >=setpoint + swing) //&&  sensors.getTempC(insideThermometer) >sensors.getTempC(outsideThermometer) ) 
  {
  digitalWrite(7,HIGH);
    Serial.println("ON ");

 } 
 else if ( sensors.getTempC(insideThermometer) <setpoint - swing)
 {
  digitalWrite(7,LOW);
  Serial.println("OFF ");
 }
delay(500);

 
}

moderatore update: added code tags → # button above smileys.

I am using the Arduino 1.0.5 and I have installed the sensor at parasite mode.

Can you please try the sensor in non-parasitic mode to see if that causes the problem?
(It might just have too little power somehow)

How long are the wires used?
Do you use a pull up resistor?
if so, what value?

nikolakisant03:
This is the code

// Data wire is plugged into port 6 on the Arduino

#define ONE_WIRE_BUS 10

This looks like a bad start.

While not necessarily utter junk, I think the code is a verbose mess.

I think you are right with your suspicions. Try this, and note the number of lines involved to achieve essentially the same result. If you want to print to LCD too, simply add the initialisation, and add commands at the bottom of the loop like

lcd.print (Temp1);
lcd.print(Temp2);

along with the appropriate cursor commands

/* Basic 3xDS18B20 code for serial monitor, bluetooth, Excel or w.h.y.
Derived from Hacktronics. Use their address sniffer and substitute your 
numbers. Use Hacktronics connections diagram. 
Stay away from using parasite power
-127C means bad connection
85 means you haven't gotten a read yet, probably wrong order of commands
*/

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

// Data wire is plugged into pin 3 on the Arduino
#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);
  
byte Thermo1[8] = {0x28, 0x39, 0xFD, 0x50, 0x04, 0x00, 0x00, 0X69};
byte Thermo2[8] = {0x28, 0x09, 0xA9, 0xC0, 0x03, 0x00, 0x00, 0x95};
byte Thermo3[8] = {0x28, 0x62, 0xA5, 0x2D, 0x04, 0x00, 0x00, 0x21};   

float tempC,Temp1,Temp2,Temp3,diff;  

void setup(){

  Serial.begin(9600);
  sensors.begin();

  delay(500);//Wait for newly restarted system to stabilize

  sensors.setResolution(Thermo1, 12); 
  sensors.setResolution(Thermo2, 12);
  sensors.setResolution(Thermo3, 12);
}

void loop() {
 sensors.requestTemperatures();  // call readings from the addresses
  Temp1 = sensorValue(Thermo1);
  Temp2 = sensorValue(Thermo2);  
  Temp3 = sensorValue(Thermo3); 
       diff = Temp2 - Temp1;

Serial.print("      Temp1 = ");
Serial.print(Temp1);
Serial.print("      Temp2 = "); 
Serial.print(Temp2);
Serial.print("      difference = ");
Serial.print(diff);
Serial.print("      Temp3 = ");
Serial.println(Temp3);

delay(1000);
}

//sensorValue function
float sensorValue (byte deviceAddress[])
{
  tempC = sensors.getTempC (deviceAddress);
  return tempC;
}

and note the number of lines involved to achieve essentially the same result

+1

Dear all thank you for your replies,

The wires I am using are 5-6 meters long and the pull up resistor is 4.7k. Ok I will try to power the prove with an external power supply.

I will try also the new code and I'll let you know with the results.

But no one answer me. It is possible to fills the internal memory of ATMEGA318 and the code stop running? How could I clear the memory after a number of cycles?

Thank you all for the replies.!!

nikolakisant03:
Dear all thank you for your replies,

The wires I am using are 5-6 meters long and the pull up resistor is 4.7k. Ok I will try to power the prove with an external power supply.

5-6 metres should be fine with decent cable and I'm sure the normal 4.7.k pullup would be OK. You can power them off Arduino, no need for an external PSU. Just stay away from parasitic power. I have never heard of anybody come up with a good reason for using parasitic power when Arduino is to hand and regarding it as the kiss of death is a good policy.

But no one answer me. It is possible to fills the internal memory of ATMEGA318 and the code stop running? How could I clear the memory after a number of cycles?

I did answer, but I guess too discreetly. The code you posted was too junky to merit perusal. You may well be clogging the memory in the way you suspect, as junk code is a very good way to do that. The best way to clear the memory is to not allow it to get clogged in the first place. One reason why code posted above will run for years is that it doesn't store anything, it just reads the sensors and passes the information to where it is needed.

Thank you Nick_Pyner!!

Hi again,

Could someone help me in this error of Nick_Pyner's code?

Regards

Nick

I don’t think there is an error in my code. It compiles properly and it is working right now before my eyes.

I don’t know what your problem is, but there are two things you need to do.

The first is to learn how to post code. A picture is not really going to help much. Use the hash icon and insert it between the pair. “Please Read…” instructions abound at the top of every forum section.

The second is that you have not inserted the addresses of your sensors into the code. I don’t think that is the cause of your problem but it will certainly stop you getting a result when you fix it.

I now think it is likely that your problem has occurred because you have not properly installed theDallasTemperature library. “Properly installing” includes restarting the IDE after installation, even if you have put it in the right place. In short, you may find you get a result now by the simple expedient of restarting the IDE, i.e. the code is 110% kosher, but the IDE didn’t know what the hell you are talking about.

You will notice that the IDE takes for ever to start. I believe this is because it does a great swag of chores first, including a browse through the libraries.

Hi again,

This is the updated code.

/* Basic 3xDS18B20 code for serial monitor, bluetooth, Excel or w.h.y.
Derived from Hacktronics. Use their address sniffer and substitute your 
numbers. Use Hacktronics connections diagram. 
Stay away from using parasite power
-127C means bad connection
85 means you haven't gotten a read yet, probably wrong order of commands
*/

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

// include the library code:
#include <LiquidCrystal.h>

// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);


// Data wire is plugged into pin 10 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);
  
byte Thermo1[8] = {0x28, 0xF1, 0xE1, 0xD9, 0x04, 0x00, 0x00, 0x40};

float tempC,Temp1;  

int relay =7;

void setup(){

  lcd.begin(20, 4);
  
  pinMode(relay,OUTPUT);
  
  Serial.begin(9600);
  sensors.begin();

  delay(500);//Wait for newly restarted system to stabilize

  sensors.setResolution(Thermo1, 12); 
  
}

void loop() {
 sensors.requestTemperatures();  // call readings from the addresses
  Temp1 = sensorValue(Thermo1);
  

Serial.print("      Temp1 = ");
Serial.print(Temp1);


lcd.setCursor(0, 0);
  lcd.print("The Temperature is:");
  lcd.setCursor(0, 2);
  lcd.print("      ");
  lcd.print(Temp1);
  lcd.print(" C");
  
  
  int setpoint = 34;
  int swing = 1; 
  if ( Temp1 >=setpoint + swing) //&&  sensors.getTempC(insideThermometer) >sensors.getTempC(outsideThermometer) ) 
  {
  digitalWrite(7,HIGH);
    Serial.println("ON ");

 } 
 else if (Temp1 <setpoint - swing)
 {
  digitalWrite(7,LOW);
  Serial.println("OFF ");
 }

delay(1000);
}

//sensorValue function
float sensorValue (byte deviceAddress[])
{
  tempC = sensors.getTempC (deviceAddress);
  return tempC;
}

Furthermore I connect the sensor in normal mode (not in parasite) but it still sticks. I observe that it sticks when the digital output 7 change from ON to OFF or versa. For example stick when the sensor reach the temperature of 35,06 Celsius or 32.92 Celsius.

Any ideas what I should check? I have check all of my connection and everything is looking fine.

Regards

Nick

void loop() {
 sensors.requestTemperatures();  // call readings from the addresses
  Temp1 = sensorValue(Thermo1);

Might try a delay before reading. Mine requires at least .750ms.
You can reduce the delay at the end of your loop if required.

void loop() {
 sensors.requestTemperatures();  // call readings from the addresses
 delay(750);
  Temp1 = sensorValue(Thermo1);

//DS18B20 flat side up, left to right.
//pin 1 to Ground.
//pin 2 Data with 4.7k pullup to digital pin used.
//pin 3 to +5 volts.

Any ideas what I should check?

I am assuming that the temperature readings are OK until they get to the critical condition. Therefore, all the problems are in that arena, and there is nothing wrong with the temperature code. One thing for certain is that the delay command you already have is all you need.

I don’t know anything about relays but, if you are driving them off the Arduino pins, there may be a power problem. This can be verified by running the project with the relays disconnected.

Since the temp is a float, I would be inclined to call swing and setpoint as floats. If your relay sticks at 35 but comes good at <=36, I guess using all floats is very likely the answer.