ESP8266 ESP-12 and the DS18B20 "CRC is not valid!"
Posted: Thu Aug 18, 2016 12:19 am
Hello everyone,
I am working on a project out here in Wichita, Kansas to measure the soil temperature of fields with terminated cover crops versus no cover crop fields. Most times this is referred to as "armored" soil versus bare soil. Armor meaning that the dead cover crop shields the normally bare soil from the sun and absorbs the shock of rain thus reducing heat, run off, and disease. The basic idea of my project is to have several probes placed in the fields that report their temperature readings via wifi to a Raspberry PI that is used as a MQTT broker or by some other by means of logging the results.
The probes are waterproof PVC enclosures used normally for outside electrical wiring for housing with ESP8266 ESP-07s and ESP-12s used as the micro controllers. The temperature sensors I am using are the common waterproof DS18B20 but here is the problem.
The waterproof DS18B20 seems to not like to play with the ESP-07 or ESP-12 very well. However the normal non-waterproof DS18B20 works completely fine. Before I continue let me post the code I have been using.
I have confirmed that is code works fine with an Arduino Nano using both the waterproof and the non-waterproof DS18B20. See below.
It is only when I connect the waterproof DS18B20 to the ESP-07/12 that I get an invalid CRC. Sometimes it works for the first couple loops and I get a reading from the waterproof DS18B20 but then it will eventually return an invalid CRC in a few loops or so. That scenerio I wasn't able to capture in images as I have only seen it a couple times. I have tried putting 700ms delays in the code. I have also tried using different GPIO pins which didn't work any better.
In the image below I have setup a waterproof and a non-waterproof DS18B20 for testing. The non-waterproof will report in just fine and give a reading but once it loops to the waterproof sensor it seems to give a 0.00 value and a 0 CRC. The code then loops seeing no more addresses.
If I try the waterproof DS18B20 all by itself the sensor the first loop will return with CRC is not valid and then loops the no more addresses found until the ESP8266 is restarted.
A different output can result from the exact same setup. This time it returns 0.00 temp and a 0 CRC.
To prove that is has got to be something to do with the waterproof DS19B20 I have also done a test with two non-waterproof DS18B20s and they worked fine.
Anyways guys I am just really banging my head against a wall trying to figure out how to fix this problem as using non-waterproof DS18B20s is not an option. For about 3 weeks now I have been working on this after work everyday but can't seem to get a break. Coming to you guys in hope someone has some experience with this issue or knows what I am doing wrong. Hope this is the right place to post this topic, first post.
I am working on a project out here in Wichita, Kansas to measure the soil temperature of fields with terminated cover crops versus no cover crop fields. Most times this is referred to as "armored" soil versus bare soil. Armor meaning that the dead cover crop shields the normally bare soil from the sun and absorbs the shock of rain thus reducing heat, run off, and disease. The basic idea of my project is to have several probes placed in the fields that report their temperature readings via wifi to a Raspberry PI that is used as a MQTT broker or by some other by means of logging the results.
The probes are waterproof PVC enclosures used normally for outside electrical wiring for housing with ESP8266 ESP-07s and ESP-12s used as the micro controllers. The temperature sensors I am using are the common waterproof DS18B20 but here is the problem.
The waterproof DS18B20 seems to not like to play with the ESP-07 or ESP-12 very well. However the normal non-waterproof DS18B20 works completely fine. Before I continue let me post the code I have been using.
Code: Select all
#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!
// http://milesburton.com/Dallas_Temperature_Control_Library
OneWire ds(5); // on pin 12 (a 4.7K resistor is necessary)
void setup(void) {
Serial.begin(9600);
}
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");
}
I have confirmed that is code works fine with an Arduino Nano using both the waterproof and the non-waterproof DS18B20. See below.
It is only when I connect the waterproof DS18B20 to the ESP-07/12 that I get an invalid CRC. Sometimes it works for the first couple loops and I get a reading from the waterproof DS18B20 but then it will eventually return an invalid CRC in a few loops or so. That scenerio I wasn't able to capture in images as I have only seen it a couple times. I have tried putting 700ms delays in the code. I have also tried using different GPIO pins which didn't work any better.
In the image below I have setup a waterproof and a non-waterproof DS18B20 for testing. The non-waterproof will report in just fine and give a reading but once it loops to the waterproof sensor it seems to give a 0.00 value and a 0 CRC. The code then loops seeing no more addresses.
If I try the waterproof DS18B20 all by itself the sensor the first loop will return with CRC is not valid and then loops the no more addresses found until the ESP8266 is restarted.
A different output can result from the exact same setup. This time it returns 0.00 temp and a 0 CRC.
To prove that is has got to be something to do with the waterproof DS19B20 I have also done a test with two non-waterproof DS18B20s and they worked fine.
Anyways guys I am just really banging my head against a wall trying to figure out how to fix this problem as using non-waterproof DS18B20s is not an option. For about 3 weeks now I have been working on this after work everyday but can't seem to get a break. Coming to you guys in hope someone has some experience with this issue or knows what I am doing wrong. Hope this is the right place to post this topic, first post.