Dallas Temperature How to use the "method 2: search()"

Hello Community

I thank you for your Attention,

I would like some help on how to use this method to address the thermometers.

in the "multiple example" of Dallas temperature we have this option to capture the address, but I couldn't find an example of how to use it,

// 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");
// if (!oneWire.search(outsideThermometer)) Serial.println("Unable to find address for outsideThermometer");

The example is right there, just commented out:

// 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");
  if (!oneWire.search(outsideThermometer)) Serial.println("Unable to find address for outsideThermometer");

Method 2 (search()) is used inside the 'getAddress()' function. It also checks the CRC to make sure the address is valid before 'true' is returned.

1 Like

Hello Mr. John, how are you?

My Name is Eduardo, I'm from Brazil and Thanks for the answer!
I am a programming enthusiast and I am learning independently.

Yes, I had already done it as in the example, but I would like the address of the thermometer to be fixed in the position where I inserted it on the bus. For example, I have 4 thermometers, I want to insert them in a sequence and I want them to have the same address for the same position, but even with this method 2 , they are in decreasing order according to the address, that is, out of order.

I made this Jig to test some heating elements that I created with the Ds18b20

What I would like to do and I can't is get the address in the sequence that I insert the heating elements on the bus, always in the same sequence, No need to adjust via software or change their positions

What you really want is far from clear, but the Hacktronics address finder tutorial, a pencil, and some sticky labels will probably fix it. The "by index" method reads sensors in address order.
Working by predetermined name is just as effective and usually preferable. Either way, you still have to know which sensor is where.

1 Like

My approach is:
1. I place marks #1, #2, #3, and #4 on the the surfaces of the sensors.
2. I keep sensor #1 on the 1-Wire Bus and remove all other sensors.
3. I collect the address of sensor #1 and permanently marks its 6-byte (48-bit, Fig-1) Serial Number on its surface.

byte addr1[8];  //array to hold 64-bit ROM Code including the SN of sensor #1
ds.reset();
ds.search(addr1); 


Figure-1: 64-bit ROM Code

4. Repeat Step-2 and 3 for other sensors.
5. Now, I know which sensor is located where physically and how much temperature it is showing.

1 Like

Can't you unplug the units and put them in order on the bus that you require?

Tom... :smiley: :+1: :coffee: :australia:

Hello Tom,

Thanks for the answer!

Yes, at the moment that's what I've been doing, but as it will be a test platform, every 10-minute cycle I change all the elements to test the new ones. I need to find a solution that with the program running I will insert the thermometers and the addresses will be saved in the order of connection

Thanks you Tom!

Hello Golam,

Thanks for the answer!

It's very similar to the way I've been doing it at the moment, but my need, as it's a test platform, is to keep replacing the heating elements for the tests, and then every time I need to identify the addresses .

the solution I've been looking for is somehow that with the program running I'm going to connect the thermometers in sequence and the addresses are getting fixed in that position

Thanks you!

Electrically, there's no concept of a position on the bus - all sensors are effectively in the same place. You can run one bus per sensor though and establish a position that way.

1 Like

Hello Wildbill,

Yes, but when the address is assigned in the temperature request, it is possible to read that same sensor, but the library always rearranges the addresses, losing the positions

Hello Nick,

sorry for my bad approach, i'll try from the beginning.

I created these heating elements for a project that is going well...

These heating elements are made with Nickel Chromium, Silicone and the Ds18b20 are flexible heaters.

As production increased, I felt the need to test and as I increased the platform to 8 heating elements and each test cycle takes only 10 minutes, the time spent arranging the thermometers in order is getting long.

for this reason I'm looking for a way to capture the address not within the program's Setup but in the Loop

If you connect them one at a time (power off of course) you can scan the bus for a new address at power up and store it in EEPROM.

Will

uhmm, I hadn't thought of that, it might work!

I will do a test!

Here is my first pass at code to maintain a list of temperature sensors in the order in which they were originally added. If you remove a sensor, that position will be marked inactive and the next sensor added will go in that position. As long as you add an replace sensors one at a time the order of positions should be maintained in EEPROM.

// RULES:
// Re-start the sketch each time you add or remove a single device.

#include <EEPROM.h>
// Include the libraries we need
#include <OneWire.h>
#include <DallasTemperature.h>

// Data wire is plugged into port 2 on the Arduino
#define ONE_WIRE_BUS 2
#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);

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

const uint16_t MaxCount = 20; // Allow room for 20 heaters
struct
{
  uint16_t activeCount;
  uint16_t inactiveCount;
  bool isActive[MaxCount];
  DeviceAddress address[MaxCount];
} AddressList;
uint16_t FullCount;

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

// Find this Deviceddress in the active list
int GetPositionIndexByAddress(DeviceAddress address)
{
  for (uint16_t i = 0; i < FullCount; i++)
  {
    if (AddressList.isActive[i] && AddressList.address[i] == address)
      return i;
  }
  return -1;
}

void DumpAddressList()
{
  Serial.println("AddressList");

  Serial.print("AddressList.activeCount = ");
  Serial.println(AddressList.activeCount);

  Serial.print("AddressList.inactiveCount = ");
  Serial.println(AddressList.inactiveCount);

  Serial.print("FullCount = ");
  Serial.println(FullCount);

  for (uint16_t i = 0; i < FullCount; i++)
  {
    Serial.print("PositionIndex: ");
    Serial.print(i);
    if (AddressList.isActive[i])
      Serial.print("    Active: ");
    else
      Serial.print("  Inactive: ");
    printAddress(AddressList.address[i]);
    Serial.println();
  }
}

void setup()
{
  Serial.begin(115200);
  delay(200);

  EEPROM.get(0, AddressList);

  FullCount = AddressList.activeCount + AddressList.inactiveCount;

  // Check for a valid count
  if (FullCount > MaxCount)
  {
    // Bad count.  Reset the array
    Serial.print("Bad counts: active=");
    Serial.print(AddressList.activeCount);
    Serial.print(" inactive=");
    Serial.print(AddressList.inactiveCount);
    Serial.print(" MaxCount=");
    Serial.println(MaxCount);
    AddressList.activeCount = 0;
    AddressList.inactiveCount = 0;
    FullCount = 0;
  }

  DumpAddressList();

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

  // Find the number of devices on the bus.
  uint16_t newActiveCount = sensors.getDeviceCount();

  // Check for valid counts
  // Are we removing one device?
  if (newActiveCount == AddressList.activeCount - 1 &&
      AddressList.inactiveCount == 0) // Removed one device
  {
    // Removed one device. Find it and mark it as 'inactive'
    for (uint16_t index = 0; index < FullCount; index++)
    {
      if (AddressList.isActive[index])
      {
        float tempC = sensors.getTempC(AddressList.address[index]);
        if (tempC == DEVICE_DISCONNECTED_C)
        {
          AddressList.isActive[index] = false;
          AddressList.inactiveCount++;
          AddressList.activeCount--;
          EEPROM.put(0, AddressList);
          DumpAddressList();
        }
      }
    }
  } // End: Removing one device
  else // Are we adding one device?
    if (newActiveCount == AddressList.activeCount + 1 &&
        AddressList.inactiveCount <= 1)
    {
      // Adding one device.  Find the one that isn't already active

      // Test each of the currently active addresses to see if they are
      // already in the active list
      for (uint16_t bussIndex = 0; bussIndex < newActiveCount; bussIndex++)
      {
        DeviceAddress address;

        if (!sensors.getAddress(address, bussIndex))
        {
          Serial.print("Error: Failed to get address at bussIndex ");
          Serial.println(bussIndex);
          while (1) {}
        }

        int positionIndex = GetPositionIndexByAddress(address);
        if (positionIndex == -1) // Not found in active list
        {
          // Found the address that is newly active.

          if (AddressList.inactiveCount == 0)
          {
            // We have no inactive entry so put the new address at the end of the list
            memcpy (AddressList.address[FullCount], address, sizeof address);
            AddressList.isActive[FullCount] = true;
            AddressList.activeCount++;
            FullCount++;
            EEPROM.put(0, AddressList);
            DumpAddressList();
          }
          else
          {
            // Find a place to put it in the list
            for (uint16_t positionIndex = 0; positionIndex < FullCount; positionIndex++)
            {
              if (!AddressList.isActive[positionIndex])
              {
                // Found the inactive entry
                AddressList.inactiveCount--;

                memcpy (AddressList.address[FullCount], address, sizeof address);
                AddressList.isActive[positionIndex] = true;
                AddressList.activeCount++;
                EEPROM.put(0, AddressList);
                DumpAddressList();
              }
            }
          }
        }
      }
    } // End of adding one device
    else if (newActiveCount == AddressList.activeCount)
    {
      Serial.println("Number of active addresses unchanged.");
      DumpAddressList();
    }
    else
    {
      // Something is wrong!
      Serial.println("Something went wrong.  Either more than one device has");
      Serial.println("been removed or more than one device has been added.");
      DumpAddressList();
      while (1) {}
    }


  // Now you have a list of addresses in order of position

  // Tell each active address to set resolution
  for (uint16_t i = 0; i < FullCount; i++)
  {
    if (AddressList.isActive[i])
      sensors.setResolution(AddressList.address[i], TEMPERATURE_PRECISION);
  }

} // End: setup()


void loop() {}
2 Likes

Mr. John,

I had this result, but I only have 4 sensors connected to the BUS, I will study what may be happening, I understand your logic.

Tankyou for you Attention!

In the future, please copy-and-paste text from Serial Monitor rather than posting screen captures.

It looks like your EEPROM may not have neem cleared before you first ran the sketch. Try running this sketch to clear the EEPROM:

#include <EEPROM.h>

void setup()
{
  for (int i = 0; i < 1024; i++)
    EEPROM[i] = 0xFF;
}

void loop() {}

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.