Help with OneWire library

I am working on building a temperature sensor system with DS18B20, Wifi module ESP8266 ESP 01S, and Arduino Uno.
I am following a code found online:

/*
 * ESP8266-01 with multiple DS10B20 temperature sensors
 * reads sensors asyncronsly for less blocking time
 * 
 * Use GPIO2 for the sensors, a single 4.7K pullup resisor is needed.
 * 
 */
#include <OneWire.h>

const int nsensors = 1 // const is to define a read-only variable, so never overwrite it. Int is for integer values (we have an integer number of sensors)
byte sensors[][8] = {
   { 0x28, 0xC1, 0x02, 0x64, 0x04, 0x00, 0x00, 0x35 }
}; // here we are defining the variable sensors with 8 bits, and this will be in our case our one sensor
int16_t tempraw[nsensors]; // here we define the raw temperature vector with a size of 16 bits
unsigned long nextprint = 0; // this can only store positive values and 0 -- nextprint will print temperature values 

OneWire  ds(2);  // on pin 2 (a 4.7K pullup is necessary)

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

  Serial.println();
  Serial.println();
}

void loop() 
{
  ds18process(); //call this every loop itteration, the more calls the better.

  if(millis() > nextprint) {
    Serial.print("Temp F: ");
    for(byte j=0; j<nsensors; j++){
      Serial.print(j); Serial.print("=");
      Serial.print(ds18temp(1, tempraw[j])); Serial.print("  ");
    }
    Serial.println();
    nextprint = millis() + 1000; //print once a second
  }
}

/* Process the sensor data in stages.
 * each stage will run quickly. the conversion 
 * delay is done via a millis() based delay.
 * a 5 second wait between reads reduces self
 * heating of the sensors.
 */
void ds18process() {
  static byte stage = 0;
  static unsigned long timeNextStage = 0;
  static byte sensorindex = 100;
  byte i, j;
  byte present = 0;
  byte type_s;
  byte data[12];
  byte addr[8];

  if(stage == 0 && millis() > timeNextStage) {
    if (!ds.search(addr)) {
      //no more, reset search and pause
      ds.reset_search();
      timeNextStage = millis() + 100; //1/10 of a second
      return;
    } else {
      if (OneWire::crc8(addr, 7) != addr[7]) {
        Serial.println("CRC is not valid!");
        return;
      }
      //got one, start stage 1
      stage = 1;
    }
  }
  if(stage==1) {
    Serial.print("ROM =");
    for ( i = 0; i < 8; i++) {
      Serial.write(' ');
      Serial.print(addr[i], HEX);
    }
    //find sensor
    for(j=0; j<nsensors; j++){
      sensorindex = j;
      for(i=0; i<8; i++){
        if(sensors[j][i] != addr[i]) {
          sensorindex = 100;
          break; // stop the i loop
        }
      }
      if (sensorindex < 100) { 
        break; //found it, stop the j loop
      }
    }
    if(sensorindex == 100) {
      Serial.println("  Sensor not found in array");
      stage = 0;
      return;
    }
    Serial.print("  index="); Serial.println(sensorindex);
  
    ds.reset();
    ds.select(sensors[sensorindex]);
    ds.write(0x44, 0);        // start conversion, with parasite power off at the end
    stage = 2; //now wait for stage 2
    timeNextStage = millis() + 1000; //wait 1 seconds for the read
  }
  
  if (stage == 2 && millis() > timeNextStage) {
    // the first ROM byte indicates which chip
    switch (sensors[sensorindex][0]) {
      case 0x10:
        Serial.print("  Chip = DS18S20");  // or old DS1820
        Serial.print("  index="); Serial.println(sensorindex);
        type_s = 1;
        break;
      case 0x28:
        Serial.print("  Chip = DS18B20");
        Serial.print("  index="); Serial.println(sensorindex);
        type_s = 0;
        break;
      case 0x22:
        Serial.print("  Chip = DS1822");
        Serial.print("  index="); Serial.println(sensorindex);
        type_s = 0;
        break;
      default:
        Serial.println("Device is not a DS18x20 family device.");
        stage=0;
        return;
    }
  
    present = ds.reset();
    ds.select(sensors[sensorindex]);
    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.print(" index="); Serial.print(sensorindex);
    Serial.println();
  
    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
    }
    tempraw[sensorindex] = raw;
    stage=0;
  }
}

/* Converts raw temp to Celsius or Fahrenheit
 * scale: 0=celsius, 1=fahrenheit
 * raw: raw temp from sensor
 * 
 * Call at any time to get the last save temperature
 */
float ds18temp(byte scale, int16_t raw) 
{
  switch(scale) {
    case 0: //Celsius
      return (float)raw / 16.0;
      break;
    case 1: //Fahrenheit
      return (float)raw / 16.0 * 1.8 + 32.0;
      break;
    default: //er, wut
      return -255;
  }
}

I am having trouble deciphering how this code works (new to Arduino). I am specifically wondering what the line OneWire ds(2) does, and what this means for the step of my circuit. What do I need to connect to pin 2?

The OneWire library communicates with the DS18B20 sensor. You need to connect the data pin of the sensor, and a 4.7K pullup resistor to pin 2 of the Arduino (as the code is currently configured). Don't forget power and ground connections.

This is a big project for a beginner. We strong recommend that you get each part of the project working and understand it completely before putting the bits together.

Start with just the temperature sensor and the Uno. There are many on line examples to follow.

Thank you, this helps a lot! I will take everything apart and start just with the Arduino and the sensor.

jremington:
Start with just the temperature sensor and the Uno. There are many on line examples to follow.

celiafb:
Thank you, this helps a lot! I will take everything apart and start just with the Arduino and the sensor.

1. Connection diagram (Fig-1) between DS18B20 sensor and UNO.
ds18b20-1z.png
Figure-1:

2. Codes (untested) to acquire temperature signal from DS18B20 and then presenting on Serial Monitor.

//12-bit default resolution; external power supply
#include<OneWire.h>     //The Library which contains ready made functions
OneWire ds(2);       //Classname, objectname, and DPin-2 with which sensor's signal line is connected
byte addr[8];         //to hold 64-bit ROM Codes of sensor (every sensor has unique 64-bit code)
byte data[9];        //buffer to hold 9-byte data coming from DS18B20
float celsius;          //temperature with integer part and fractional part (floating point number)

void setup() 
{
  Serial.begin(9600);
  //---------------------------------------------------------------  
  ds.reset();
  ds.search(addr);  //collect 64-bit ROM code from sensor and save in array named addr[]
}

void loop()
{
  acqTemp();       //acquire temperature and show 0n Serial Monitor
  delay(1000);    //sample temperature at 1-sec interval
}

void acqTemp()
{
 //----------------------------
 ds.reset();       //bring 1-Wire into idle state
 ds.select(addr); //slect sensor with address in this array: addr[]
 ds.write(0x44);    //temperature conversion command
 delay(1000);        //maximum conversion time is about 1000 ms
 //---------------------------

 ds.reset();
 ds.select(addr);  
 ds.write(0xBE);             //Function command to read Scratchpad Memory (9 Bytes)
 ds.read_bytes(data, 9); //data comes from sensor and are saved into buffer data[8]
 //---------------------------------

  int16_t raw = (data[1] << 8) | data[0]; //---data[0] and data[1] contains temperature data 
  celsius = (float)raw / 16.0;  //12-bit resolution
  Serial.println(celsius, 2);     //show temperature on Serial Monitor in this format: xx.xx
}

ds18b20-1z.png

Hi everyone,
I am working on a project for which I need to detect breathing rate through temperature measurements. I am using WiFi module ESP8266 ESP-01S, and Dallas DS18B20 Temperature sensor. I got the sensor to work but it takes too long to change temperature and thus to report temperature changes.
I was wondering if anyone has any idea of what other (smaller) temperature sensor I could use, that would change temperature quickly enough as to detect breathing rate?

Thank you!

Thank you for your help! I got this to work and my sensor is now displaying the temperature it reads. However, it is too slow for my application (reading nasal airflow temperatures) -- any ideas for what other temperature sensors I can use that are not so big and take so long to update temperature?

Try using LM35 (analog type temperature sensor).

Use a thermocouple with a high sensitivity ADC. I don't know if that's fast enough for your application but I guess that's about the speed you can get using more or less cheap sensors.

Topics merged

What about more expensive sensors? I have a few hundred dollars in my budget so money is not an issue. I just want something that will for sure update quickly enough as to detect breathing (so around 1/10th second). Will LM35 do this?
The sensor also needs to be small as it will be taped to the face.

celiafb:
Will LM35 do this?

Don't think so.
The size (thermal mass) of a TO-92 DS18B20 is the same as a TO-92 LM35.

A glass bead thermistor, connected with thin wires, might work.
Or a thin tube, connected to a sensitive (air) pressure sensor.
Leo..