Main Site Documentation

DS18B20 temperature sensor one-wire


#1

Hi,
has anyone else got any experience with DS18B20’s or other one-wire devices?

Here’s what I have.

Fez Domino. Di1 connected to DS18B20 data pin on breadboard. Pullup resistor on breadboard from data pin to +3v3 (or +5v, doesn’t matter). +3v3 and GND connected back to Fez relevant headers.

Pseudocode:

OW.reset;
iterate devices into array with OW.search_getnextdevice; debug.print shows correct ID for all.

ow.reset;
ow.write(0x55) to match device ID
ow.write actual device ID
ow.write 0, 0
ow.write 0x7f (register value for 12-bit resolution)

ow.reset
ow.write(0x55) to match device ID
ow.write actual device ID
ow.write 0x44 (convert temp)

Wait_750msec
ow.reset
ow.write 0x55 to match
ow.write actual device ID
ow.write 0xbe (read scratchpad)
2x ow.readbyte and then manipulate for correct temperature.

sleep 10sec and repeat again.


When i have one device connected, my code works as expected. Temperatures read as per ambient temp, put finger on chip and temp goes up, take it off and it goes down.

When I connect two devices though, I get weirdness.

One device will read temperature as expected. A second device will only read 85 deg C, which basically means the conversion did not work. It seems to be related to code, since when i disconnect the “working” DS18B20 from the breadboard, the one showing 85 now reads ambient correctly; plug the other one back in and it reads temperature correct but the other one will now stay on it’s last scratchpad reading until you reset the Fez or the OW network (pull power from it) and then it’ll read 85.

Anyone with thoughts?


#2

Yep, I have a few DS18B20’s kicking around. Here’s my code: http://files.chrisseto.com/8DC IT works just fine on my Domino.


#3

thanks Chris for your code - didn’t actually help though since your code uses SkipROM code 0xCC which according to the datasheet apparently only works with a single slave device on the bus.

I tracked it down - not enough Reset()s. I had missed a reset in the loop to initiate the temperature conversion, so I was writing to the first slave ok, then the subsequent ones were failing since they weren’t waiting for the command.


#4

I’m in the works of making a 1-wire station device. Here is code I wrote to record temperature from a DS18B20 until disconnected. Haven’t tried it yet as I’m working on Thermochron stuff. Let me know if you try it and how it works.

ushort temperature;
            byte[] romid = new byte[8];
            // read every second
            while (ow.Reset())
            {
                ow.WriteByte(0x33);
                ow.Read(romid, 0, 8);
                ow.WriteByte(0x44); // Start temperature conversion
                while (ow.ReadByte() == 0) ; // wait while busy

                ow.Reset();
                ow.WriteByte(0xCC); // skip ROM
                ow.WriteByte(0xBE); // Read Scratchpad
                temperature = ow.ReadByte(); // LSB
                temperature |= (ushort)(ow.ReadByte() << 8); // MSB
                Debug.Print("Temperature: " + temperature / 16);

                string romstr = new string(ToHexString(romid));
                string filename = "\\" + romstr + ".CSV";
                string dtastr = "";
                // SD Card is inserted
                // Create a new storage device

                PersistentStorage sdPS = new PersistentStorage("SD");
                // Mount the file system
                sdPS.MountFileSystem();
                // Assume one storage device is available, access it through NETMF
                string rootDirectory = VolumeInfo.GetVolumes()[0].RootDirectory;
                FileStream FileHandle = new FileStream(rootDirectory + @ filename, FileMode.Append);
                // write the data and close the file
                dtastr = temperature + "," + DateTime.Now.ToString();
                byte[] data = Encoding.UTF8.GetBytes(dtastr);
                try
                {
                    FileHandle.Write(data, 0, data.Length);
                }
                catch (Exception)
                {
                    throw;
                }
                FileHandle.Close();
                sdPS.UnmountFileSystem();
                sdPS.Dispose();

                Thread.Sleep(1000);
            }

#5

Next question (hopefully not too inane - but probably a question for one of the GHI team)

The GHI OneWire library documents the CalculateCRC method, but I can’t seem to get VS to resolve it.
http://ghielectronics.com/downloads/NETMF/Library%20Documentation/html/0a49ec0e-cae5-b68a-8618-d9b74622e12d.htm

So if I can figure that out, how then is it meant to be used? I read a sequence of 9 bytes into an array, that is the 9 bytes returned from a DS18B20. Byte 9 is the CRC. What should I be passing to CalculateCRC?


#6

Thanks Logictechs.

Your algorithm is much the same as Chris’ and the GHI example, in that it’ll work fine for a single device on the bus (the SkipROM 0xCC being the key).

I’ll post my code eventually, but it’s still in a state of flux - until then I wouldn’t see yours as having any issue, it just wouldn’t be able to read and report temps from two devices.


#7

Can you post complete code please? But before posting, clean your code and shrink it down to the bare minimum please.


#8

Brett,

I raised the issue of the CalcCRC where it only produces an 8-bit instead of a 16-bit CRC. Chimp said that they will implement that I believe in a response.

Chimp, were you talking to Brett or me?


#9

We already have 8-bit CRC calculation which is what brett needs, correct? The 16-bit will be added in future but this is not a high priority. CRC16 can still be done in C#


#10

probably 8-bit is all I need. But it looks like my “issue” is more general in nature.

This project may have been started in VC# 2008 with an earlier version of the firmware and GHI NETMF SDK. Right now though, it’s running fine with 4.0.3.0 showing in all versions of the GHI assemblies listed in the right-hand pane.

In my code I have:
OneWire ow = new OneWire((Microsoft.SPOT.Hardware.Cpu.Pin)FEZ_Pin.Digital.Di1);

Intellisense doesn’t list the CRC method at all. Typing ow.r shows the read/readbit/readbyte/reset, but the extent of what i have listed is:
dispose
read
readbit
readbyte
reset
search_getnextdevice
search_isdevicepresent
search_restart
write
writebit
writebyte

(plus things like gettype that are not specific to the onewire class)

Any thoughts on what is not in sync, or what I’m doing wrong?


#11

Hi Brett,

Here is what I needed to add to the project I’m working:

using System;
using System.Text;
using System.Threading;
using Microsoft.SPOT;
using Microsoft.SPOT.Hardware;
using GHIElectronics.NETMF.Hardware;
using GHIElectronics.NETMF.FEZ;
using System.IO;
using Microsoft.SPOT.IO;
using GHIElectronics.NETMF.IO;
using GHIElectronics.NETMF.System;

I did have an issue recently when I upgraded where I needed to ensure the VC Studio was using the correct version of GHI references. Here’s the post about that fix: http://www.tinyclr.com/forum/2/269/


#12

One other thing to mention is I had to make the ow object static so it can work throughout the project.

static Cpu.Pin myPin = (Cpu.Pin)FEZ_Pin.Digital.Di3;
static OneWire ow = new OneWire(myPin);

#13

Brett, I know what is the problem I think :slight_smile:

The method for CRC is static so you need ot call it directly not on a instance.


OneWire ow = new OneWire(....);
OneWire.CalculateCRC(buffer, 0, 10);


#14

yes, you got it !

Mmmm, now to figure out what parameters to be passing for the 8-byte array that I’ve read out (plus a ninth byte, the CRC). I am assuming I need to pass all 8 bytes, and if it doesn’t match the 9th then I have a problem…


#15

Probably yes. It is easy to try :wink:


#16

What’s the latest time frame of implementing the CRC16 calc for 1-wire. I cannot seem to find a version that works correctly.


#17

As far as I know, it is already there!


#18

It’s already here. I believe there was some confusion since it was a static method or something.


#19

Keep in mind that you can read the accumulator to get higher accuracy. You can refer to my page at the Arduino playground for more info (see .5 degree resolution section toward bottom)

http://www.arduino.cc/playground/Learning/OneWire