Getting correct address of DS18B20

hi I have tried so many different ways to get correct output, but so far I only get this way works.

void discoverOneWireDevices(void)
{
  byte i;
  byte present = 0;
  byte data[12];
  byte addr[8];

  Serial.print("Looking for 1-Wire devices...\n\r");
  while(device.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");
  device.reset_search();
}

I am trying to understand how this get correct address, but one thing I don’t understand is since the addr[8] doesn’t have anything in there, how’s that possible to find address of device, and it actually works. However when I pass in a type-defined DeviceAddress type. It doesn’t work at all. What happen?

This isn’t looking for a device with a specific ID, it is looking for any devices and telling you which are present on the 1-wire bus.

If this helps, here is code I’ve been using to read one sensor. This is working on both core and photon

// Get the ROM address
    one.reset();
    one.write(0x33);
    one.read_bytes(rom, 8);
// Get the temp
    one.reset();
    one.write(0x55);
    one.write_bytes(rom,8);
    one.write(0x44);
    delay(10);
    one.reset();
    one.write(0x55);
    one.write_bytes(rom, 8);
    one.write(0xBE);
    one.read_bytes(resp, 9);

    byte MSB = resp[1];
    byte LSB = resp[0];

    int16_t intTemp = ((MSB << 8) | LSB); //using two's compliment 16-bit
    float celsius =   ((double)intTemp)/16.0;
    float fahrenheit = (( celsius*9.0)/5.0+27.0);  // was 32

Also - I’m using the the main OneWire Lib for the core, and Particle-OneWire lib from here https://github.com/cdrodriguez/Particle-OneWire for the Photon.

1 Like

hi, I am using multiple DS18B20 library on a project. I always have problem to read out correct count of sensors. For example, I have 5 sensors, but it only reads out 3 values. Does anyone know what the problem is? how should I solve the problem. I know the function, begin( ), counts the number for us. Is there any problem in this function? or any problem in OneWire library?

Search “DS18B20 multi” on this forum

1 Like

I don’t see anyone of them helpful to my project.

How far from the board are the sensors ?
Try adjusting the pullup resistor, in the 1-5k ballpark, 1k may be too low and the recommended 5k is a bit weak.

mikelo,

Be sure that you are using both the Onewire lib and the spark-dallas-temprature (since you are using ds18b20) the latter has some higher level functions like getDeviceCount() that will make things much easier.

It is a bit of a paradox with the ds18b20. You can get the temperature by address or by index (0,1,2 …) but the problem is you can’t ever count on the indexes being the same, and this only happens at setup. What most people do is run code like below to find the addresses then set the values in a variable of DeviceAddress.

Something like this:

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

insideThermometer = { 0x28, 0x1D, 0x39, 0x31, 0x2, 0x0, 0x0, 0xF0 };
outsideThermometer   = { 0x28, 0x3F, 0x1C, 0x31, 0x2, 0x0, 0x0, 0x2 };

(From at the multi example Misternetwork talked about to get the temperature by address.)

I am working on a solution that will store the addresses in EEPROM so if a new devices is added (even during runtime) it’s address will be added to the EEPROM and the location in EEPROM will map to your known devices every time.

// This #include statement was automatically added by the Particle IDE.
#include "spark-dallas-temperature/spark-dallas-temperature.h"

// This #include statement was automatically added by the Particle IDE.
#include "OneWire/OneWire.h"

#define ONE_WIRE_BUS D2
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensor(&oneWire);

//globals
int deviceCount;
DeviceAddress tempDeviceAddress, deviceOne, deviceTwo, deviceThree, deviceFour; // We'll use this variable to store a found device address

//Prototypes
void printAddress(DeviceAddress deviceAddress);



void setup() {
  Serial.begin(9600);
  sensor.begin();

}

void loop() {
    /* Get and display the device count 
     * this will not change if you add or remove sensors once you are in the loop.
     * if you want the count to be dynamic you need to add sensor.begin() to 
     * the loop in addtion to the setup
     */
    deviceCount = sensor.getDeviceCount();
    Serial.print("\nNumber of devices: ");
    Serial.println(deviceCount);
    
    delay(1000);
    
    /* now print the addresses for the count.
     * I am going to store them in the same variable 
     * tempDeviceAddress and just reassign it.  I am getting
     * the address by method1: byindex
     * if you want to store them seperately you need 
     * to pass a variable like deviceOne, deviceTwo ...
     * or use an array
     */
     
     for( int i = 0; i < deviceCount; i++) {
         sensor.getAddress(tempDeviceAddress, i);
         Serial.print("\nthe address for device ");
         Serial.print(i);
         Serial.print(" is: ");
         printAddress(tempDeviceAddress);
         
     }
     
    
    
    delay(5000);

}

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


You can use something like this: sensor.getAddress(deviceOne, 0) to assign the first sensor found to the variable deviceOne of type DeviceAddress

1 Like

for current application I am using is not very far, but from what I have tested for this project is 150ft. total under parasite power mode.

Any good reason you want to use parasitic power? its just one more thing to debug to save 1 wire.

I have a question about the difference between using parasite power mode and normal power mode. Does power mode make the things different?

Parasite power uses the data line to charge a capacitor inside the sensors to do the conversion, so you need to make sure theres a strong enough pullup to provide this power.

Regular power uses an extra wire to provide stable power, ie. ground, power and data.

I know it, but my question is how does different power mode effect the reading result and reading speed. Is there any document points that out?

Hi @mikelo

Here’s a link for you:

Do you have the pull-up FET as they show in the diagrams in this app note? It does not work well will just resistor pull-up. Using parasitic power transfers data more slowly than regular power and that could be your problem. Can you try with regular three wire power, ground and data and make sure that works?

My hardware wiring is good. I use USB’s power for DS18B20’s power, which is 4.7V~4.8V, I have 4.7k as pull-up resistor. I believe there is no need to use FET for pull-up. One thing I don’t understand is, why the code I post above is probably the only way to find out the correct address, and other code doesn’t work, such as.
void printAddress(DeviceAddress deviceAddress)
{
for (uint8_t i = 0; i < 8; i++)
{
if (deviceAddress[i] < 16) Serial.print(“0”);
Serial.print(deviceAddress[i], HEX);
}
}
This code doesn’t output the same address the the code I post on the question. Does any one have solution for this?

You say you have 5 devices on your one-wire bus but you can only see 3 of them. Have you tried connecting them one at time and gathering their addresses so you can check? Perhaps you are seeing the address of the “other” two devices with the different code.

From your response, I still can’t tell if you are using parasitic power or not. If you are, you should change to three wire “real” power until you have the bugs worked out.

I have tried normal and parasite as power supply. The results are the same.

Can you post the two outputs? The address is an array so it has to be printed by element. It may just be a formatting issue.

Would you sell a plug and play solution for REsTful addressing 18b20, AIN and TTL, may be also PWM?
Thanks