DS18B20 and DHT testing update


#1

Progress is being made! Finally got some spotty ROM address responses (looping fast so prob not letting the pin float long enough) and seeing the DS assert itself on the OneWire bus. Need to tighten up timing and think the write_bit for conversion is where the problem is as far as a temp response. Will update as I progress and then again when the DHT shows some signs of life.


Compact DHT library
#2

Hey! Any update? Did you get something working with this sensor?


#3

Let me answer that question with another question…how battery intense is USART and can I put those pins in open drain?

The lib and/or the write_bit function acts like it’s in parasitic mode then not then is. Very weird. I can run another test, update github and add the serial out I am seeing if you think you could troubleshoot that way.


#4

Serial is pretty bad on the battery in bluz. I don’t remember the exact numbers, but it basically jumps the current consumption up to about 1mA in sleep mode. This will drain a CR2032 pretty fast.


#5

OK…I will gather up where I am run a few output heavy tests and put everything on GitHub. I bet you or @peekay123 will see something I am missing.


#6

Getting closer. Got a valid response but then when magenta and no more…

Welcome to the bluz serial transverter!
R=28 EC 89 C3 6 0 0 12 Device is a DS18B20 family device.
P=1 58 1 4F 46 7F FF 8 10 F9 CRC=25
Celsisus is: 21.50
Fahrenheit is: 70.70
No more addresses.
No more addresses.
No more addresses.
No more addresses.


#7

@eric another piece to the puzzle but I don’t know the why…if not connected and not in deep sleep (not tested in sleep) something steps on the timing. Maybe the radio?? Any way to shut it down?

Connected I started seeing a lot of successful reads at 4 second intervals (not realistic in my mind for most applications). Maybe a 40% success rate.


#8

Yeah, the radio runs at the highest interrupt priority and can easily squash some other things. This is always an issue with the nrf51 since the user app the radio management run off the same processor.

There are two things you can try. First, you can turn off the radio in setup() by calling BLE.stopAdvertising(). You can look here in the docs: http://docs.bluz.io/reference/ble/. Just make sure you do that before you connect, so maybe turn off the gateway shield. If you can read successfully with this, then you know it is the radio stepping on your timing.

The second is that you can make sure to read from the sensor only when the radio is off. There is a way to register a callback now that will tell you when the radio is active. It is on the same page of the docs. I needed this for the neopixel library. So the callback gets called before the radio turns on/off when advertising or connected.

So what you can do is keep track of the radio state and be sure to only read when the radio is off. Not sure how long it takes to read, but hopefully it is fast enough to fit in between radio events.

Let me know if that helps.


#9

Can you post how you used the register option? I was thinking just setting a bool and thats it and waiting for the timing of the radio and the sample to intersect. I don’t need perfect timing on when it happens as long as it regularly returns good values.


#10

Sure, I used it for neopixels a little differently, but it should work something like this:

int readInterval = 1000, lastTimeRead = 0;
volatile bool sensorRead = false;
int lastSensorValue = -999;

void radioCallbackHandler(bool radio_active) {

if (radio_active == false && millis() > lastTimeRead) {
    lastSensorValue = readSensor();
    sensorRead = true;
    lastTimeRead += readInterval;
}

}

/* executes once at startup */
void setup() {

BLE.registerNotifications(radioCallbackHandler);

}

void loop() {

if (sensor_read)
{
    //do something with the sensor value
    sensorRead = false;
}

}

This is more like pseudo-code, I didn’t try to compile it or make sure it works in any way, but I think it conveys the idea.

Is that helpful? Let me know. I think long term the libraries should be modified for bluz to include this type of functionality, but this should work for now.


#11

Pretty close to what I did actually. Success rate is improving!


#12

OK smart people aka @eric and @peekay123 I am getting rational values but they are failing CRC inspection. Any idea why that would be? If you look at the CRC values are the next two lines after CRC Fail/Success statements.

CRC is done exactly as I did it in the past on Photon…

  for ( i = 0; i < 9; i++) {           // we need 9 bytes
    data[i] = ds.read();
    Serial1.print(data[i], HEX);
    Serial1.print(" ");
  }
  _dataCRC = (OneWire::crc8(data, 8));
  _readCRC = (data[8]);
   R=28 EC 89 C3 6 0 0 12 Device is a DS18B20 family device.
sampleOpen: 1
P=1 FF FF FF FF FF FF FF FF FF CRC Failed: 
201
FF
sampleOpen: 1
Celsisus is: 4095.94
Fahrenheit is: 7404.69
Succesful Reads: 0
Failed Reads: 1
No more addresses.
R=28 EC 89 C3 6 0 0 12 Device is a DS18B20 family device.
sampleOpen: 1
P=1 FF FF FF FF FF FF FF FF FF CRC Failed: 
201
FF
sampleOpen: 1
Celsisus is: 4095.94
Fahrenheit is: 7404.69
Succesful Reads: 0
Failed Reads: 2
No more addresses.
R=28 EC 89 C3 6 0 0 12 Device is a DS18B20 family device.
sampleOpen: 1
P=1 5B 1 4B 46 7F FF 5 14 B5 CRC Failed: 
212
B5
sampleOpen: 1
Celsisus is: 21.69
Fahrenheit is: 71.04
Succesful Reads: 0
Failed Reads: 3
R=28 EC 89 C3 6 0 0 12 Device is a DS18B20 family device.
sampleOpen: 1
P=1 FF FF FF FF FF FF FF FF FF CRC Failed: 
201
FF
sampleOpen: 1
Celsisus is: 4095.94
Fahrenheit is: 7404.69
Succesful Reads: 0
Failed Reads: 4
R=28 EC 89 C3 6 0 0 12 Device is a DS18B20 family device.
sampleOpen: 1
P=1 FF FF FF FF FF FF FF FF FF CRC Failed: 
201
FF
sampleOpen: 1
Celsisus is: 4095.94
Fahrenheit is: 7404.69
Succesful Reads: 0
Failed Reads: 5
R=28 EC 89 C3 6 0 0 12 Device is a DS18B20 family device.
sampleOpen: 1
P=1 5C 1 4B 46 7F FF 4 10 A1 CRC Passed: 
A1
A1
sampleOpen: 1
Celsisus is: 21.75
Fahrenheit is: 71.15
Succesful Reads: 1
Failed Reads: 5
No more addresses.
No more addresses.
No more addresses.
No more addresses.
No more addresses.
R=28 EC 89 C3 6 0 0 12 Device is a DS18B20 family device.
sampleOpen: 1
P=1 5B 1 4F 46 7F FF 5 10 B5 CRC Failed: 
105
B5
sampleOpen: 1
Celsisus is: 21.69
Fahrenheit is: 71.04
Succesful Reads: 1
Failed Reads: 6
No more addresses.
No more addresses.
No more addresses.
R=28 EC 89 C3 6 0 0 12 Device is a DS18B20 family device.
sampleOpen: 0
P=1 DB 1 4B 46 7F FF 5 10 B5 CRC Failed: 
39
B5
sampleOpen: 1
Celsisus is: 29.69
Fahrenheit is: 85.44
Succesful Reads: 1
Failed Reads: 7
No more addresses.
No more addresses.
No more addresses.
No more addresses.
No more addresses.
No more addresses.
No more addresses.
No more addresses.
No more addresses.
No more addresses.
No more addresses.
R=28 EC 89 C3 6 0 0 12 Device is a DS18B20 family device.
sampleOpen: 1
P=1 FF FF FF FF FF FF FF FF FF CRC Failed: 
201
FF
sampleOpen: 1
Celsisus is: 4095.94
Fahrenheit is: 7404.69
Succesful Reads: 1
Failed Reads: 8
No more addresses.
No more addresses.
R=28 EC 89 C3 6 0 0 12 Device is a DS18B20 family device.
sampleOpen: 1
P=1 FF FF FF FF FF FF FF FF FF CRC Failed: 
201
FF
sampleOpen: 1
Celsisus is: 4095.94
Fahrenheit is: 7404.69
Succesful Reads: 1
Failed Reads: 9
No more addresses.
No more addresses.
No more addresses.
No more addresses.
No more addresses.
No more addresses.
R=28 EC 89 C3 6 0 0 12 Device is a DS18B20 family device.
sampleOpen: 1
P=1 7C 1 4B 46 7F FF 4 30 A1 CRC Failed: 
42
A1
sampleOpen: 1
Celsisus is: 23.75
Fahrenheit is: 74.75
Succesful Reads: 1
Failed Reads: 10

#13

@LukeUSMC, which parts are the raw value data? I believe the CRC is a single byte value, right? And from what I can see, you are printing in HEX format so why are there values of 212 and 201 HEX?!


#14

@LukeUSMC any luck figuring this one out? I just got in a shipment from SparkFun and I ordered some of the same sensor, so I can try this out now. I also bought a few other random things just to try, tried to pick different protocols and support to cover a wide range. So hopefully I can flush out some more issues with these different sensors


#15

I’ll send you what I have. Sorry, was a busy week and didn’t get to mess with it much. If you pull the github link I had before you’ll see the commonly used Particle-OneWire lib modified for Bluz. I just couldn’t get reliable temps. Maybe if you try we will know if it is my sensor or the timing still.


#16

Thanks. I am going to be gone most of the weekend, but should be able to give it a shot later on Sunday. Will see if I can reproduce the issue.


#17

I give…still can’t get any kind of reliable success in reading my sensor. Maybe one of you @peekay123 @eric can…


#18

Thanks, I will give this a shot. My bag of sensor goodies arrived from SparkFun so I have one of these now. Will add it to my list and try it out today/this weekend.


#19

Ok, sorry for the delay on this, but I made some progress.

The issue definitely stems from system interrupts. Basically, bluz had one firing once every mSec to update the millis counter but also to do housekeeping stuff like updating the RGB LED and check if we need to send the cloud a keep alive. Having this interrupt run so frequently is one thing that was messing up the OneWire library.

The other is the BLE stack. The BLE interrupts run at the highest priority and we just can’t stop that. It can be planned around, to a degree, by using the notifications function, but even that isn’t fullproof. Your example sketch, for instance, only makes sure the radio is off when you start, but the process of reading can get interrupted at any time.

So for the first, I am scaling back the system interrupt. Instead, it will run 10 times a second. The millis value will get updated directly from the RTC Counter. I was actually planning to do this anyway, this just sort of got me motivated :smile:

As for the second, there isn’t a lot we can do except try for better planning. I will try and play around with it a little more, see if the measurements can be paused right before reading until the radio is off.

Here is what I have found now playing with different modes while reading the sensor:

  • If BLE is off, the sensor will read correctly nearly every single time
  • If BLE is advertising, the sensor will read correctly roughly 80% of the time
  • If the board is connected to the gateway and the Particle cloud, the sensor will read correctly maybe 50% of the time (or even a little less)

In all modes, the first measurement pretty much always fails and sometimes even the first few will fail. It seems sometimes the sensor needs to clear through one or a few to get the right value.

Having never played with this sensor before, I am not sure if this is a decent result or way off the charts horrible. I will have to dig a little more into this, I am curious how long the read time is. Clearly it is very time sensitive and I am wondering if that will be a problem on a system where all the interrupts can’t be controlled.

I did check in changes that produced the above results. I would call them experimental for now, and I absolutely need to go back and fix millis. Right now, the value will roll over in only 4.5 hours since I am using the RTC Counter directly which is only 24 bits. I will use the Overflow event to keep track of overflows which can extend the time it will work. But everything should still work, but please let me know if that isn’t the case.


#20

Awesome! Glad it wasn’t just me doing something stupid. I’ll pull the latest and play around some more. I have company in town for the week but I usually do this stuff early in the am before everyone else is awake. Thanks for digging into this! If we lower the resolution we can cut the time required from 750+micros to 200 or so. Default is 12bit but we can get down to 9bit I think. Sadly I am still learning the bits, bytes of stuff but most people stuff the return into a double or float. How many decimal places would 9bit give us?