4.2, OneWire and DS18B20

Are you sure you tested it? :wink: Unless you choose “Unknown” sensor family there’s no way it could ever find anything. In OneWireBus.Scan()…

foreach( var f in includeFamilies )
{
	if( addr[0] == (byte)f )
		list.Add(new Device(da));
}

should be…

foreach( var f in includeFamilies )
{
	if( da[0] == (byte)f )                                               <--- In current code addr[] is never assigned to...
		list.Add(new Device(da));
}

Now to figure out why all my readings always come back as “85”.

Do you have the pull up resistor in place?

@ godefroi - After comparing your ReadTemperature() to Eric’s, I determined that you need to add a few lines of code. This got me working. Thanks to you both. godefroi, unfortunately your codeshare page doesn’t have the forum link. So, I couldn’t post the patches there.

        public float ReadTemperature()
        {
            var data = 0L;

            // reset the bus
            m_ow.TouchReset();

            // address the device
            m_ow.WriteByte(Command.MatchROM);
            WriteBytes(m_dev.Address);
            
//  THIS SECTION WAS ADDED.
            m_ow.WriteByte(Command.StartTemperatureConversion);
            while (m_ow.ReadByte() == 0) {}
            m_ow.TouchReset();
            m_ow.WriteByte(Command.MatchROM);
            WriteBytes(m_dev.Address);
//  END ADDED

            // read the data from the sensor
            m_ow.WriteByte(Command.ReadScratchPad);

            // read the two bytes of data
            data = m_ow.ReadByte(); // LSB
            data |= (ushort)(m_ow.ReadByte() << 8); // MSB

            // reset the bus, we don't want more data than that
            m_ow.TouchReset();

            // returns C
            // F would be:  (float)((1.80 * (data / 16.00)) + 32.00);
            return (float)data / 16f;
        }

I’m sure I tested it, but I probably changed some stuff around before posting. Sorry about that.

Ah yes, indeed that was a problem in the current code. addr was left over from the 4.1 version.

It’s always returning 85 because you’re never telling it to convert the temperature, and you’re always reading whatever random values happen to be in the scratchpad memory upon startup. You may want to look at the StartConversion() method. The “fix” you posted below basically turns ReadTemperature() into ConvertAndReadTemperature() (which is fine, but seems sort of redundant).

The correct usage is shown in the usage example.

Ah… I see. It never occurred to me that ReadTemperature() wouldn’t actually return a temperature. :frowning: A small usage example added to Codeshare would be worth a million internets. Why would you ever want to separate the conversion out? Thanks, again!

http://www.tinyclr.com/codeshare/entry/438

Version 1 has a usage example, showing both the convert-then-read and convert-and-read-all-in-one paradigms. I didn’t add a usage example for version 2, because nothing changed.

You’d want to do the one-after-other because doing the conversion can be a LONG process (up to 750ms according to the datasheet), and you might have other useful things to do in that time.

Ah… Sounds like a really good candidate to be converted to an async operation.

It already IS asynchronous, unless you use an extremely narrow definition of “asynchronous”. Personally, I don’t see any reason to mess with IAsyncResult and BeginXXX/EndXXX and leaking handles and everything else that comes with it, because there’s no actual work being done by any user code. Everything is being done on the sensor itself.

I suppose you’re right. I was thinking more along the lines of adding a callback function that would get fired once the conversion is done but on second thought that may be overkill in this situation.

It’s certainly a possibility, but in my use case, at least, I forsaw starting conversion in a bunch of sensors, and then going back later and reading out the temperatures. To have an even or callback fired would either mean doing nothing but having a thread sleep for 750ms and then calling a method, which is a waste, or polling the sensor which would consume a bunch of CPU time and tie up the OneWire bus.

I like the idea of starting a bunch of conversions, figuring out current time / ticks and THREAD.SLEEPing until the expected end of conversion (based on the resolution you have set is how long you should sleep). That makes sense to me, so maybe not to others :slight_smile:

This is making more sense. I haven’t really thought much beyond my little one sensor setup. I can see the advantage of doing the read & translate in separate steps if you have several sensors on the wire.

I connected a DS18B20 to pin 6 of port 7 on my Mountaineer Eth board with NETMF 4.2 QFE2.

My test program uses the “Usage” Example from Version 1 of http://www.tinyclr.com/codeshare/entry/438
with the only modification of the GPIO pin:


using (var op = new OutputPort((Cpu.Pin)70, false))

I found this pin number in the following document: http://www.mountaineer.org/app/download/6083970675/Mountaineer.Netmf.Hardware.pdf

But the line

var devs = ow.FindAllDevices();

throws an exception:

What could I be doing wrong here?

Thanks a lot for your help!

What would that mean? Shouldn’t the OneWire class work with just any GPIO pin?

Thanks!

Sorry, I am just starting with NETMF and am a bit confused right now. So please bear with me…

To put my question another way: How can I use Microsoft.SPOT.Hardware.OneWire on the Mountaineer board? Would I have to build a custom firmware image with the PK?

As the Cerberus does not have on-board Ethernet, I suppose this would mean that Ethernet would not work any more on the Mountaineer?
Would you agree that the “proper” solution would be to create a new firmware using the PK? I might try this with the newly released netmf 4.3…?

Thank you, its really good to find helpful people here!

I just tested that approach, and reading the temperature from OneWire worked!

Now my following question is - with the Cerberus firmware on the Mountaineer board, is there a way to access the additional pins on the Mountaineer? (the Cerberus STM32F407 has only 64 pins, vs. 100 pins on the Mountaineer).

Also, Mountaineer uses the internal Ethernet encoder, whereas Cerberus uses SPI for an external ENC. So to sum it up, I am looking for a firmware suitable for 100-pin STM32F407, supporting internal Ethernet and OneWire.

[ul]Is there any other similar board for which someone already built the firmware?[/ul]
[ul]Should I build everything myself? Start with http://ghielectronics.com/community/codeshare/entry/618 maybe?[/ul]
[ul]Ask Oberon to include OneWire?[/ul]