Last week I’ve spend connecting Dallas temperature sensor DS18B20 to .NET Micro Framework. Unfortunately I did not make it and realize where are the limits of .NET Micro Framework 2.0 in the real-time world. This post will be about lessons learned.
Dallas One-Wire bus
DS18B20 is hight precise temperature sensor with 12 bit accuracy connected to 1-Wire bus. This bus is sometimes referred as One-Wire or simply Dallas. Advantage of 1-Wire is saving of CPU pins because it consumes only one, which at the same time can act as the bus power supply. Some of the 1-Wire devices like DS18B20 support parasite power supply from communication pin. Communication protocol on 1-Wire is quite easy and self-clocked. More about 1-Wire protocol can be read at Maxim Integrated Products pages.
DS18B20 and Micro Framework
Communication with DS18B20 is a simple sequence of two bus resets and 4 bytes send to bus. DS18B20 replies with two bytes representing the current temperature. Complete sequence follows:
- Bus reset
- Skip ROM command 0xCC h
- Convert Temperature 0x44 h
- Wait approx. 750ms to conversion ends
- Bus reset
- Skip ROM command 0xCC h
- Read data 0xBE h
- Read Low and High byte from sensor
When I implemented driver for 1-Wire and DS18B20, I was able to reset the the bus by by setting link to LOW for 480us (us = microseconds). DS18B20 replied with “presence signal” which is link LOW for about 110us. However next communication with DS18B20 was not successful. Low and High byte were both 0xFF h, which really don’t represent temperature in my room :) I was really desperate, because I had no clue of what could be wrong. I’ve tested 3 pieces of SD18B20 and all with the same result.
DS18B20 and PICAXE
Hobby robot builders probably heard about PICAXE micro-controllers, which can be easily programmed in Basic and debugged over serial port. Picaxe Basic has readtemp command already implemented. It reads temperature from DS18B20 connected on selected pin. I’ve connected DS18B20 to PICAXE 18X project board and wrote this simple program.
main: readtemp 1, b1 ' read temperature to b1 debug b1 ' show the temperature pause 10000 ' wait 10 seconds goto main
Since everything worked as expected I decide to debug what’s happening on the 1-Wire bus. Maybe PICAXE using different sequence of command for DS18B20 or different bus timing.
Data link analyzer in C#
What man can do to discover what is happening in electric wire during micro seconds time intervals. Answer is “use data link analyzer”. Since data link analyzer is not common household appliance, I wrote one my self. I used the .NET Micro Framework and Tahoe development board. As you can see in C# source code listing, it is nothing else than InerruptPort event logger. Following figure shows, the circuit for traffic analyzing between PICAXE and DS18B20. Power supply for PICAXE and DS18B20 is done by output pin PA7 on Tahoe development board. Now I can start PICAXE and DS18B20 to communicate, only when I want them to do so. This gives me time to initialize analyzer, then power up the devices and be sure with beginning of the transaction.
Real-time in Micro Framework
When I saw results from analyzer, I’ve started smell a rat - in time periods for signals. For example signal for logic 1 take 11us and reading slot even 2us. It is really fast.
<index>|<state>,<duration in microsec.> 0| True, 15 1| False, 108 ; PICAXE start up 2| True, 76401 ; PICAXE init 3| False, 548 ; Master reset 1-Wire 4| True, 15 5| False, 115 ; DS18B20 Presence signal 6| True, 692 7| False, 82 ; 0 = 0xCC Skip Rom 8| True, 12 9| False, 88 ; 0 10| True, 16 11| False, 15 ; 1 12| True, 96 13| False, 11 ; 1 14| True, 100 15| False, 85 ; 0 16| True, 12 17| False, 89 ; 0 18| True, 15 19| False, 15 ; 1 20| True, 96 21| False, 11 ; 1 22| True, 100
Full listing available here
So I’ve made quick test: How long does it take to Micro Framework to switch from LOW to HIGH on OutputPort? Simple test with simple source code:
OutputPort port = new OutputPort(Meridian.Pins.GPIO14, false); port.Write(false); port.Write(true); port.Dispose();
Such a fast change from LOW to HIGH takes from 62us to 70us. When I realize this, I knew that 1-wire is to fast for .NET Micro Framework 2.0 . Logic 1 on 1-Wire bus is represented by LOW signal from 1-15us. Logic 0 is LOW signal longer then 30us. This is the reason why DS18B20 did not talk to me, because I ‘am not able to send such a short signal with Micro Framework.
Conclusion is that .NET Micro Framework 2.0 is slow for output signals but it’s fast enough for input signals. InterruptPort IS able to catch signals 2us long, but OutputPort IS NOT able to send signals shorter than 70us effectively.
It seems that the best bus for .NET Micro Framework remains the I2C with it’s native support. Since there are a thermometers for I2C like DS1631, my robot has thermo sensor feature saved. In case that no suitable substitute with I2C exists, then there are an I2C to 1-Wire bridges like DS2482-100 or DS2482-800.