Spark Core and DS18B20 Digital Temperature Sensor

A beginner level sample application using Spark Core and Dallas DS18B20 Digital Temperature Sensor. The OneWire source code is taken from this link by @tidwelltimj. I just separated this into two classes OneWire and DS18B20. The sample code publish a variable named tmpinfo with temperature value.

3 Likes

Hi @krvarma

That’s great and I am glad you got it working!

I also wanted to point out that the Spark team is working on building in a one wire library and @Dave posted some preliminary code over here:

So someday all this will be built-in and easier to use! I love my DS18B20’s: they are easy to use and very accurate.

1 Like

And one more thing! You get bonus points for getting the whole int versus int16_t thing correct! Yay negative temperatures!

    // 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];
3 Likes

Thanks @bko, good to know Spark Core team is working on One Wire, waiting for all the good features in next release.

Where I'm from, I don't need negative temperatures. :wink:

2 Likes

Even Celsius? I’m in Texas and we get negative Celsius temps.

Ya got me. We saw roughly -13°C in Tennessee this past winter. I'd rather not think about that again...

Ugh. Rough winter here also, and my DS18B20 ran like a champ! :smiley:

You guys should come to New England where -40 C is -40 F! That is also the magic temperature at which you can spray a cup of water just off the boil and still make ice before it hits the ground!

1 Like

No thank you. Paid my penance up north. You don’t have to shovel heat, much easier on the back. :wink:

Help please. I’ve read the get started, I’ve browsed examples, I’ve read the forums,
and I’ve had programming experience with many languages, but I’m still
lost and very frustrated. I haven’t found a simple reference or tutorial on setting up functions or variables when relating to different files.

I’m trying to read info from the core (temperature) but am still lost on
defining variables or functions so I can read them. I’ve left tinker
in place and that is working but I cannot seem to create or read a
temperature value. Anything I try gives me a list of errors. There should be a value in tmpinfo but it can’t be found via get. I’ve tried setting up other variables and they cannot be read either. I’m sure I’m just missing something simple, but i cannot figure out what and have spent way too much time on this already going around in circles.

Can someone please look at this and help me
understand what is needed and how to read a variable or a function.
https://github.com/MisterNetwork/TinkerSense

I’ve tried http://jflasher.github.io/spark-helper/ ,

followed this https://community.spark.io/t/spark-core-and-ds18b20-digital-temperature-sensor/4446

and this https://community.spark.io/t/reading-spark-variables-with-your-own-html-file/4148/5

I’d also love to find a good tutorial on what definitions need to go where. What is the Setup vs the Loop, and what has to be within or outside of those sections.

Thank you in advance!

Hi @MisterNetwork

I tried you code from github and I got a hard-fault (SOS, one red flash, SOS)–I am not sure what is wrong with the DS18B20 library, but I just cut and pasted in some code I have that uses the OneWire directly and that worked fine. This code does not check the CRCs but the sensor is sitting right on the breadboard next to Spark core.

Your publish/variable string was a bit long (63 character max) so I trimmed it down.

I was able to see both the published event “tmpinfo” and the variable “tempr”.

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

OneWire one = OneWire(D2);
uint8_t rom[8];
uint8_t resp[9];

char szInfo[64];
 
void setup() {
    Spark.variable("tempr", &szInfo, STRING);
    Serial1.begin(9600);    
}
 
void loop() {
  
    // Get the ROM address
    one.reset();
    one.write(0x33);
    one.read_bytes(rom, 8);
    // Get the temp
    one.reset();
    one.write(0x55);
    one.write_bytes(rom,8);
    one.write(0x44);
    delay(10);
    one.reset();
    one.write(0x55);
    one.write_bytes(rom, 8);
    one.write(0xBE);
    one.read_bytes(resp, 9);
    
    byte MSB = resp[1];
    byte LSB = resp[0];
    
    int16_t intTemp = ((MSB << 8) | LSB); //using two's compliment 16-bit
    float celsius =   ((double)intTemp)/16.0;
    float fahrenheit = (( celsius*9.0)/5.0+32.0);
  
    sprintf(szInfo, "T: %2.2f C, %2.2f F", celsius, fahrenheit);
  
 
       Spark.publish("tmpinfo", szInfo);
  
    delay(5000);
}

Hi @bko
Thanks for the reply. I appreciate your time.
I’ve made some progress. Started with just your code and the OneWire.cpp and OneWire.u (That is right I hope.) and I get a response. Yea!
Now, I added application.cpp and application.u for Tinker app. which compiles fine, but no tinker operation, and no functions listed via “spark list” only variable tempr
What might prevent the Tinker app from running now? Do I need to add that in to the loop now?

Hi @MisterNetwork

OK, so I was not sure why you wanted Tinker in there. Tinker is the “default” app that makes proving that the core works right very easy. When you write your own sketch or app, you replace Tinker usually, since you are in full control with your own sketch. You can always get Tinker back by doing a factory reset.

If you want to add to Tinker, then you need to put your code in with the Tinker code and disable pin D2 in Tinker, so would end up with a Tinker + DS18B20 thermometer. That is an usual thing to want to do, but it is certainly possible. You will end up with a hybrid Tinker-like sketch, but it won’t talk to the iOS or Android app for pin D2 or any other pin you dedicate to your code.

You don’t need to include application.h which is the way your code gets access to all the good stuff built-in to the Spark.

1 Like

Hi @bko

This is the first part of the spark journey, so tinker control and web temp is fine for a start. I’ve also got a RaspberryPi512 to try for same project. Pi better for streaming video, which I’ll need to add in, too. I’d like video, but snapshots will do for the Sparks limited resources. 
You might want to block me now - I’m sure you’ll be hearing more from me as time goes on!! :wink:

On the Spark, I’ve got a Shield-Shield and an arduino 4x relay board on it. First task was to be able to control relays and get temp. Tinker controls the relays just fine. Will look to build other apps/interfaces later, but for now just a crude proof-of-concept test.

The tinker app - application.cpp didn’t have anything in the .ino file, so what stops it currently? Does the pin conflict stop it. I thought tinker doesn’t do anything until I request it, so what if I don’t write to D2?
My original code wasn’t creating the variable, but Tinker was running.  I’m still confused. How is control passed or not passed to other .cpp files in an app? Why is the OneWire one = OneWire(D2); statement above the Setup()? Is that the conflict?

And why the heck should I be bothering you with all this - why have I not been able to find some simple format / syntax info so I don’t feel like such an idiot?! Sigh!

Thanks again for your time and help Brian! I really appreciate it.

@bko, @MisterNetwork, the issue could be the szInfo[64], I think we should reduce the array. This was added only for demo purpose. @MisterNetwork cna you try reduce it and try, please note that you to change the sprintf portion and just print the temperature only.

Hi @bko
I got it!!
OK - after some more playing - I think I figured out that there can be only one controlling Loop(), and that would be the first one called. (Do I have this correct?)
Anyway - I Blanked out the .ino moved code to application.cpp, and added “|| pinNumber=2” to all the ifs. Tinker works and I can query the temp sensor. WooHoo! The Arduino Language Reference was a bit of a help.
@krvarma - Thanks for the reply.

2 Likes

Good to know you figured it out, happy exploring @MisterNetwork!

New/Updated TinkerSense
https://github.com/MisterNetwork/TinkerSense

2 Likes

How does your code handle negative numbers? When I used it with negative temps, the sign bit is extended so you have to mask out the extended bits or the value is way off.

Mask your raw value with 0x8FFF and this will then blank out the extended sign bits and leave only the top bit (15) set if there is a negative temp. :slight_smile:

There is also a bug in the 1-wire sample code to read temperature. The following line after the read scratchpad needs to be removed otherwise you lose the LSB of the temperature reading.

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

Remove the last line and then everything works.

1 Like