50 NTC o DS18B20 con un arduino UNO [SOLUCIONADO casi]

Vaya, Sergegsx me ha dejado otra vez con dudas, en lo de la maraña de cables tiene razón.

flico: podrías explicar muy brevemenete qué es eso de "pushpull activo"?

En el datasheet aparecen dos formas de conectar:

  1. Supplying the Parasite-Powered DS18B20 During Temperature Conversions
  2. Powering the DS18B20 with an External Supply

Cuando mencionas "pushpull activo" te refieres a la segunda?

Supongo que lo que quiere decir es esto:

Parasite power mode
When operating in parasite power mode, only two wires are required: one data wire, and ground. At the master, a 4.7k pull-up resistor must be connected to the 1-wire bus. When the line is in a "high" state, the device pulls current to charge an internal capacitor.

This current is usually very small, but may go as high as 1.5 mA when doing a temperature conversion or writing EEPROM. When a slave device is performing one these operations, the bus master must keep the bus pulled high to provide power until the operation completes; a delay of 750ms is required for a DS18S20 temperature conversion. The master can't do anything during this time, like issuing commands to other devices, or polling for the slave's operation to be completed. To support this, the OneWire library makes it possible to have the bus held high after the data is written.

Cuando hay mucho conectado al 1 wire, se puede emplear en paralelo un mosfet para mandarle la tension directa, sin limite de corriente por los "altos consumos" en los momentos de la lectura como esta nota de aplicacion:

Añado que con el modo tradicional (vcc-gnd-data) no hace falta, solo calcular la resistencia un poco mas baja:
http://datasheets.maximintegrated.com/en/ds/DS18B20.pdf

Normal (external supply) mode
With an external supply, three wires are required: the bus wire, ground, and power. The 4.7k pull-up resistor is still required on the bus wire. As the bus is free for data transfer, the microcontroller can continually poll the state of a device doing a conversion. This way, a conversion request can finish as soon as the device reports being done, as opposed to having to wait 750ms in "parasite" power mode.

Note on resistors:
For larger networks, you can try smaller resistors.
The ATmega328/168 datasheet indicates starting at 1k6 and a number of users have found smaller to work better on larger networks.

Solo es que durante el tiempo de conversión activas el Pin del mosfet. Suele ser como maximo 750ms el tiempo que dura la conversión pero se acorta si bajas la resolución.

Unas pruebas que hice llegue a los 200m leyendo dispositivos onewire de dos hilos y 750ms de pushpull que en modo pasivo no leía nada mas que un dispositivo. Pero claro era en dos hilos.

Gracias de nuevo
resumiendo: si pongo tres cables (vcc-gnd-data) me olvido del mosfet.
Sobre poner resistencia menor, según el datasheet

Note on resistors:
For larger networks, you can try smaller resistors.
The ATmega328/168 datasheet indicates starting at 1k6 and a number of users have found smaller to work better on larger networks.

¿Se supone que debo poner algo entre 1k6 y 4k7? Probaré.

Y ya que sois tan amables, otra pregunta: Cómo calcularía el consumo en mA de una red de 50 DS18B20? Si el consumo fuera continuo usaría un téster, pero cambia según esté midiendo o no cada sensor. Según el datasheet:

  • active current (cuando está leyendo): 1mA
  • standby current: 750nA
  • sink current: 1mA
  • DQ Input Current : 5uA (cuando la línea DQ está alta)

No controlo los dos últimos...

Hola Curro92

Empleando la configuracion de 3 cables, ya lleva alimentacion separada, la resistencia es un simple pullup, casi pogo la mano en el fuego por el valor de 1k5 para las 50.

Si la distancia es grande, 100m p.ej. usa cable cat6.

Por lo demas debe de funcionar sin problemas...

Suerte electro-Apicultor. XD

Gracias, Heke

Estoy probando varios DS18B20 conectados a un Arduino. Uso la librería DallasTemperature

Para saber el número de sensores, utilizo la función correspondiente

devicecount = sensors.getDeviceCount();

Y luego busco el ID de cada sensor para identificarlo

for(n=0;n< devicecount; n++)
      sensors.getAddress(addresses[n], n);

Por otro lado, externamente a los sensores les identifico con unas marcas (con un pintauñas reciclado). Apretando con los dedos los sensores uno a uno, veo en cuál sube la temperatura y puedo asociar el ID y las marcas de pintura.

Mi pregunta es: al usar sensors.getDeviceCount() ¿siempre saldrán en el mismo orden los sensores? O pueden salir en un orden aleatorio?

Hola Curro

Cuando haces un devicecount lo que hace es enumerar los sensores que tiene conectados, el orden no depende de eso.

Cada sensor tiene lo que se llama una mac o para mas sencillo digamos que un DNI, y ese numero es fijo de cada sensor, lo pongas al principio o al final de una hilera.

Es un numero estampado internamente (electronicamente) como si fuera la IP de un ordenador, da igual donde vaya cuando tu accedes al dispositivo X siempre sera a él.

Como bien decis los dispositivos onewire tienen un dni o ROM de 8 bytes.
El primer byte de la ROM define el tipo de dispositivo 0x28 DS18B20 0x10 DS18S20

Te dejo este ejemplo de hacktronics, espero que te sirva

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

// 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, 0x94, 0xE2, 0xDF, 0x02, 0x00, 0x00, 0xFE };
DeviceAddress outsideThermometer = { 0x28, 0x6B, 0xDF, 0xDF, 0x02, 0x00, 0x00, 0xC0 };
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");
}

Gracias, Heke y flico

De acuerdo, no importa el orden en que yo coloque los sensores. Creo que me lié un poco al explicar antes: todavía quedo con la duda, ¿el orden en que sensors.getAddress() me los presenta, ¿siempre es el mismo, o es aleatorio? Si fuera aleatorio, tendría que recoger en el log mac+valor cada vez; si siempre salieran en el mismo orden, sabiendo el orden en que salen, solo anotaría el valor.

He visto que en la librería DallasTemperature (con la que también está hecho el ejemplo que menciona flico) al hacer begin se buscan los devices

while (_wire->search(deviceAddress))
{
    if (validAddress(deviceAddress))
    {
       // ...
        devices++;
    }

Está llamando iterativamente a un _wire->search() que es una función de la librería OneWire , en cuyas fuentes casi me ahogo...

en cuyas fuentes casi me ahogo...

No eres el unico que le ha pasado.

Hola,
sigo intentando establecer el orden de mis sensores: son 10 sensores que van colocados en fila entre los panales de una colmena, de izquierda a derecha. La librería produce una lista de los sensores que detecta.
En más de un lugar he hallado esto:

The order is deterministic. You will always get the same devices in the same order

Como no puedo establecer a partir de su ID el orden en que aparecerán en la lista, voy a hacer esto:

  • conectar los 10 sensores al arduino, sacar la lista de los sensores
  • mientras estoy viendo las temperaturas en la consola, ir calentando uno a uno los sensores (apretando entre dos dedos), y ver cuál de ellos sube la temperatura, y marcarlo con el nº de orden que tiene en la lista.
  • desconectarlos, y volver a conectarlos en el orden que se les ha asignado.
    Así en el log sabré que el primer registro corresponde al primer sensor de la izquierda, y así sucesivamente.

El problema: mi aplicación servirá solo para esos sensores colocados de esa manera. El día que uno se estropee y tenga que cambiarlo, tendría que rehacer todo el proceso de identificación.
La alternativa no me gusta: guardar en el log cada registro de temperatura asociado a su ID (16 caracteres), y luego reordenar los registros según el orden físico de los sensores.

Curro92

Me parece recordar que habia un sketch para identificar la MAC de cada dispositivo conectado...

Si es asi, solo tendrias que antes de sustituir un sensor cambiar en las variables o definiciones del programa su valor, pero la posicion seria la misma.

Me refiero a algo asi:

define sensor 1 = mac... la que sea o numero de orden el que sea..

define sensor 2 = mac... la que sea o numero de orden el que sea..

define sensor 10 = mac... la que sea o numero de orden el que sea..

y en tu programa seguirias leyendo el sensor 1 o 2 o 3 solo que la mac o numero de orden habria cambiado.

Mira a ver si lo encuentras, yo hare lo mismo y si lo veo te lo posteo.

He encontrado de momento estos enlaces que te identifican el adress (yo lo llamo la mac)

http://arduino-info.wikispaces.com/Brick-Temperature-DS18B20#mult
http://tutorialpedia.org/tutorials/Working+with+Dallas+DS18S20+and+DS18B20+temperature+sensors+from+Arduino.html

Aqui el codigo que emplean para identificar el adress:

// This sketch looks for 1-wire devices and
// prints their addresses (serial number) to
// the UART, in a format that is useful in Arduino sketches
// Tutorial: 
// http://www.hacktronics.com/Tutorials/arduino-1-wire-address-finder.html

#include <OneWire.h>

OneWire  ds(3);  // Connect your 1-wire device to pin 3

void setup(void) {
  Serial.begin(9600);
  discoverOneWireDevices();
}

void discoverOneWireDevices(void) {
  byte i;
  byte present = 0;
  byte data[12];
  byte addr[8];
  
  Serial.print("Looking for 1-Wire devices...\n\r");
  while(ds.search(addr)) {
    Serial.print("\n\rFound \'1-Wire\' device with address:\n\r");
    for( i = 0; i < 8; i++) {
      Serial.print("0x");
      if (addr[i] < 16) {
        Serial.print('0');
      }
      Serial.print(addr[i], HEX);
      if (i < 7) {
        Serial.print(", ");
      }
    }
    if ( OneWire::crc8( addr, 7) != addr[7]) {
        Serial.print("CRC is not valid!\n");
        return;
    }
  }
  Serial.print("\n\r\n\rThat's it.\r\n");
  ds.reset_search();
  return;
}

void loop(void) {
  // nothing to see here
}

PD: Upsss..... creo que Flico ya te habia dirigido a hackatronics.... sorry... no lo habia visto.

Hola a todos, yo estoy dandoles vueltas al mismo tema, y he hecho prueba con cuatro sensores ds18b20, y siempre salen en el mismo orden indiferentemente, de como estén conectados.

Looking for 1-Wire devices...


Found '1-Wire' device with address:

0x28, 0x68, 0x29, 0xEA, 0x03, 0x00, 0x00, 0xC1

Found '1-Wire' device with address:

0x28, 0x46, 0x40, 0x1A, 0x04, 0x00, 0x00, 0x8D

Found '1-Wire' device with address:

0x28, 0x5E, 0x78, 0x1A, 0x04, 0x00, 0x00, 0xCD

Found '1-Wire' device with address:

0x28, 0xF1, 0x33, 0xEA, 0x03, 0x00, 0x00, 0x27

That's it.

la verdad es que me tiene un poco despistado, pero su lógica tendrá....

Hola, @leorrr
Yo me hice un programilla que sacaba por serie el address y temperatura de cada sensor repetidamente. Tomando cada vez un sensor entre los dedos, miraba en cuál subía la temperatura y lo identifiqué externamente con el número de orden que le correspondía.
Luego tendrías que montar un array de los address en el orden en que salen, y leer temperturas en addresses[0], addresses[1] etc.

DeviceAddress addresses[] =
{
   { 0x28, 0x68, 0x29, 0xEA, 0x03, 0x00, 0x00, 0xC1 },  // nº 1
   { 0x28, 0x46, 0x40, 0x1A, 0x04, 0x00, 0x00, 0x8D },  // nº 2
   { 0x28, 0x5E, 0x78, 0x1A, 0x04, 0x00, 0x00, 0xCD },  // nº 3
   { 0x28, 0xF1, 0x33, 0xEA, 0x03, 0x00, 0x00, 0x27 }   // nº 4
};

Mirando el foro encontré un link a una pagina de maxin, el creador del bus one-wire que usa el ds18b20, y que te explica el algoritmo de busqueda 1-Wire Search Algorithm | Analog Devices pero la verdad es que a mi me supera, y de todas maneras para mi proyecto no me sirve, el problema que yo veo es que si algún día se avería una sonda, y la cambias, la nueva no ocupara necesariamente la posición que tenia la antigua, y eso implica reasignar las sondas en el codigo, demasiado complicado, como solo tengo pensado usar 6, emplearé las ntc con el multiplexor 4051, así puedo controlar el orden, si se avería alguna solo es cambiar y listo.

Hola, leorrr
tal vez me lié con mi insistencia en el orden, era una forma de identificar los sensores, pero ahora veo más claro que en realidad el orden que salen no tiene importancia, lo que necesitas es asociar cada sensor físico con su address. Luego según el orden que te interese que salgan las lecturas, ordenas los address en el array DeviceAddress addresses[]. Usando el array, el orden de lectura lo estableces tú, sabiendo el número de sensores (devicecount). Yo lo hago así

for(n=0;n< devicecount; n++)
     tempC[n] = sensors.getTempC(addresses[n]);

Cuando falle un sensor, conectas el nuevo al arduino, y averiguas su address (con el programilla que muestra en address por consola) y colocas esa dirección en el lugar que te convenga en el array.

Realmente el orden en que salen (según ese algoritmo tan complicado) solo interesaría si no usáramos ese array.
Te animo a que uses DS18B20, se conectan todos a 3 cables, y en la lectura no interviene la resistencia de los conductores.

Si el funcionamiento de la ds18b20, lo tengo claro, de hecho dispongo de 5 de ellas, 2 waterprof, y 3 mas de los normales, y se que son mas fiables, mas versátiles, he leído que les puedes programar una temperatura de alerta y el chip te avisa cuando llega a esa "temp", etc, pero,pero... para mi es muy importante que en caso de fallo de un sensor, el orden de las sondas no se altere, y que al sustituirla se mantenga el orden físico original, ademas es mucho mas rápido de reparar, con un simple destornillador lo solucionas. con la ds18b20, aparte del destornillador, te hace falta un ordenador y alguien que sepa modificar el código.
Había pensado, incluso, en hacer una especie de menú de configuración para asignar las sondas, pero la memoria del arduino normal tiene sus limites, probablemente con el mega podría hacerlo, pero bueno lo mejor es ir poco a poco, me he propuesto, para el próximo agosto, tener un prototipo manejable..., que se pueda meter en una caja.
Saludos Leo...

Así lo estoy haciendo yo, aunque de momento no uso tantos termómetros como tú, pero el sistema es perfectamente ampliable:
Guardo en eeprom las direcciones de los dallas.
Al leer la configuración miro uno a uno si los dallas existen. Si no, asigno 00000000.
Un menú específico me permite seleccionar un índice de termómetro e ir recorriendo todos los dallas (en caso de sustituir uno) y asignar uno nuevo a ese índice, guardando luego en la eeprom la nueva configuración.

Creo que la dirección de cada dallas eran 8 bytes; tampoco me parece una escabechina de memoria 80 bytes por 10 dallas conectados, por ejemplo; más teniendo en cuenta que para muchos de los comandos necesitas invocar esa dirección, con lo que te ahorras el tener que hacer un getAddress cada vez que quieras llamar a un termómetro determinado.

noter:
Guardo en eeprom las direcciones de los dallas.
Al leer la configuración miro uno a uno si los dallas existen. Si no, asigno 00000000.
Un menú específico me permite seleccionar un índice de termómetro e ir recorriendo todos los dallas (en caso de sustituir uno) y asignar uno nuevo a ese índice, guardando luego en la eeprom la nueva configuración.

Creo que la dirección de cada dallas eran 8 bytes; tampoco me parece una escabechina de memoria 80 bytes por 10 dallas conectados, por ejemplo; más teniendo en cuenta que para muchos de los comandos necesitas invocar esa dirección, con lo que te ahorras el tener que hacer un getAddress cada vez que quieras llamar a un termómetro determinado.

Pues, esta muy bien pensado, con tu sistema, al fallar una sonda puede saber cual y actuar en consecuencia, por cierto, ¿alguien sabe,cuantas ds18b20, se pueden conectar a la vez en modo parásito al arduino?, lo pregunto mas que nada por el consumo de corriente....