SOLUCIONADO - Incompatibilidad Software RTC y sensor temperatura digital ds18b20

Buenas arduineros,

Estoy construyendo un sistema de adquisición de datos para una caldera de calefacción con un arduino leonardo; quiero ver temperaturas y guardarlas en una tarjeta SD con la hora real proporcionada por un RTC. Por separado funciona correctamente todo pero al unirlo hay alguna incompatibilidad.

Cuando meto el código para obtener la temperatura de un sensor digital ds18b20 en el código principal, la lectura del sensor de temperatura da valores irreales. Si borro la parte del código que pertenece al control del RTC, el sensor de temperatura funciona perfectamente.

He simplificado mucho el código para que os sea más rápido de ver. Aqui va:

#include <Time.h>                    // RTC DS1307
#include <Wire.h>                    // RTC DS1307
#include <RTClib.h>                  // RTC DS1307
#include <OneWire.h>               // DS18b20
#include <DallasTemperature.h>  // DS18b20

#define Pin 2                                   // DS18b20
OneWire ourWire(Pin);                       // DS18b20
DallasTemperature sensors(&ourWire);  // DS18b20
RTC_DS1307 RTC;                            // RTC

void setup() {
Serial.begin(9600);
sensors.begin();        // DS18b20
Wire.begin();            // RTC           // El sensor de temperatura funciona bien si elimino esta linea
RTC.begin();             // RTC           // El sensor de temperatura funciona bien si elimino esta linea
}
void loop() {
sensors.requestTemperatures();    // DS18b20

// Publica en monitor serie:
DateTime now = RTC.now();         // El sensor de temperatura funciona bien si elimino esta linea
Serial.print(now.second(), DEC);   // El sensor de temperatura funciona bien si elimino esta linea
Serial.print(" ; ");
Serial.print(sensors.getTempCByIndex(0));
Serial.println(" grados");
delay (2000);
}

Si dejo en el programa todas las líneas del código, el resultado publicado en el monitor serie es este:

6 ; -127.00 grados
9 ; -127.00 grados
11 ; -127.00 grados
etc...

son los segundos del RTC ; lectura del sensor de temperatura de -127 grados.

Si elimino del código las 4 líneas que estan comentadas en el código, el resultado es este:

; 19.31 grados
; 19.37 grados
; 19.37 grados
etc...

No hay lectura de segundos, pero el sensor de temperatura funciona perfectamente.

Alguien sabe a que puede ser debido??

Gracias por adelantado

Un saludo

y esta conectado asi?

Buenas,

Si lo conecto como tú me planteas me dá una lectura de 85 grados eliminando las líneas en relación al RTC y -127 grados si dejo las líneas del RTC.

Como yo lo tengo conectado, y funciona bien el sensor de temperatra si borro las líneas del RTC es:

Gracias por todo, a ver si se os ocurre otra cosa.

Porque no pruebas el Dallas solo, y nos cuentas si tiene lecturas razonables.
SOlo sin RTC, con código limpio, un ejemplo de la librería DallasTemperature

Nota: te mandé privado, por favor edita tu post#1 y usa tags
Seleccionas todo el código y luego presionas </>
La siguiente es una imágen del Editor y el tag de código. Se borrará en 1 semana.

Buenas,

Ya he probado con varios ejemplos del dallas con el código limpio y funciona perfectamente. Es algún tipo de incompatibilidad con el RTC creo yo, he probado mil cosas y nada. A ver si a alguien se le ocurre otra cosa que pueda ser.

El privado no me ha llegado, pero ya he editado el mensaje, no sabía que se hacía así.

Gracias

Un saludo

He visto muchos códigos mezclando las dos cosas.
Hay que buscar la falla.
Quita para probar el

delay(2000);

Define DateTime now = RTC.now();
fuera del loop
y luego actualiza con RTC.now(), de este modo

#include <Time.h>                    // RTC DS1307
#include <Wire.h>                    // RTC DS1307
#include <RTClib.h>                  // RTC DS1307
#include <OneWire.h>               // DS18b20
#include <DallasTemperature.h>  // DS18b20

#define Pin 2                                   // DS18b20
OneWire ourWire(Pin);                       // DS18b20
DallasTemperature sensors(&ourWire);  // DS18b20
RTC_DS1307 RTC;                      // RTC
DateTime now;

void setup() {
	Serial.begin(9600);
	sensors.begin();        // DS18b20
	Wire.begin();            // RTC           // El sensor de temperatura funciona bien si elimino esta linea
	RTC.begin();             // RTC           // El sensor de temperatura funciona bien si elimino esta linea
}

void loop() {
	sensors.requestTemperatures();    // DS18b20

	// Publica en monitor serie:
	now = RTC.now();         // El sensor de temperatura funciona bien si elimino esta linea
	Serial.print(now.second(), DEC);   // El sensor de temperatura funciona bien si elimino esta linea
	Serial.print(" ; ");
	Serial.print(sensors.getTempCByIndex(0));
	Serial.println(" grados");
	delay (2000);
}

Sugiero un cambio de librerias para el DHT11 y el DS1307. Es mas: un voto para sustituir el 1307 por un DS3231.

La combinación OneWire.h/DallasTemperature.h, siempre me han dado dolores de cabeza.

Encontré este acumulado de librerias, y entre ellas hay una para el DHT11 que funciona para el arduino UNO y el arduino Due.

  1. Hay que descargar el compilado de librerias y extraer solo esta carpeta:
libraries/DHTlib

Dentro de la carpeta de librerias de arduino

  1. Luego se renombra de DHTlib a simplemente dht

  2. Este es uno de los ejemplos simples que trae la libreria:

//    FILE: dht11_test.ino
//  AUTHOR: Rob Tillaart
// VERSION: 0.1.01
// PURPOSE: DHT library test sketch for DHT11 && Arduino
//     URL:
//
// Released to the public domain
//

#include <dht.h>

dht DHT;

#define DHT11_PIN 2

void setup()
{
  Serial.begin(115200);
  Serial.println("DHT TEST PROGRAM ");
  Serial.print("LIBRARY VERSION: ");
  Serial.println(DHT_LIB_VERSION);
  Serial.println();
  Serial.println("Type,\tstatus,\tHumidity (%),\tTemperature (C)");
}

void loop()
{
  // READ DATA
  Serial.print("DHT11, \t");
  int chk = DHT.read11(DHT11_PIN);
  switch (chk)
  {
    case DHTLIB_OK:  
 Serial.print("OK,\t"); 
 break;
    case DHTLIB_ERROR_CHECKSUM: 
 Serial.print("Checksum error,\t"); 
 break;
    case DHTLIB_ERROR_TIMEOUT: 
 Serial.print("Time out error,\t"); 
 break;
    default: 
 Serial.print("Unknown error,\t"); 
 break;
  }
  // DISPLAY DATA
  Serial.print(DHT.humidity, 1);
  Serial.print(",\t");
  Serial.println(DHT.temperature, 1);

  delay(2000);
}

Esto es lo que reporta el monitor serie:

DHT TEST PROGRAM 
LIBRARY VERSION: 0.1.13

Type,	status,	Humidity (%),	Temperature (C)
DHT11, 	OK,	37.0,	23.0
DHT11, 	OK,	37.0,	23.0
DHT11, 	OK,	37.0,	23.0
DHT11, 	OK,	36.0,	23.0
DHT11, 	OK,	36.0,	23.0
DHT11, 	OK,	37.0,	23.0
DHT11, 	OK,	36.0,	23.0
DHT11, 	OK,	38.0,	23.0
DHT11, 	OK,	37.0,	23.0

Si te es posible consigue un DS3231, es mucho mejor que el DS1307. Hice pruebas con el DS1307 que acumula polvo para intentar hacer una prueba y simular el hardware que tienes, pero el 1307 se negó a despertar. Conecté en su lugar un 3231 y funciona impecablemente.

Tomé la libreria para DS1307 hecha por Henning

Este es el código que armé para las pruebas

// 6 Nov 2015
#include <dht.h>     //https://github.com/RobTillaart/Arduino
#include <DS1307.h>  //http://www.rinkydinkelectronics.com/library.php?id=34

dht DHT;
#define DHT11_PIN 2

// SDA  al pin digital 4, SCL al pin digital 5
DS1307 rtc(4, 5);  

void setup()
{
  rtc.halt(false);

// Lineas para actualizar dia, hora y fecha en el RTC
//  rtc.setDOW(FRIDAY);        // Dia VIERNES (FRIDAY)
//  rtc.setTime(12, 59, 0);     // hora actual: hh, mm, en formato de 24h
//  rtc.setDate(6, 11, 2015);   // fecha actual dd, mm, aaaa
  
  Serial.begin(115200);
  Serial.println("DHT TEST PROGRAM ");
  Serial.print("LIBRARY VERSION: ");
  Serial.println(DHT_LIB_VERSION);
  Serial.println();
  Serial.println("Type,\tstatus \thora     \tH (%) \tT (C)");
}

void loop()
{
  // READ DATA
  Serial.print("DHT11, \t");
  int chk = DHT.read11(DHT11_PIN);
  switch (chk)
  {
    case DHTLIB_OK:  
		Serial.print("OK,\t"); 
		break;
    case DHTLIB_ERROR_CHECKSUM: 
		Serial.print("Checksum error,\t"); 
		break;
    case DHTLIB_ERROR_TIMEOUT: 
		Serial.print("Time out error,\t"); 
		break;
    default: 
		Serial.print("Unknown error,\t"); 
		break;
  }
  // DISPLAY DATA
  Serial.print(rtc.getTimeStr());
  Serial.print(" \t");
  Serial.print(DHT.humidity, 1);
  Serial.print(" \t");
  Serial.println(DHT.temperature, 1);

  delay(2000);
}

Este es el resultado del codigo previo:

DHT TEST PROGRAM 
LIBRARY VERSION: 0.1.13

Type,	status 	hora     	H (%) 	T (C)
DHT11, 	OK,	13:10:49 	37.0 	22.0
DHT11, 	OK,	13:10:51 	37.0 	22.0
DHT11, 	OK,	13:10:53 	37.0 	22.0
DHT11, 	OK,	13:10:55 	37.0 	22.0
DHT11, 	OK,	13:10:57 	37.0 	22.0

El DS3231 funciona con las mismas librerias y conexionado que el DS1307, así que simplemente sacas de su empaque el flamante 3231 y lo conectas en el mismo lugar donde está el 1307.

Sugiero un cambio de librerias para el DHT11 y el DS1307. Es mas: un voto para sustituir el 1307 por un DS3231.

La combinación OneWire.h/DallasTemperature.h, siempre me han dado dolores de cabeza.

Vaya TFTLCDCyg, no entiendo que respondiste.
El hilo habla de Dallas DS18B20 y RTC DS1307
y tu respondes con usar un DHT11 y un DS3231 que esta bien pq hay libreraias que lo manejan igual que el 1307.

Entonces lo que propones es que cambie el Dallas por un DHT11 y el DS1307 por un DS3231, te va a matar jajajaja!!!

jejejeje me he confundido de sensor, estaba bien entretenido tratando de armar un reloj con un LCD de texto 4 lineas que se me paso el detallito del sensor con el que se tiene la duda. Ya saben que uno sumerge en las librerias y código... y cuando lo que has conectado da señales de vida, a uno se le van las notas...

Pero no todo lo dejo en saco roto, ¿que tal si usan la libreria de Hening para el DS1307?

PD: el avance del post me ha motivado a darle una segunda oportunidad al tinyRTC, pero nada más no se deja >:(

Eso si, gracias a sus comentarios me dieron la motivación y ya tengo funcionando el 3231 junto con el sensor de temperatura/humedad.

Buenas, perdón por tardar tanto en contestar, he estado realizando varias pruebas y no he conseguido avanzar mucho. Vamos por partes:

surbyte, he realizado las dos cosas que me comentabas, al eliminar el delay no cambia nada, simplemente la frecuencia con que se actualiza. Si defino DateTime now fuera del loop tal y como me indicas (y a parte comento la primera línea del programa //#include <Time.h> para que funcione el programa) el resultado es el mismo que antes, no cambia nada, la temperatura registra -127 grados.

TFTLCDCyg, he probado con la librería de Hening y creo que no funciona para el arduino Leonardo (es el arduino que yo tengo) no consigo hacer que funcionen bien ni los ejemplos que trae la librería de Hening (la hora se queda siempre fija, a veces se actualiza, hace cosas muy raras)

Comentas que

"La combinación OneWire.h/DallasTemperature.h, siempre me han dado dolores de cabeza."

Pero estas dos librerías son para controlar el sensor que estoy usando "DS18b20" no??

Conocen alguna otra forma para controlar este sensor sin usar estas librerías??

Conocen algún otro sensor de temperatura digital que funcione mejor que el DS18b20 pero que tenga un poco más de precisión que el DHT11 (este último sólo dá medidas de temperatura sin decimales)

Si me compro un DS3231 y lo substituyo por el DS1307creen que funcionaría??

Muchas gracias por todo

Un saludo

Prueba a mover el delay delante de la lectura de temperatura:

delay(2000);
Serial.print(sensors.getTempCByIndex(0));

Como te había dicho, usa DS1307RTC Library, mira

El código que usé

#include <Time.h>                  // RTC DS1307
#include <Wire.h>                  // RTC DS1307
#include <DS1307RTC.h>             // https://www.pjrc.com/teensy/td_libs_DS1307RTC.html
#include <OneWire.h>               // DS18b20
#include <DallasTemperature.h>     // DS18b20

#define Pin 2                      // DS18b20
OneWire ourWire(Pin);              // DS18b20
DallasTemperature sensors(&ourWire);  // DS18b20

void setup() {
    Serial.begin(9600);
    sensors.begin();        // DS18b20
}

void loop() {
	tmElements_t tm;

	sensors.requestTemperatures();    // DS18b20

	// Publica en monitor serie:
	if (RTC.read(tm)) {
		print2digits(tm.Second);
		Serial.print(" ; ");
		Serial.print(sensors.getTempCByIndex(0));
		Serial.println(" grados");
		delay (2000);
	}
	else {
	    if (RTC.chipPresent()) {
	      Serial.println("The DS1307 is stopped.  Please run the SetTime");
	      Serial.println("example to initialize the time and begin running.");
	      Serial.println();
	    } 
	    else {
	      Serial.println("DS1307 read error!  Please check the circuitry.");
	      Serial.println();
    	}
    }
}

void print2digits(int number) {
  if (number >= 0 && number < 10) {
    Serial.write('0');
  }
  Serial.print(number);
}

Buenas,

Noter, el cambio de posición del delay no cambia el resultado. Gracias de todas formas.

Surbyte, he probado con el montaje y el código exacto que has puesto y nada, obtengo el mismo resultado de antes:

41 ; -127.00 grados
43 ; -127.00 grados
45 ; -127.00 grados

Para comprobar que no era un problema de cableado, he comentado en tu programa todas las líneas que tenían algo que ver con el RTC (menos la 3ª línea #include <DS1307RTC.h> donde se llama a la librería) y obtengo lo mismo:

; -127.00 grados
; -127.00 grados
; -127.00 grados

Pero si comento también la 3ª línea de tu código que es la que llama a la librería "DS1307RTC.h" funciona! Obtengo esto:

; 27.50 grados
; 27.50 grados
; 28.00 grados
; 29.50 grados
; 29.50 grados
; 29.00 grados
; 28.50 grados

Simplemente por incluir esta librería sin usarla para nada, el sensor deja de funcionar. Te dejo tu código con las líneas que yo he comentado para que funcione a ver si encuentras algo.

Muchas gracias

#include <Time.h>                  // RTC DS1307
#include <Wire.h>                  // RTC DS1307
//#include <DS1307RTC.h>             // https://www.pjrc.com/teensy/td_libs_DS1307RTC.html
#include <OneWire.h>               // DS18b20
#include <DallasTemperature.h>     // DS18b20
#define Pin 2                      // DS18b20
OneWire ourWire(Pin);              // DS18b20
DallasTemperature sensors(&ourWire);  // DS18b20

void setup() {
    Serial.begin(9600);
    sensors.begin();        // DS18b20
}

void loop() {
//	tmElements_t tm;
	sensors.requestTemperatures();    // DS18b20
	// Publica en monitor serie:
//	if (RTC.read(tm)) {
//		print2digits(tm.Second);
		Serial.print(" ; ");
		Serial.print(sensors.getTempCByIndex(0));
		Serial.println(" grados");
		delay (2000);
	}
//	else {
//	    if (RTC.chipPresent()) {
//	      Serial.println("The DS1307 is stopped.  Please run the SetTime");
//	      Serial.println("example to initialize the time and begin running.");
//	      Serial.println();
//	    }
//	    else {
//	      Serial.println("DS1307 read error!  Please check the circuitry.");
//	      Serial.println();
//  	}
//    }
//}
//
//void print2digits(int number) {
//  if (number >= 0 && number < 10) {
//    Serial.write('0');
//  }
//  Serial.print(number);
//}

Tu sensor esta mal cableado. Esta trabajando en modo parásito?
Yo te subí un código (tu código fallaba) y además subí un esquema, y en el esquema el DS18B20 esta conectado a 5V y a una R.
Tu lo conectas asi? Parece que si pero no entiendo esto que te marco a continuación

Yo veo un puente entre dos extremos.
Uno debiera estar si a GND y otro a 5V. No veo la conexión a 5V.
Te lo pregunté en el post#2 mío, recuerdas?

Buenas Surbyte,

He probado de ambas maneras de conexión de cableado y el resultado es el mismo, ahora mismo lo tengo conectado asi:

Y el resultado es el mismo. Puede ser porque mi arduino es un Leonardo y alguna de las librerías sólo funcione con el arduino uno?? Es lo único que se me ocurre.

Gracias de todas maneras

No. Eso si que no es porque sea Leonardo.

¿Probaste lo que te dije de modificar la posición del delay?

Si que probé lo de cambiar la posición del delay y el resultado es el mismo.

Creeis que con un DS3231 en lugar del DS1307 que tengo actualmente se solucionaría el problema?

Gracias

A mi me ocurría algo parecido, el problema está en el código, creo que el esquema de conexión que usas era el parásito, es correcto. Puede ser porque no guardas los resultados de los ds18 en una variable sino que los muestras por el serial directamente, prueba almacenándolos en una variable.

float a = sensors.getTempCByIndex(0);

Otra posible solución o almenos intentarlo, es que tomes el tiempo después o antes de solicitar la temperatura, es decir, antes del comando

sensors.requestTemperatures(); 
float a = sensors.getTempCByIndex(0);

Buenas,

Actualmente lo tengo conectado de la forma que no es parásita, aunque he probado todo lo que me comentáis con ambas maneras de conexión.

He probado a hacer las dos cosas que me comentas y unas cuantas más (he cambiado de posición las líneas del RTC y del sensor, he creado otra variable para los segundos, he introducido varios delay para dar tiempo a realizar las operaciones) y nada, el resultado es el mismo.

Comentaros que si pongo el código de la manera que funciona (borrando las líneas que hacen referencia al RTC) y desconecto la resistencia de 4,7K, el sensor sigue funcionando bien.

Y que cuando escribo en el código cualquiera de las líneas que hacen referencia al RTC, el sensor deja de funcionar.

Os dejo el último código que he probado y el resultado que me dá.

#include <Time.h>
#include <Wire.h>
#include <RTClib.h>
#include <OneWire.h>
#include <DallasTemperature.h>
#define Pin 2
OneWire ourWire(Pin);
DallasTemperature sensors(&ourWire);
RTC_DS1307 RTC;
float a;
float seg;

void setup() {
  Serial.begin(9600);
  sensors.begin();
  Wire.begin();                  // Funciona bien si elimino esta línea
  RTC.begin();                   // Funciona bien si elimino esta línea
  }
void loop() {
  DateTime now = RTC.now();      // Funciona bien si elimino esta línea
  float sec = now.second();      // Funciona bien si elimino esta línea
//  delay (500);
  Serial.print(sec);             // Funciona bien si elimino esta línea
  Serial.print(" ; "); 
//  delay (500);
  
  sensors.requestTemperatures();
//  delay (500);
  float a = sensors.getTempCByIndex(0);
//  delay (500);
  Serial.print(a);
  Serial.println(" grados");
  
  delay (1000);
}

Monitor serie:
38.00 ; -127.00 grados
40.00 ; -127.00 grados
41.00 ; -127.00 grados
43.00 ; -127.00 grados

Gracias por vuestro tiempo y un saludo