2

I am writing an Arduino sketch to read temp data from multiple DS18B20 sensors and then write it to serial. The problem is, as I am connecting more sensors, the delay between my temp data is written to a serial increases (like 100ms for 1 sensor and 1s for 4 sensors). Can I somehow improve my sketch to read it faster?

Here is the sketch I am using: (I am using DallasTemperature to simplify it all)

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

#define ONE_WIRE_BUS 10
#define TEMPERATURE_PRECISION 8
#define BAUD_RATE 9600

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

// arrays to hold device addresses
DeviceAddress devices[10];
int devicesFound = 0;

void setup(void)
{
  // start serial port
  Serial.begin(BAUD_RATE);
  //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.");

  devicesFound = sensors.getDeviceCount();  

  // report parasite power requirements
  Serial.print("Parasite power is: "); 
  if (sensors.isParasitePowerMode()) Serial.println("ON");
  else Serial.println("OFF");

  for (int i = 0; i < devicesFound; i++)
    if (!sensors.getAddress(devices[i], i)) 
      Serial.println("Unable to find address for Device" + i); 

  // show the addresses we found on the bus
  for (int i = 0; i < devicesFound; i++)
  {    
    Serial.print("Device " + (String)i + " Address: ");
    printAddress(devices[i]);
    Serial.println();
  }

  for (int i = 0; i < devicesFound; i++)
    sensors.setResolution(devices[i], TEMPERATURE_PRECISION);
}

// 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
String printTemperature(DeviceAddress deviceAddress)
{
  float tempC = sensors.getTempC(deviceAddress);
  if (tempC < 10)
    return "0" + (String)tempC;
  else
    return (String)tempC;
}

// 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)
{ 
  if (devicesFound == 0)
  {
     Serial.println("No devices found.");
     return;
  }

  sensors.requestTemperatures();

  String sent = "";

  // print the device information
  for (int i = 0; i < devicesFound; i++)
  {
    sent += printTemperature(devices[i]);
    if (i != devicesFound - 1)
      sent += " ";    
  }

  Serial.println(sent);
}
3

With 12 bits precision, DS18B20 may take up to 750 ms converting a temp.

Try using async reading, so you don't have to wait for the end of the process.

First you ask for a reading, later your read it

    DallasTemperature sensors(&oneWire);
    ...
    sensors.setWaitForConversion(false);  // makes it async
    sensors.requestTemperatures();
    sensors.setWaitForConversion(true);
    ...
    // Do something else while temp is been reading by the sensor
   ...
   float temp = sensors.getTempCByIndex(0); 
2

I would start by changing this section:

String sent = "";

// print the device information
for (int i = 0; i < devicesFound; i++)
{
  sent += printTemperature(devices[i]);
  if (i != devicesFound - 1)
  sent += " ";    
}

Serial.println(sent);

This section should read and print the temperature directly instead of creating a string. The string handling is a large overhead and it does not allow Serial (UART) to work very much in parallel if the buffer is filled. The printTemperature() function is using a lot of strings (and heap operations).

Otherwise you have done what is possible; 1) reduce the conversion resolution (9-bits is minimum), 2) use single conversion request command to all sensors.

The alternative is to use alarm triggers and only read sensors with alarms.

  • like that pastebin.com/NubeaW4M ? – serge1peshcoff Dec 22 '15 at 21:12
  • What are the results of that? I did some tests and it is possible to issue a conversion request, read and print the results from 48 sensors at 9-bits resolution and 14 sensors at 12-bits resolution (per second). – Mikael Patel Dec 22 '15 at 22:36
  • delay is still the same – serge1peshcoff Dec 22 '15 at 23:37
  • Can you scale it down to a single sensor and measure the conversion request and reading of scratch pad? We need to isolate the issue in the library that you are using. – Mikael Patel Dec 23 '15 at 15:54
  • So, I changed my sketch this way: pastebin.com/7EADdVAu, and it shows that around 110ms has passed while reading one sensor. – serge1peshcoff Dec 24 '15 at 20:48

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.