Fez Panda II and the 18B20 temp sensor

I have a FEZ Panda II and I’m trying to use a DS18B20 in parasitic mode.
I can read the registers, find the address etc but when I read the temp it is always the default 85C.
I also cannot set the configuration register. I was hoping dropping the precision would make it work since the wait times are much shorter.
I’ve seen the examples of how to make it work but doesn’t for me.

BTW, I’m running with the latest firmware and 4.1
Thanks,
-Kenny

Hi Kenny, welcome to the forums!

The code you linked to doesn’t work in parasitic mode, you can see the line:

[quote]while (ow.ReadByte() == 0) ; // wait while busy
[/quote]
explicitly waits for the busy state to end, but in parasitic mode the device never powers the busy state.

My first suggestion is to switch out of parasitic mode and make sure you can read the device. Parasitic mode is somewhat of a challenge - if you want to implement it, you’ll need to check the datasheet to figure out how to cater for it’s nuances.

Hi Brett,
Thanks for the quick reply.
I get past the while(ow.ReadByte()); I can see the scratch register. The problem is it doesn’t want to read and convert the true temp.
byte 0 = 0x50 and byte 1 = 0x5 for a temp of 0x550 -> 85C which is the default.
I tried non-parasitic but it just get the same 85C
Thanks,
-Kenny

Here’s my sample code that works fine even for multiple devices.

using System;
using System.IO;
using System.Text;
using System.Threading;

using Microsoft.SPOT;
using Microsoft.SPOT.Hardware;
using Microsoft.SPOT.IO;

using GHIElectronics.NETMF.Hardware;
using GHIElectronics.NETMF.IO;
using GHIElectronics.NETMF.FEZ;


namespace Panda_ow_test
{
    public class Program
    {
        public static void Main()
        {
            // Blink board LED

            bool ledState = false;

            OutputPort led = new OutputPort((Cpu.Pin)FEZ_Pin.Digital.LED, ledState);
            const short MaxOWDevices = 20;
            ushort temperature;
            ushort temperature_fraction;

            byte[] ow_readvalue = new byte[9];

            byte[][] OW_List = new byte[MaxOWDevices][];
            char[] OutStr = new char[40];
            short OW_number = 0;

            short i = 0, j = 0;

            // Change this your correct pin!
            OneWire ow = new OneWire((Cpu.Pin)FEZ_Pin.Digital.Di7);

            for (i = 0; i < MaxOWDevices; i++)
            {
                OW_List[i] = new byte[8];
            }

            while (true)
            {
                if (ow.Reset())
                {

                    OW_number = 0;
                    while (ow.Search_GetNextDevice(OW_List[OW_number]))
                        OW_number++;
                    //Debug.Print("Found: " + OW_number + " devices");

                    // Block to set up the register for 12-bit resolution of DS18B20's
                    for (i = 0; i < OW_number; i++)
                    {
                        if (OW_List[i][0] == 40)    // This is the ID for DS18B20's that are in use. Only set them up!
                        {
                            ow.Reset();
                            // First step is to match each ROM, and then set up the register.
                            ow.WriteByte(0x55);     // Match ROM
                            ow.Write(OW_List[i], 0, 8);
                            ow.WriteByte(0x0);
                            ow.WriteByte(0x0);
                            ow.WriteByte(0x7f);     // register value for 12 bit resolution

                        }
                    }

                    // Block to start the temperature conversions
                    for (i = 0; i < OW_number; i++)
                    {
                        if (OW_List[i][0] == 40)                             // This is the ID for DS18B20's that are in use.
                        {
                            ow.Reset();
                            // Match each ROM, and start conversion.
                            ow.WriteByte(0x55);     // Match ROM
                            ow.Write(OW_List[i], 0, 8);
                            ow.WriteByte(0x44);     // Start temperature conversion
                        }
                    }

                    Thread.Sleep(750);
                    for (i = 0; i < OW_number; i++)
                    {
                        if (OW_List[i][0] == 40)                             // This is the ID for DS18B20's that are in use.
                        {
                            ow.Reset();
                            ow.WriteByte(0x55);     // Match ROM
                            ow.Write(OW_List[i], 0, 8);
                            ow.WriteByte(0xBE);     // Read Scratchpad
                            ow.Read(ow_readvalue, 0, 9);
                            temperature = ow_readvalue[0];       // LSB 
                            temperature |= (ushort)(ow_readvalue[1] << 8); // MSB
                            temperature_fraction = (ushort)(temperature & 0x0f);
                            Debug.Print( i + ", " + OW_List[i][7] + ", " + (float)((temperature / 16) + (temperature_fraction * .0625)));
                        }

                    }
                }
                // Sleep for 500 milliseconds
                Thread.Sleep(500);

                // toggle LED state
                ledState = !ledState;
                led.Write(ledState);
            }
        }

    }
}

Thanks Brett.
This code gives me the same results. I still read 85C (default value) in Parasitic mode and 127C in VDD high
I also tried to change the config reg in your code to 9 bit resolution by changing the 0x7f to 0x1F.
I can’t get that to work either.
I’m not sure what is going on.
Thanks,
-Keny

@ kennyd - I remember having this exact same problem a few months back. To be honest, I’m not really sure what I did to get past it but it does work now. My code is here if you want to try it. It’s based on the code of others. The project is for Gadgeteer but I think the driver code is mostly generic.

What is your Vpu? edit: I suspect you don’t have over 3v on the data line when in parasitic mode.
Can you also check your wiring; looking at the flat face going left to right you have GND, Data, and VCC.

I had the same problem with my Arduino project and it turned out that you have to wait 750+ ms after the start conversion command is issued. I see that you have the thread.sleep(750);
Try giving the device more time.

1 Like

@ Geir the lightbulb went on for me - yeah I think you’re right, I think I saw 85C when the conversion hadn’t finished.

From the spec sheet, I figured that out too so I added a sleep. This made it work once.
Brett’s example has a sleep in it as well. It still gives me the default 85C
I’m going to try and get a scope on it and check out the hold times.
Thanks
Kenny

OK, I got it working.
I added in a Thread.Sleep(750) just before the while (ow.ReadByte() == 0) ;
This solved the problem. I added the code below.
Thanks for all the replies.
-Kenny

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

namespace MFConsoleApplication1
{
public class Program
{

    public static void Main()
    {
        
        Cpu.Pin myPin = (Cpu.Pin)FEZ_Pin.Digital.Di48;
        // Change this your correct pin!
        
        byte[] scratchpad = new byte[9];

        OneWire ow = new OneWire(myPin);
        ushort temperature;

        // read every second
       while (true)
        {
            if (ow.Reset())
            { 
                ow.WriteByte(0xCC);     // Skip ROM, we only have one device
                ow.WriteByte(0x44);     // Start temperature conversion

                Thread.Sleep(750);                     // <- ADDED THIS!!!
                // while (ow.ReadByte() == 0) ;   // wait while busy <- COMMENTED THIS OUT
               
                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);
                Thread.Sleep(1000);
            }
            else
            {
                Debug.Print("Device is not detected.");
            }

            Thread.Sleep(1000);
        }
 
    }
}

}

Using code tags will make your post more readable. This can be done in two ways:[ol]
Click the “101010” icon and paste your code between the

 tags or...
Select the code within your post and click the "101010" icon.[/ol]
(Generated by QuickReply)

Thanks Gus.
I also spoke too soon. The code I posted works with a pull up of 1K but fails with 4.7K pull up.
If I set the sleep below 250 I get the default 85C but f I increase it I get 127F (0x7F).
Like I said earlier, I will be putting a scope on it and see what is going on.
Thanks,
-Kenny

Kenny have you checked out the DS18B20 datasheet? From memory it has an explicit section that talks about powering devices and pull up resistor requirements (“DC and AC power requirements” or something). I remember that it needs a strong pullup.

Yes, it’s open on my desktop right now. The diagram shows a 4.7K for the pull up. Funny because thats the one I can’t get working .
I’m still using parasitic mode because I’ve had zero luck with out it.

I just looked at the DS18B20’s that I bought (it’s been a while). I have the D18B20-PAR it seems they are a little different.
The sheet says I need a 4…7K as a DQ pullup and a strong (MOSFET?) pullup on the line as well controlled by the uP. hmmmm…

I’ll keep at it.
Thanks,
-Kenny