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
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.
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);
}
}
}
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…