T4 and DS18B20 not working?

Status
Not open for further replies.

PhilB

Well-known member
I didn't see anything on this in the forum. The T4 seems to not work correctly with the DS18B20 even though the Teensy 2.0 and Teensy LC do. There is a mention in the T4 beta thread that it works so maybe I'm doing something wrong. I did try it on 2 different T4s - both of which run several other large programs correctly. And, I tried several different pins for the sensor with no success.

The same sketches work on a TLC or T2.0 but not on a T4. See the first sketch for a simple program that demos the problem. The second sketch shows the 1 Wire library finding the DS18B20 on the T4 - reads the signature and correctly IDs it as a DS18B20 - but fails to read the temperature correctly. It looks like it fails to correctly read the scratchpad memory that contains the temperature data.

Neither program is mine. First one is unattributed - found it at https://create.arduino.cc/projecthu...digital-temperature-sensor-and-arduino-9cc806. There are very similar versions all over the internet - I suspect it originated at Dallas Semi. The second one is similarly unattributed.

The hardware used is very simple - DS18B20, 4.7K resistor and a Teensy. Connection is basically from the DS18B20 datasheet, page 7, figure 7. Vdd pin to 5V or 3.3V depending on processor, Gnd connected to Gnd and DQ (yes, that's what the datasheet calls the sensor pin) pulled up to Vdd via a 4.7K resistor and connected to pin 2 or 10 depending on which code.


Code:
/********************************************************************/
// First we include the libraries
#include <OneWire.h> 
#include <DallasTemperature.h>
/********************************************************************/
// Data wire is plugged into pin 2 on the Arduino 
#define ONE_WIRE_BUS 2 
/********************************************************************/
// 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);
/********************************************************************/ 
void setup(void) 
{ 
 // start serial port 
 Serial.begin(9600); 
 Serial.println("Dallas Temperature IC Control Library Demo"); 
 // Start up the library 
 sensors.begin(); 
} 
void loop(void) 
{ 
 // call sensors.requestTemperatures() to issue a global temperature 
 // request to all devices on the bus 
/********************************************************************/
 Serial.print(" Requesting temperatures..."); 
 sensors.requestTemperatures(); // Send the command to get temperature readings 
 Serial.println("DONE"); 
/********************************************************************/
 Serial.print("Temperature is: "); 
 Serial.print(sensors.getTempCByIndex(0)); // Why "byIndex"?  
   // You can have more than one DS18B20 on the same bus.  
   // 0 refers to the first IC on the wire 
   delay(1000); 
}


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!
// http://milesburton.com/Dallas_Temperature_Control_Library

OneWire  ds(10);  // on pin 10 (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");
  while(!Serial.available());
  while(Serial.available())Serial.read();
}
 
As a quick check, I connected a DS18B20 to Teensy 4.0 and run the DS18x20_Temperature example. OneWire definitely does work on Teensy 4.0.

DSC_0762_web.jpg

sc.png

I tested with Arduino 1.8.12 and Teensyduino 1.52-beta2 on Linux 64 bit, Ubuntu 18.04.
 
Both of those sketches worked for me on a T4 with a 4.7k pullup to 3.3V on DQ - once I had wired the DS18B20 properly and changed the code to use a different pin (7).

Pete
 
Yes, I did. That's the "pulled up to Vdd" in the original post. I was using the datasheet terminology, probably confusing. And, it works correctly on a T 2.0 (pulled up to 5V) and a Teensy LC (pulled up to 3.3V). It doesn't work with the T4 with the input (DQ) pulled up to 3.3V.
 
It doesn't work with the T4 with the input (DQ) pulled up to 3.3V.

Maybe something isn't connected correctly? We might be able to help if you could show photos of your wiring.

This absolutely does work with Teensy 4.0 when connected properly, as I hope you can see in the tests I did just now.
 
Took a bunch of fussing to resize the photo. I rebuilt it in a cleaner form, just to make sure I didn't have any SBB or other wiring issues. Still does the same thing. Thought about parasitic power too, don't see it here, though. Output is from the first program above.
ds18B20_DxO.jpg
ds18B20_output.jpg

Here's the T2 setup and the output
ds18b20-T2.jpg
ds18B20_output-T2.jpg
 
Oh, and by the way, the T3.2 behaves the same even though 3.3V, I just can't use it in the SBB because I soldered in all the pin headers. But, I get the same behavior/output as the T2 - it works.
 
Which program are you running? That doesn't look like the OneWire DS18x20_Temperature example.

If you can post the code or point me to the exact file online, I'll give that a try here.
 
It's the first one I posted above but here it is again:
Code:
/********************************************************************/
// First we include the libraries
#include <OneWire.h> 
#include <DallasTemperature.h>
/********************************************************************/
// Data wire is plugged into pin 2 on the Arduino 
#define ONE_WIRE_BUS 2 
/********************************************************************/
// 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);
/********************************************************************/ 
void setup(void) 
{ 
 // start serial port 
 Serial.begin(9600); 
 Serial.println("Dallas Temperature IC Control Library Demo"); 
 // Start up the library 
 sensors.begin(); 
} 
void loop(void) 
{ 
 // call sensors.requestTemperatures() to issue a global temperature 
 // request to all devices on the bus 
/********************************************************************/
 Serial.print(" Requesting temperatures..."); 
 sensors.requestTemperatures(); // Send the command to get temperature readings 
 Serial.println("DONE"); 
/********************************************************************/
 Serial.print("Temperature is: "); 
 Serial.print(sensors.getTempCByIndex(0)); // Why "byIndex"?  
   // You can have more than one DS18B20 on the same bus.  
   // 0 refers to the first IC on the wire 
   delay(1000); 
}
 
I'm running it here on a Teensy 4.0, using the same sensor as the photos on msg#3, but plugged into pin 2.

Seems to be working fine.

sc.png

Try turning on verbose output while compiling in File > Preferences. Then look for the info about the libs used. Here's what it shows for me.

Code:
Using library OneWire at version 2.3.5 in folder: /home/paul/teensy/arduino-1.8.12/hardware/teensy/avr/libraries/OneWire 
Using library DallasTemperature at version 3.7.6 in folder: /home/paul/teensy/sketch/libraries/DallasTemperature

Any chance you're using different versions?
 
Maybe also try a lower value resistor, like 2.2K or 2.7K.

4.7K is definitely working here with a genuine DS18B20. But I've seen reports that a lower value resistor is sometimes needed when using 3.3V. Maybe for (very common) counterfeit DS18B20 sensors?
 
I tried 2.7K and 10K, no change. Is it possible that Mouser is selling counterfeit? I would think they buy direct from Maxim. I broke the seal and started using it yesterday. By the way, this is listed as a DS18B20+. I had assumed that it's a DS18B20 because the Mouser page links to the DS18B20 (no +) datasheet.
ds18B20order.jpg

Both OneWire and DallasTemperature were installed via the Arduino Library Manager. Your question made me think that might be the problem. I moved the arduino/libraries version and forced a recompile with the one in the Arduino install. Sigh - same behavior. Not sure why it prints as "OneWir e", it looks right on the verbose output.
Multiple libraries were found for "OneWire.h"
Used: C:\Program Files (x86)\Arduino\hardware\teensy\avr\libraries\OneWire
Not used: D:\Documents\Arduino\libraries\xxxOneWire
Using library OneWire at version 2.3.5 in folder: C:\Program Files (x86)\Arduino\hardware\teensy\avr\libraries\OneWire
Using library DallasTemperature at version 3.8.0 in folder: D:\Documents\Arduino\libraries\DallasTemperature
"C:\\Program Files (x86)\\Arduino\\hardware\\teensy/../tools/arm/bin/arm-none-eabi-size" -A "C:\\Users\\philba\\AppData\\Local\\Temp\\arduino_build_823/ds18b20-2.ino.elf"
 
Mouser is an authorized distributor. Seems unlikely they'd be selling counterfeits.

I can not explain why that 1 sensor you are using does not work. Your wiring appears to be correct.

I updated DallasTemperature to 3.8.0 and I can confirm it works here, the same as with version 3.7.6.

All I can tell you is DS18B20 definitely does work with Teensy 4.0. I tested 2 different sensors, Pete confirmed it works for him. It was tested last year during the Teenst 4 beta test. Many people have used it since.
 
Thanks for taking a look and spending time on it. It's fortunate that I was just pulling out unused parts for "pandemic locked in" play and don't have a specific project.

I looked closely at the markings - made in week 12 of 2017. Philippines mark on the back. Seems legit.

Got curious and put a logic analyzer on it. Something was pulling the pin low. I could see the library trying to start the device but no response - just a low pin. I believe it should be high when neither side is talking. When I switched to the Teensy 2.0 (and 5V), I think the sensor gave up the ghost and now it's completely dead. It was probably a marginal sensor. Not sure where it got damaged, maybe some mistake I made. But anyway, this case is closed. Thanks again for putting your valuable time into it.
ds18B20 on T4.jpg
 
Status
Not open for further replies.
Back
Top