OneWire library does not work on analog pin, but OnWireHub library does

rtek1000

Member
Hello,

Please check, examples with DS18B20 temperature sensor, and OneWireSearch do not work on pins that have ADC function.

I do not have other One Wire devices, only 4 DS18B20, which on digital pins work properly with the OneWire library.

But another library (OneWireHub) works with these ADC pins.

What do I need to configure for this OneWire library to work with pins that have ADC function, such as Arduino UNO over A0 and A1 (D14 and D15)?

Reference for OneWireHub:
https://github.com/orgua/OneWireHub

Thank you.
 
OneWire does not work:

Code:
//
//    FILE: oneWireSearch.ino
//  AUTHOR: Rob Tillaart
// VERSION: 0.1.02
// PURPOSE: scan for 1-Wire devices + code snippet generator
//    DATE: 2015-june-30
//     URL: http://forum.arduino.cc/index.php?topic=333923
//
// inspired by http://www.hacktronics.com/Tutorials/arduino-1-wire-address-finder.html
//
// Released to the public domain
//
// 0.1.00 initial version
// 0.1.01 first published version
// 0.1.02 small output changes

#include <OneWire.h>

void setup()
{
  Serial.begin(115200);
  Serial.println("//\n// Start oneWireSearch.ino \n//");

  for (uint8_t pin = 2; pin < 15; pin++) // <----------- from 13 to 15
  {
    findDevices(pin);
  }
  Serial.println("\n//\n// End oneWireSearch.ino \n//");
}

void loop()
{
}

uint8_t findDevices(int pin)
{
  OneWire ow(pin);

  uint8_t address[8];
  uint8_t count = 0;


  if (ow.search(address))
  {
    Serial.print("\nuint8_t pin");
    Serial.print(pin, DEC);
    Serial.println("[][8] = {");
    do {
      count++;
      Serial.println("  {");
      for (uint8_t i = 0; i < 8; i++)
      {
        Serial.print("0x");
        if (address[i] < 0x10) Serial.print("0");
        Serial.print(address[i], HEX);
        if (i < 7) Serial.print(", ");
      }
      Serial.println("  },");
    } while (ow.search(address));

    Serial.println("};");
    Serial.print("// nr devices found: ");
    Serial.println(count);
  }

  return count;
}
 
OneWire does not work:

Code:
#include <OneWire.h>

// OneWire DS18S20, DS18B20, DS1822 Temperature Example
//
// http://www.pjrc.com/teensy/td_libs_OneWire.html
//
// The DallasTemperature library can do all this work for you!
// https://github.com/milesburton/Arduino-Temperature-Control-Library

OneWire  ds(A1);  // on pin (a 4.7K resistor is necessary)  // <------------ from 10 to A1

void setup(void) {
  Serial.begin(115200);
}

void loop(void) {
  byte i;
  byte present = 0;
  byte type_s;
  byte data[12];
  byte addr[8];
  float celsius, fahrenheit;
  
  if ( !ds.search(addr)) {
    Serial.println("No more addresses.");
    Serial.println();
    ds.reset_search();
    delay(250);
    return;
  }
  
  Serial.print("ROM =");
  for( i = 0; i < 8; i++) {
    Serial.write(' ');
    Serial.print(addr[i], HEX);
  }

  if (OneWire::crc8(addr, 7) != addr[7]) {
      Serial.println("CRC is not valid!");
      return;
  }
  Serial.println();
 
  // the first ROM byte indicates which chip
  switch (addr[0]) {
    case 0x10:
      Serial.println("  Chip = DS18S20");  // or old DS1820
      type_s = 1;
      break;
    case 0x28:
      Serial.println("  Chip = DS18B20");
      type_s = 0;
      break;
    case 0x22:
      Serial.println("  Chip = DS1822");
      type_s = 0;
      break;
    default:
      Serial.println("Device is not a DS18x20 family device.");
      return;
  } 

  ds.reset();
  ds.select(addr);
  ds.write(0x44, 1);        // start conversion, with parasite power on at the end
  
  delay(1000);     // maybe 750ms is enough, maybe not
  // we might do a ds.depower() here, but the reset will take care of it.
  
  present = ds.reset();
  ds.select(addr);    
  ds.write(0xBE);         // Read Scratchpad

  Serial.print("  Data = ");
  Serial.print(present, HEX);
  Serial.print(" ");
  for ( i = 0; i < 9; i++) {           // we need 9 bytes
    data[i] = ds.read();
    Serial.print(data[i], HEX);
    Serial.print(" ");
  }
  Serial.print(" CRC=");
  Serial.print(OneWire::crc8(data, 8), HEX);
  Serial.println();

  // Convert the data to actual temperature
  // because the result is a 16 bit signed integer, it should
  // be stored to an "int16_t" type, which is always 16 bits
  // even when compiled on a 32 bit processor.
  int16_t raw = (data[1] << 8) | data[0];
  if (type_s) {
    raw = raw << 3; // 9 bit resolution default
    if (data[7] == 0x10) {
      // "count remain" gives full 12 bit resolution
      raw = (raw & 0xFFF0) + 12 - data[6];
    }
  } else {
    byte cfg = (data[4] & 0x60);
    // at lower res, the low bits are undefined, so let's zero them
    if (cfg == 0x00) raw = raw & ~7;  // 9 bit resolution, 93.75 ms
    else if (cfg == 0x20) raw = raw & ~3; // 10 bit res, 187.5 ms
    else if (cfg == 0x40) raw = raw & ~1; // 11 bit res, 375 ms
    //// default is 12 bit resolution, 750 ms conversion time
  }
  celsius = (float)raw / 16.0;
  fahrenheit = celsius * 1.8 + 32.0;
  Serial.print("  Temperature = ");
  Serial.print(celsius);
  Serial.print(" Celsius, ");
  Serial.print(fahrenheit);
  Serial.println(" Fahrenheit");
}
 
OneWire does not work:

Code:
#include <OneWire.h>

// OneWire DS18S20, DS18B20, DS1822 Temperature Example
//
// http://www.pjrc.com/teensy/td_libs_OneWire.html
//
// The DallasTemperature library can do all this work for you!
// https://github.com/milesburton/Arduino-Temperature-Control-Library

OneWire  ds(15);  // on pin (a 4.7K resistor is necessary) // <---------- from 10 to 15

void setup(void) {
  Serial.begin(115200);
}

void loop(void) {
  byte i;
  byte present = 0;
  byte type_s;
  byte data[12];
  byte addr[8];
  float celsius, fahrenheit;
  
  if ( !ds.search(addr)) {
    Serial.println("No more addresses.");
    Serial.println();
    ds.reset_search();
    delay(250);
    return;
  }
  
  Serial.print("ROM =");
  for( i = 0; i < 8; i++) {
    Serial.write(' ');
    Serial.print(addr[i], HEX);
  }

  if (OneWire::crc8(addr, 7) != addr[7]) {
      Serial.println("CRC is not valid!");
      return;
  }
  Serial.println();
 
  // the first ROM byte indicates which chip
  switch (addr[0]) {
    case 0x10:
      Serial.println("  Chip = DS18S20");  // or old DS1820
      type_s = 1;
      break;
    case 0x28:
      Serial.println("  Chip = DS18B20");
      type_s = 0;
      break;
    case 0x22:
      Serial.println("  Chip = DS1822");
      type_s = 0;
      break;
    default:
      Serial.println("Device is not a DS18x20 family device.");
      return;
  } 

  ds.reset();
  ds.select(addr);
  ds.write(0x44, 1);        // start conversion, with parasite power on at the end
  
  delay(1000);     // maybe 750ms is enough, maybe not
  // we might do a ds.depower() here, but the reset will take care of it.
  
  present = ds.reset();
  ds.select(addr);    
  ds.write(0xBE);         // Read Scratchpad

  Serial.print("  Data = ");
  Serial.print(present, HEX);
  Serial.print(" ");
  for ( i = 0; i < 9; i++) {           // we need 9 bytes
    data[i] = ds.read();
    Serial.print(data[i], HEX);
    Serial.print(" ");
  }
  Serial.print(" CRC=");
  Serial.print(OneWire::crc8(data, 8), HEX);
  Serial.println();

  // Convert the data to actual temperature
  // because the result is a 16 bit signed integer, it should
  // be stored to an "int16_t" type, which is always 16 bits
  // even when compiled on a 32 bit processor.
  int16_t raw = (data[1] << 8) | data[0];
  if (type_s) {
    raw = raw << 3; // 9 bit resolution default
    if (data[7] == 0x10) {
      // "count remain" gives full 12 bit resolution
      raw = (raw & 0xFFF0) + 12 - data[6];
    }
  } else {
    byte cfg = (data[4] & 0x60);
    // at lower res, the low bits are undefined, so let's zero them
    if (cfg == 0x00) raw = raw & ~7;  // 9 bit resolution, 93.75 ms
    else if (cfg == 0x20) raw = raw & ~3; // 10 bit res, 187.5 ms
    else if (cfg == 0x40) raw = raw & ~1; // 11 bit res, 375 ms
    //// default is 12 bit resolution, 750 ms conversion time
  }
  celsius = (float)raw / 16.0;
  fahrenheit = celsius * 1.8 + 32.0;
  Serial.print("  Temperature = ");
  Serial.print(celsius);
  Serial.print(" Celsius, ");
  Serial.print(fahrenheit);
  Serial.println(" Fahrenheit");
}
 
OneWireHub works:

Code:
/*
 *    Example-Code that emulates a DS18B20
 *
 *    Tested with:
 *    - https://github.com/PaulStoffregen/OneWire --> DS18x20-Example, atmega328@16MHz as Slave
 *    - DS9490R-Master, atmega328@16MHz and teensy3.2@96MHz as Slave
 */

#include "OneWireHub.h"
#include "DS18B20.h"  // Digital Thermometer, 12bit

constexpr uint8_t pin_led       { 13 };
constexpr uint8_t pin_onewire   { 15 }; // <------------------------ ADC pin

auto hub    = OneWireHub(pin_onewire);

auto ds18b20 = DS18B20(DS18B20::family_code, 0x00, 0x00, 0xB2, 0x18, 0xDA, 0x00); // DS18B20: 9-12bit, -55 -  +85 degC
auto ds18s20 = DS18B20(0x10, 0x00, 0x00, 0xA2, 0x18, 0xDA, 0x00);                 // DS18S20: 9   bit, -55 -  +85 degC
auto ds1822  = DS18B20(0x22, 0x00, 0x00, 0x22, 0x18, 0xDA, 0x00);                 // DS1822:  9-12bit, -55 - +125 degC

bool blinking(void);

void setup()
{
    Serial.begin(115200);
    Serial.println("OneWire-Hub DS18B20 Temperature-Sensor");
    Serial.flush();

    pinMode(pin_led, OUTPUT);

    // Setup OneWire
    hub.attach(ds18b20);
    hub.attach(ds18s20);
    hub.attach(ds1822);

    // Test-Cases: the following code is just to show basic functions, can be removed any time
    Serial.print("Test - set Temperatures to -56 degC (out of range): ");
    ds18b20.setTemperature(int8_t(-56));
    Serial.println(ds18b20.getTemperature());

    Serial.print("Test - set Temperatures to -55 degC: ");
    ds18b20.setTemperature(int8_t(-55));
    ds18s20.setTemperature(int8_t(-55));
    Serial.print(ds18b20.getTemperature());
    Serial.print(", ");
    Serial.println(ds18s20.getTemperature());   // ds18s20 is limited to signed 9bit, so it could behave different

    Serial.print("Test - set Temperatures to 0 degC: ");
    ds18b20.setTemperature(int8_t(0));
    ds18s20.setTemperature(int8_t(0));
    Serial.print(ds18b20.getTemperature());
    Serial.print(", ");
    Serial.println(ds18s20.getTemperature());

    Serial.print("Test - set Temperatures to 21 degC: ");
    const int8_t temperature = 21;
    ds18b20.setTemperature(temperature);
    ds18s20.setTemperature(temperature);
    ds1822.setTemperature(temperature);
    Serial.print(ds18b20.getTemperature());
    Serial.print(", ");
    Serial.println(ds18s20.getTemperature());

    Serial.print("Test - set Temperatures to 85 degC: ");
    ds18b20.setTemperature(int8_t(85));
    ds18s20.setTemperature(int8_t(85));
    Serial.print(ds18b20.getTemperature());
    Serial.print(", ");
    Serial.println(ds18s20.getTemperature());

    Serial.print("Test - set Temperatures to 126 degC (out of range): ");
    ds1822.setTemperature(int8_t(126));
    Serial.println(ds1822.getTemperature());


    Serial.println("config done");
}

void loop()
{
    // following function must be called periodically
    hub.poll();
    // this part is just for debugging (USE_SERIAL_DEBUG in OneWire.h must be enabled for output)
    if (hub.hasError()) hub.printError();

    // Blink triggers the state-change
    if (blinking())
    {
        // Set temp
        static float temperature = 20.0;
        temperature += 0.1;
        if (temperature > 30.0) temperature = 20.0;
        ds18b20.setTemperature(temperature);
        ds18s20.setTemperature(temperature);
        ds1822.setTemperature(temperature);
        Serial.println(temperature);
    }
}

bool blinking(void)
{
    constexpr  uint32_t interval    = 1000;          // interval at which to blink (milliseconds)
    static uint32_t nextMillis  = millis();     // will store next time LED will updated

    if (millis() > nextMillis)
    {
        nextMillis += interval;             // save the next time you blinked the LED
        static uint8_t ledState = LOW;      // ledState used to set the LED
        if (ledState == LOW)    ledState = HIGH;
        else                    ledState = LOW;
        digitalWrite(pin_led, ledState);
        return 1;
    }
    return 0;
}
 
OneWireHub works:

Code:
/*
 *    Example-Code that emulates a DS18B20
 *
 *    Tested with:
 *    - https://github.com/PaulStoffregen/OneWire --> DS18x20-Example, atmega328@16MHz as Slave
 *    - DS9490R-Master, atmega328@16MHz and teensy3.2@96MHz as Slave
 */

#include "OneWireHub.h"
#include "DS18B20.h"  // Digital Thermometer, 12bit

constexpr uint8_t pin_led       { 13 };
constexpr uint8_t pin_onewire   { A1 }; // <-------------------- ADC pin

auto hub    = OneWireHub(pin_onewire);

auto ds18b20 = DS18B20(DS18B20::family_code, 0x00, 0x00, 0xB2, 0x18, 0xDA, 0x00); // DS18B20: 9-12bit, -55 -  +85 degC
auto ds18s20 = DS18B20(0x10, 0x00, 0x00, 0xA2, 0x18, 0xDA, 0x00);                 // DS18S20: 9   bit, -55 -  +85 degC
auto ds1822  = DS18B20(0x22, 0x00, 0x00, 0x22, 0x18, 0xDA, 0x00);                 // DS1822:  9-12bit, -55 - +125 degC

bool blinking(void);

void setup()
{
    Serial.begin(115200);
    Serial.println("OneWire-Hub DS18B20 Temperature-Sensor");
    Serial.flush();

    pinMode(pin_led, OUTPUT);

    // Setup OneWire
    hub.attach(ds18b20);
    hub.attach(ds18s20);
    hub.attach(ds1822);

    // Test-Cases: the following code is just to show basic functions, can be removed any time
    Serial.print("Test - set Temperatures to -56 degC (out of range): ");
    ds18b20.setTemperature(int8_t(-56));
    Serial.println(ds18b20.getTemperature());

    Serial.print("Test - set Temperatures to -55 degC: ");
    ds18b20.setTemperature(int8_t(-55));
    ds18s20.setTemperature(int8_t(-55));
    Serial.print(ds18b20.getTemperature());
    Serial.print(", ");
    Serial.println(ds18s20.getTemperature());   // ds18s20 is limited to signed 9bit, so it could behave different

    Serial.print("Test - set Temperatures to 0 degC: ");
    ds18b20.setTemperature(int8_t(0));
    ds18s20.setTemperature(int8_t(0));
    Serial.print(ds18b20.getTemperature());
    Serial.print(", ");
    Serial.println(ds18s20.getTemperature());

    Serial.print("Test - set Temperatures to 21 degC: ");
    const int8_t temperature = 21;
    ds18b20.setTemperature(temperature);
    ds18s20.setTemperature(temperature);
    ds1822.setTemperature(temperature);
    Serial.print(ds18b20.getTemperature());
    Serial.print(", ");
    Serial.println(ds18s20.getTemperature());

    Serial.print("Test - set Temperatures to 85 degC: ");
    ds18b20.setTemperature(int8_t(85));
    ds18s20.setTemperature(int8_t(85));
    Serial.print(ds18b20.getTemperature());
    Serial.print(", ");
    Serial.println(ds18s20.getTemperature());

    Serial.print("Test - set Temperatures to 126 degC (out of range): ");
    ds1822.setTemperature(int8_t(126));
    Serial.println(ds1822.getTemperature());


    Serial.println("config done");
}

void loop()
{
    // following function must be called periodically
    hub.poll();
    // this part is just for debugging (USE_SERIAL_DEBUG in OneWire.h must be enabled for output)
    if (hub.hasError()) hub.printError();

    // Blink triggers the state-change
    if (blinking())
    {
        // Set temp
        static float temperature = 20.0;
        temperature += 0.1;
        if (temperature > 30.0) temperature = 20.0;
        ds18b20.setTemperature(temperature);
        ds18s20.setTemperature(temperature);
        ds1822.setTemperature(temperature);
        Serial.println(temperature);
    }
}

bool blinking(void)
{
    constexpr  uint32_t interval    = 1000;          // interval at which to blink (milliseconds)
    static uint32_t nextMillis  = millis();     // will store next time LED will updated

    if (millis() > nextMillis)
    {
        nextMillis += interval;             // save the next time you blinked the LED
        static uint8_t ledState = LOW;      // ledState used to set the LED
        if (ledState == LOW)    ledState = HIGH;
        else                    ledState = LOW;
        digitalWrite(pin_led, ledState);
        return 1;
    }
    return 0;
}
 
View attachment 14419

I am using a 1R resistor in Vcc (5V) with the objective to operate as a fusistor and 4k7 in the bus (pull-up to 5V).

Links wires have been redirected to the digital pins, so I can continue my testing.

I am now using pins D7 and D8 instead of A0 and A1.

I know I can operate on only 1 wire, but each DS18B20 sensor is on a pin because I need to read different temperatures, and in the future I do not want to have to reconfigure each sensor that is defective, so I can only change the sensor.

I just want to warn you that something went wrong here when trying to use this library, with the Arduino Pro Mini (with UNO bootloader).

I am reprogramming the ATmega328 via wireless connection to the IDE, with the help of ESP8266 (with esp-link firmware).

Thank you. forum.jpg
 
I tested just now, using Arduino Uno R3 and the code from msg #3 (using "A1" pin). It seems to work properly here.

sc.png

DSC_0189_web.jpg

Perhaps your hardware has a defect?
 
Back
Top