Ds18b20 cant get it to work

Trying to get a temperature sensor going. I just want to have it publish the temp periodically so I can get it into my smartthings. I cant get a reading other than null… what am I doing wrong with this code?

// This #include statement was automatically added by the Particle IDE.
#include <DS18B20.h>
#include <math.h>

const int      MAXRETRY          = 4;


DS18B20  ds18b20(D1, true); //Sets Pin D2 for Water Temp Sensor and 
                            // this is the only sensor on bus
char     szInfo[64];
double   celsius;
double   fahrenheit;


void setup() {
  Time.zone(-7);
  Particle.variable("tempHotWater", fahrenheit);
  pinMode(D0, OUTPUT);
  digitalWrite(D0, HIGH);
}

void loop() {
    getTemp();
    publishData();
    delay(60000);
}

void publishData(){
  if(!ds18b20.crcCheck()){      //make sure the value is correct
    return;
  }
  sprintf(szInfo, "%2.2f", fahrenheit);
  Particle.publish("dsTmp", szInfo, PRIVATE);
  }

void getTemp(){
  float _temp;
  int   i = 0;

  do {
    _temp = ds18b20.getTemperature();
  } while (!ds18b20.crcCheck() && MAXRETRY > i++);

  if (i < MAXRETRY) {
    celsius = _temp;
    fahrenheit = ds18b20.convertToFahrenheit(_temp);
    }
  else {
    celsius = fahrenheit = NAN;
    }
  }

How is your wiring done? Do you have a pullup resistor to 3.3V?

And also, is the sensor connected to D1 or D2?

DS18B20 ds18b20(D1, true); //Sets Pin D2 for Water Temp Sensor

D1 since I was looking at the code and not the comments which looks wrong for some reason… This was mainly taken from the example code in the library. I just removed the serial stuff and added cloud publishing… I am using a pull up resistor and 4.8 volts from the VIN pin

Double check the pining of your sensor. If you are using TO-92 package you might have mixed up top and bottom view - happened to me before :wink:

Maybe post a pic of your setup.

Sorry for the crummy pic.

I just used this terminal block. Red goes to vin black goes to a ground pin. And yellow is on d1. The 4.7k pull-up is between vin and d1

I’ve been using the spark-dallas-temperature and onewire libraries with my ds18b20s with great results.

I doubt it’s a software issue.
That red wire just before disappearing into the black insulation looks damaged.

yeah i knicked it. Ill cut it fresh. However this is not the first sesnor I tried on this setup :frowning:

Let me know if you don’t find a mechanical issue as I have working DS18B20 code for you but don’t want to clog up the thread if you are having a problem that is not related to code. :slight_smile:

Peace,
EJ

well I just tried a third temp sensor in my batch of 5 so Im starting to think it isnt hardware?

Then it’s unfortunate to post exactly that picture :wink:

1 Like

I sent it to you in a message

Just to make sure, is this a red or orange ring on your resistor - it look orange on my screen which would mean 47k not 4k7

Also try another pin on the Photon - to be on the safe side.

ahhhh you nailed it man your code gets a temp perfect and it makes sense! Looks like my hardware is squared away after all! And Scruffr its even hard for me to tell in person the colors on these things they arent super cleat but I am reasonably sure it should be the right ones with how the package was labeled and I ordered them years ago specifically for an adriuno uno project with the same temp sensors and ithose have worked perfectly

Glad to hear it :slight_smile: There are some growing pains switching over from Arduino (that’s what I did) but stick with it, it’s worth the effort. Connectivity problems (buying expensive shields) with Arduino, large footprint, and cost is what made me move over to Photon.

Peace,
EJ

3 Likes

agreed everything seems so simple comparatively. I love my photons I now have 5 doing various things. Ive run into a few snags here and there and am learning alot but everyone here has been so helpful and I havent failed at a project yet because someone has been able to come to the rescue on my few snags! Thanks everyone!

3 Likes

Any chance you could share the fixed code?

Here is the code that was sent to me. It works great I have since removed all the serial stuff and added stuff for my own things on my own version but this works. Don’t forget to add the libraries as I don’t think it will work by just pasting the include statements.

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

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

/************************************************************************
This sketch reads the temperature from a 1-Wire device and then publishes
to the Particle cloud. From there, IFTTT can be used to log the date,
time, and temperature to a Google Spreadsheet. Read more in our tutorial
here: http://docs.particle.io/tutorials/topics/maker-kit

This sketch is the same as the example from the OneWire library, but
with the addition of three lines at the end to publish the data to the
cloud.

Use this sketch to read the temperature from 1-Wire devices
you have attached to your Particle device (core, p0, p1, photon, electron)

Temperature is read from: DS18S20, DS18B20, DS1822, DS2438

Expanding on the enumeration process in the address scanner, this example
reads the temperature and outputs it from known device types as it scans.

I/O setup:
These made it easy to just 'plug in' my 18B20 (note that a bare TO-92
sensor may read higher than it should if it's right next to the Photon)

D3 - 1-wire ground, or just use regular pin and comment out below.
D4 - 1-wire signal, 2K-10K resistor to D5 (3v3)
D5 - 1-wire power, ditto ground comment.

A pull-up resistor is required on the signal line. The spec calls for a 4.7K.
I have used 1K-10K depending on the bus configuration and what I had out on the
bench. If you are powering the device, they all work. If you are using parisidic
power it gets more picky about the value.
************************************************************************/

OneWire ds = OneWire(D1);  // 1-wire signal on pin D1

unsigned long lastUpdate = 0;

float lastTemp;

void setup() {
  Serial.begin(9600);
  // Set up 'power' pins, comment out if not used!
  // pinMode(D3, OUTPUT);
  // pinMode(D5, OUTPUT);
  // digitalWrite(D3, LOW);
  // digitalWrite(D5, HIGH);
  
}

// up to here, it is the same as the address acanner
// we need a few more variables for this example

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

  // The order is changed a bit in this example
  // first the returned address is printed

  Serial.print("ROM =");
  for( i = 0; i < 8; i++) {
    Serial.write(' ');
    Serial.print(addr[i], HEX);
  }

  // second the CRC is checked, on fail,
  // print error and just return to try again

  if (OneWire::crc8(addr, 7) != addr[7]) {
      Serial.println("CRC is not valid!");
      return;
  }
  Serial.println();

  // we have a good address at this point
  // what kind of chip do we have?
  // we will set a type_s value for known types or just return

  // the first ROM byte indicates which chip
  switch (addr[0]) {
    case 0x10:
      Serial.println("  Chip = DS1820/DS18S20");
      type_s = 1;
      break;
    case 0x28:
      Serial.println("  Chip = DS18B20");
      type_s = 0;
      break;
    case 0x22:
      Serial.println("  Chip = DS1822");
      type_s = 0;
      break;
    case 0x26:
      Serial.println("  Chip = DS2438");
      type_s = 2;
      break;
    default:
      Serial.println("Unknown device type.");
      return;
  }

  // this device has temp so let's read it

  ds.reset();               // first clear the 1-wire bus
  ds.select(addr);          // now select the device we just found
  // ds.write(0x44, 1);     // tell it to start a conversion, with parasite power on at the end
  ds.write(0x44, 0);        // or start conversion in powered mode (bus finishes low)

  // just wait a second while the conversion takes place
  // different chips have different conversion times, check the specs, 1 sec is worse case + 250ms
  // you could also communicate with other devices if you like but you would need
  // to already know their address to select them.

  delay(1000);     // maybe 750ms is enough, maybe not, wait 1 sec for conversion

  // we might do a ds.depower() (parasite) here, but the reset will take care of it.

  // first make sure current values are in the scratch pad

  present = ds.reset();
  ds.select(addr);
  ds.write(0xB8,0);         // Recall Memory 0
  ds.write(0x00,0);         // Recall Memory 0

  // now read the scratch pad

  present = ds.reset();
  ds.select(addr);
  ds.write(0xBE,0);         // Read Scratchpad
  if (type_s == 2) {
    ds.write(0x00,0);       // The DS2438 needs a page# to read
  }

  // transfer and print the values

  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 == 2) raw = (data[2] << 8) | data[1];
  byte cfg = (data[4] & 0x60);

  switch (type_s) {
    case 1:
      raw = raw << 3; // 9 bit resolution default
      if (data[7] == 0x10) {
        // "count remain" gives full 12 bit resolution
        raw = (raw & 0xFFF0) + 12 - data[6];
      }
      celsius = (float)raw * 0.0625;
      break;
    case 0:
      // 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
      if (cfg == 0x20) raw = raw & ~3; // 10 bit res, 187.5 ms
      if (cfg == 0x40) raw = raw & ~1; // 11 bit res, 375 ms
      // default is 12 bit resolution, 750 ms conversion time
      celsius = (float)raw * 0.0625;
      break;

    case 2:
      data[1] = (data[1] >> 3) & 0x1f;
      if (data[2] > 127) {
        celsius = (float)data[2] - ((float)data[1] * .03125);
      }else{
        celsius = (float)data[2] + ((float)data[1] * .03125);
      }
  }

  // remove random errors
  if((((celsius <= 0 && celsius > -1) && lastTemp > 5)) || celsius > 125) {
      celsius = lastTemp;
  }

  fahrenheit = celsius * 1.8 + 32.0;
  lastTemp = celsius;
  Serial.print("  Temperature = ");
  Serial.print(celsius);
  Serial.print(" Celsius, ");
  Serial.print(fahrenheit);
  Serial.println(" Fahrenheit");
  
 /* if(lastTemp < 20) {
      String temperature = String(fahrenheit);
      Particle.publish("The_House_Heater_Is_Broke3171", temperature);
      delay(10000);  // 20 minute delay
  }

if(lastTemp > 30) {
      String temperature = String(fahrenheit);
      Particle.publish("The_House_AC_Is_Broke3171", temperature);
      delay(100000);  // 20 minute delay
  } */

  // now that we have the readings, we can publish them to the cloud
  String temperature = String(fahrenheit); // store temp in "temperature" string
  Particle.publish("Current Temperature", temperature); // publish to cloud
  delay(5000); // 20 minute delay
 
}

Perfect. Thank you! Now off to Frankenstein it for my own uses. :smiley: