Netduino Plus 2 Native OneWire Temp Sensor - Page 2 - Netduino Plus 2 (and Netduino Plus 1) - Netduino Forums
   
Netduino home hardware projects downloads community

Jump to content


The Netduino forums have been replaced by new forums at community.wildernesslabs.co. This site has been preserved for archival purposes only and the ability to make new accounts or posts has been turned off.
Photo

Netduino Plus 2 Native OneWire Temp Sensor


  • Please log in to reply
26 replies to this topic

#21 M8in

M8in

    New Member

  • Members
  • Pip
  • 3 posts

Posted 05 January 2013 - 05:10 PM

Hi,

 

i would like to say thanks for this piece of code. I was able to get all my DS1820 running in two hours of work. And I would like to call me an newbie... ;-)

 

Also I would like to contibute a modified Main() which iterates trought all DS1820 found on the bus and displays the read temperature:

static string DS1820ID = "";static float sensorTemp = -99;public static void Main(){    while (true)    {	Array owSensors = owBus0.FindAllDevices().ToArray();	foreach (byte[] s in owSensors)	{	    DS1820ID = ""; 	    foreach (byte b in s) {		//Debug.Print( );		DS1820ID += b.ToString() + " ";	    }	    sensorTemp = GetOneWireTempByByteArray(s);	    Debug.Print(DS1820ID + " => " + sensorTemp + "°F");	}	Thread.Sleep(1000);    }}

Maybe this is usefull for someone....

 

Best regards from Cologne/Germany,

Martin



#22 Ludostes

Ludostes

    New Member

  • Members
  • Pip
  • 2 posts

Posted 07 January 2013 - 04:23 PM

Hi,

I don't know why, but I had to change this line, otherwise I was getting only 85 degC (which is the power-on reset value of the temperature register, which is +85°C)

 

while (owBus0.ReadByte() == 0) ; //wait while busy

into this


 Thread.Sleep(750);

 

 

 

The Temperature Conversion Time is maximum 750miliseconds (for a DS18B20), See also datasheet link
 
And ofcourse you have to add the following reference (Microsoft.SPOT.Hardware.OneWire)
 


#23 iced98lx

iced98lx

    Advanced Member

  • Members
  • PipPipPip
  • 134 posts
  • LocationSouth Dakota

Posted 07 January 2013 - 07:30 PM

Very cool, thank you all for this. Making my DS18B20 easier to use!



#24 Ludostes

Ludostes

    New Member

  • Members
  • Pip
  • 2 posts

Posted 07 January 2013 - 11:01 PM

I made this, now I need some Idea to work with multiple sensors (and different types) <_<

Made it in vb.net, C# should be almost same

 

Imports Microsoft.SPOTImports Microsoft.SPOT.HardwareImports SecretLabs.NETMF.HardwareImports SecretLabs.NETMF.Hardware.NetduinoModule OneWireTemperature    'Public MyTempMeter As TemperatureOneWire.OneWireSensor    Sub Main()        ' write your code here        Dim MyTempMeter = New TemperatureOneWire.OneWireSensor        MyTempMeter.Start()        While True            'do something            Thread.Sleep(1000)            Debug.Print("My temp raw : " & MyTempMeter.Raw.ToString)            Debug.Print("My temp now : " & MyTempMeter.NowCelcius.ToString)            Debug.Print("My temp now : " & MyTempMeter.NowFahr.ToString)            Debug.Print("My temp ave : " & MyTempMeter.AveCelcius.ToString)            Debug.Print("My temp ave : " & MyTempMeter.AveFahr.ToString)            Thread.Sleep(9000)        End While    End SubEnd Module#Region "Class, Temperature measuring with a OneWire (DS18B20)"Namespace TemperatureOneWire    Public Class OneWireSensor        '----------------------------------------------------------------------        'DS18B20 Commands        'http://datasheets.maximintegrated.com/en/ds/DS18B20.pdf        '----------------------------------------------------------------------        Private Enum OneWireCommand As Byte            'ROM commands            SearchROM = &HF0        'Search slave devices            ReadRom = &H33          'Read slave on bus (only when 1 device is connected)            MatchRom = &H55         'Address a specific slave device            SkipRom = &HCC          'Address all slave devices            AlarmSearch = &HEC      'Find devices in alarm            'Function commands (DS18B20)            ConvertTemp = &H44     'initiates single temperature conversion            WriteScratchPad = &H4E 'Write Th, Tl and config in temperature slave RAM register (3 bytes)            ReadScratchPad = &HBE  'Read slave register (9 bytes)            CopyScratchPad = &H48  'Copy Th, Tl and Config in EEPROM            RecallE2 = &HB8        'Copy Th, Tl and Config from EEPROM to RAM register            ReadPwrSuplly = &HB4   'Read power externally powered slave devices         End Enum        '----------------------------------------------------------------------        'DS18B20 Constants        '----------------------------------------------------------------------        Const cnstConversionTime As Integer = 750  '12 bit conversion time        Const cnstSleeptime As Integer = 10000     'Sleep this thread        Const UnknownValue As Integer = &HAAA      'Initial value after power up        Const SignBit As Integer = &H800           'First Sign Mask is defined here        Const Resolution As Single = 0.0625        'Bit resolution this sensor        Private TemperatureThread As Thread = Nothing        Private RawData As Integer        Private HisData(7) As Integer        Public Sub New()            Me.TemperatureThread = New Thread(AddressOf ReadTemperatureOneWireSensor)            Me.TemperatureThread.Priority = ThreadPriority.Lowest        End Sub        Public Sub Start()            TemperatureThread.Start()        End Sub        '----------------------------------------------------------------------        'Main routine to read tempurature for a SINGLE!! connected device        'I/O to SDA PIN        '----------------------------------------------------------------------        Private Sub ReadTemperatureOneWireSensor()            Dim TemperaturePort As New OutputPort(Pins.GPIO_PIN_SDA, False)            Dim OneWireBus As New OneWire(TemperaturePort)            Dim Data(8) As Integer            Dim Counter As Integer            Counter = 0            For item As Integer = 0 To 7                HisData(item) = UnknownValue            Next            Try                Do While True                    OneWireBus.TouchReset()                    OneWireBus.WriteByte(OneWireCommand.SkipRom)     'Read single device only                    OneWireBus.WriteByte(OneWireCommand.ConvertTemp) 'Start temperature reading/conversion                    Thread.Sleep(cnstConversionTime)                    OneWireBus.TouchReset()                    OneWireBus.WriteByte(OneWireCommand.SkipRom)        'Read single device only                    OneWireBus.WriteByte(OneWireCommand.ReadScratchPad) 'Command to read register                    For item As Integer = 0 To 8                        Data(item) = OneWireBus.ReadByte()              'Read data from register                    Next                    If (Data(0) = &HFF) And (Data(1) = &HFF) And (Data(2) = &HFF) Then           'No data receieved, or crap                        RawData = UnknownValue                    Else                        RawData = (Data(0) + (Data(1) << 8))                   'Raw Temperature data                        'RawData = &HFE6F                                       'Test value = -25.0625                        If (RawData And SignBit) = SignBit Then                'Negative value (sign bit is high)                            RawData = (RawData Or &HFFFF0000)                  'Convert to Negative integer (32bit)                        End If                    End If                    'Collect data for average calculation (shift data)                    If Counter < 8 Then Counter += 1                    If Counter > 1 Then                        For item As Integer = Counter - 1 To 1 Step -1                            HisData(item) = HisData(item - 1)                                     'shift data                        Next                    End If                    HisData(0) = RawData                    Thread.Sleep(cnstSleeptime - cnstConversionTime)                Loop            Catch ex As Exception            End Try        End Sub        '----------------------------------------------------------------------        'Convert raw data temperature to Deg Celcius        '----------------------------------------------------------------------        Private Function ConvertTemp(myData As Integer) As Single            If myData = UnknownValue Then                Return 999            Else                Return CSng(myData * Resolution)            End If        End Function        '----------------------------------------------------------------------        'Convert raw temperature to Deg Fahrenheit        '----------------------------------------------------------------------        Private Function ConvertToFahr(myData As Single) As Single            If myData = 999 Then                Return 999            Else                Return myData * 9 / 5 + 32            End If        End Function        '----------------------------------------------------------------------        'Calculate Average tempurature from last 8 readings        '----------------------------------------------------------------------        Private Function CalcAve() As Single            Dim cnt As Integer            Dim total As Single            For item As Integer = 0 To 7                If HisData(item) <> UnknownValue Then                    cnt += 1                    total += ConvertTemp(HisData(item))                End If            Next            If cnt > 0 Then                Return (total / cnt)            Else                Return 999            End If        End Function        '----------------------------------------------------------------------        'Callup raw data        '----------------------------------------------------------------------        Public ReadOnly Property Raw As Integer            Get                Return Me.RawData            End Get        End Property        '----------------------------------------------------------------------        'Last known value in deg C        '----------------------------------------------------------------------        Public ReadOnly Property NowCelcius As Single            Get                Return ConvertTemp(Me.RawData)            End Get        End Property        '----------------------------------------------------------------------        'Last known value in deg F        '----------------------------------------------------------------------        Public ReadOnly Property NowFahr As Single            Get                Return ConvertToFahr(ConvertTemp(Me.RawData))            End Get        End Property        '----------------------------------------------------------------------        'Average value in deg C        '----------------------------------------------------------------------        Public ReadOnly Property AveCelcius As Single            Get                Return CalcAve()            End Get        End Property        '----------------------------------------------------------------------        'Average value in deg F        '----------------------------------------------------------------------        Public ReadOnly Property AveFahr As Single            Get                Return ConvertToFahr(CalcAve())            End Get        End Property    End ClassEnd Namespace#End Region


#25 M8in

M8in

    New Member

  • Members
  • Pip
  • 3 posts

Posted 11 January 2013 - 09:08 AM

Hi,

 

i ran into the same problem, but my solution was to provide +5V to PIN3 of the DS18S20. The delay of 750ms may be only needed when using "parasitic power"...

 

I discovered a similar problem when playing around with a serial DIY Board for a PC, running Linux and digitemp. The solution was also to use extra power on PIN3 or the delay of 750ms...

http://www.m8in.de/2...igenbau-sensor/ (sorry, german ;-) )

 

Regards, Martin

 

Hi,

I don't know why, but I had to change this line, otherwise I was getting only 85 degC (which is the power-on reset value of the temperature register, which is +85°C)

 

while (owBus0.ReadByte() == 0) ; //wait while busy

into this

 

 Thread.Sleep(750);

 

 

The Temperature Conversion Time is maximum 750miliseconds (for a DS18B20), See also datasheet link
 
And ofcourse you have to add the following reference (Microsoft.SPOT.Hardware.OneWire)
 


#26 OZ8ET

OZ8ET

    Advanced Member

  • Members
  • PipPipPip
  • 72 posts
  • LocationHundested, Denmark

Posted 11 January 2013 - 04:14 PM

For reference - her is my OneWire Engine using Netduino Plus 2 and native OneWire. (it may not run without modifications as it is part of my home automation controller.).

The engine runs in a loop and maintain 2 tables - one for DS1820 and one for DS2438 as these are the once i use.

All use of the data from the devices, are retrieved from these tables.

 

I have used a similar module on Netduino Plus (ver.1) but with the use of CW2's implementation of OneWire. This requires the special firmware and is only availalbe on NETMF 4.1.

 

using System;using System.Collections;using System.Threading;using Config;using Microsoft.SPOT;using Microsoft.SPOT.Hardware;namespace EPD{	static class owCommands	{		public const byte SkipRom = 0xCC;		public const byte MatchRom = 0x55;		public const byte Convert1820 = 0x44;		public const byte ReadScratchpad = 0xBE;		public const byte CopyScratchpad = 0x48;		public const byte WriteScratchpad = 0x4E;		public const byte RecallMemory = 0xB8;		public const byte ConvertT = 0x44;		public const byte ConvertV = 0xB4;	}	static class OneWireExtension	{		public static bool isOwAddr(string parm)		{			if (parm.Length != 16) return false;			for (int i = 0; i < 16; i++)			{				bool ishex = (((parm[i] >= '0') & (parm[i] <= '9')) | ((parm[i] >= 'A') & (parm[i] <= 'F')) | ((parm[i] >= 'a') & (parm[i] <= 'f')));				if (!ishex) return false;			}			return true;		}		const string hexChar = "0123456789ABCDEF";		public static string AddrString(this byte[] buf)	//	{ 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF } converts to 'FECDAB8967452301'		{			string s = string.Empty;			for (int i = 0; i < buf.Length; i++) s += buf[buf.Length - i - 1].toHex();			return s;		}		public static byte[] AddrBytes(this string s)	//	'0123456789ABCDEF' converts to { 0xEF, 0xCD, 0xAB, 0x89, 0x67, 0x45, 0x23, 0x01 }		{			int j = s.Length;			byte[] b = new byte[(j + 1) >> 1];			for (int i = 0; i < j; i++)			{				int ir = b.Length - (i >> 1) - 1;				int x = hexChar.IndexOf(s.ToUpper()[i]);				b[ir] = ((i & 1) == 0) ? (byte)(x << 4) : (byte)(b[ir] | (byte)x);			}			return b;		}		public static int inList(this ArrayList ar, string addr)		{			for (int i = 0 ; i< ar.Count; i++)				{ if ((ar[i] as byte[]).AddrString() == addr) return i;  }			return -1;		}		public static string getLocation(string addr)		{			//string place = HttpClient.webGet("http://palsbo.net/getLocation.php?addr=" + addr);			//if (place != "") Ini.setValue(addr, place);			//return place == "" ? Ini.getValue(addr, "(undefined)") : place;			return Ini.getValue(addr, "(undefined)");		}	}	class OneWireEngine : IDisposable	{		static OneWire core;		public static bool Pause = false;		private static bool ready = false;		public OneWireEngine(OutputPort _core)		{			core = new OneWire(_core);			ds1820.dev.Clear();			new Thread(Start).Start();			while (!ready) { Thread.Sleep(200); }			Debug.Print("OneWire Started");		}		public void Dispose() { GC.SuppressFinalize(this); }		public static void Start()		{			while (true)			{				core.TouchReset();				core.TouchByte(owCommands.SkipRom);				core.TouchByte(owCommands.Convert1820);				Thread.Sleep(750);				var devs = core.FindAllDevices();				lock (ds1820.dev) foreach (ds1820.Device d in ds1820.dev) { if (devs.inList(d.Addr) < 0) ds1820.dev.Remove(d); }				lock (ds2438.dev) foreach (ds2438.Device d in ds2438.dev) { if (devs.inList(d.Addr) < 0) ds2438.dev.Remove(d); }				foreach (byte[] _Rom in devs)				{					string addr = _Rom.AddrString();					if (addr.Substring(14) == "10")					{						double Temp = get1820(_Rom);						int index = ds1820.inList(addr);						if (index < 0)						{							string Place = OneWireExtension.getLocation(addr);							ds1820.dev.Add(new ds1820.Device(addr, Temp, Place));						}						else						{							ds1820.setTemp(index, Temp);						}					}					if (addr.Substring(14) == "26")					{						double Temp = 0.0;						double Current = 0.0;						double Volt = 0.0;						int index = ds2438.inList(addr);						if (index < 0)						{							init2438(_Rom);							get2438(_Rom, ref Temp, ref Current, ref Volt);							string Place = OneWireExtension.getLocation(addr);							ds2438.dev.Add(new ds2438.Device(addr, Temp, Current, Volt, Place));						}						else						{							get2438(_Rom, ref Temp, ref Current, ref Volt);							ds2438.setData(index, Temp, Current, Volt);						}					}					ready = true;					Thread.Sleep(2000);				}			}		}		public static void WriteBytes(byte[] data)		{			foreach (byte B in data) { core.TouchByte(B); }		}		public static void ReadBytes(byte[] buf)		{			for (var i = 0; i < buf.Length; i++) buf[i] = (byte)(core.ReadByte());		}		public static void Match(byte[] addr)		{			core.TouchReset();			core.TouchByte(owCommands.MatchRom); //match rom			WriteBytes(addr);		}		private static double get1820(byte[] _Rom)		{			Match(_Rom);			core.WriteByte(owCommands.ReadScratchpad);			byte[] buf = { 255, 255, 255, 255, 255, 255, 255, 255, 255 };			ReadBytes(buf);			return (float)((short)((buf[1] << 8) | buf[0]) >> 1) + (float)(buf[7] - buf[6]) / (float)buf[7] - .25;		}		private static void init2438(byte[] _Rom)		{			const byte IAD = 0x01;			const byte CA = 0x02;			const byte EE = 0x04;			//const byte AD = 0x08;			const byte Page0 = 0x00;			const byte Ctrl = IAD | CA | EE;			var buf = new byte[9];			Match(_Rom);			WriteBytes(new byte[] { owCommands.WriteScratchpad, Page0, Ctrl });			Match(_Rom);			WriteBytes(new byte[] { owCommands.ReadScratchpad, 0x00 });			ReadBytes(buf);			Match(_Rom);			WriteBytes(new byte[] { owCommands.CopyScratchpad, 0x00 });			while (core.ReadByte() != 0xFF) { };		}		private static void get2438(byte[] _Rom, ref double Temp, ref double Current, ref double Volt)		{			var buf = new byte[9];			Match(_Rom);			core.WriteByte(owCommands.ConvertT);			while (core.ReadByte() != 0xFF) { };			Thread.Sleep(10);			Match(_Rom);			core.WriteByte(owCommands.ConvertV);			while (core.ReadByte() != 0xFF) { };			Thread.Sleep(10);			Match(_Rom);			WriteBytes(new byte[] { owCommands.RecallMemory, 0x00 });			Match(_Rom);			WriteBytes(new byte[] { owCommands.ReadScratchpad, 0x00 });			ReadBytes(buf);			Temp = (double)((buf[2] << 8) + (buf[1])) / 256;			Volt = (double)((buf[4] << 8) + (buf[3])) - 224; // / 100;			//Volt = Volt / 1.75672;			Current = (double)((Int16)(buf[6] << 8) | (Int16)buf[5]);		}	}	class ds1820	{		public class Device		{			public string Addr { get; set; }			public string Place { get; set; }			public double Temp { get; set; }			public Device(string addr, double temp, string place = null)			{				Addr = addr;				Temp = temp;				if (place == null) Place = Ini.getValue(Addr, "(undefined)");				else Place = place;			}		}		public static int inList(string addr)		{			for (int i = 0; i< dev.Count; i++) { if ((dev[i] as Device).Addr == addr) return i; }			return -1;		}		public static string Addr(int i) { return (dev[i] as Device).Addr; }		public static string Place(int i) { return (dev[i] as Device).Place; }		public static void Place(int i, string Place) { (dev[i] as Device).Place = Place; }		public static double Temp(int i) { return (dev[i] as Device).Temp; }		public static void setTemp(int index, double Temp) { (dev[index] as Device).Temp = Temp; }		public static ArrayList dev = new ArrayList();		public static int Count { get { return dev.Count; } }		public class InUse		{			static string _InUse;			public static int Index			{				get				{					for (int i = 0; i < dev.Count; i++) { if (Addr(i) == _InUse) return i; }					if (dev.Count > 0) return 0; else return -1;				}			}			public static string Addr			{				get { return Index < 0 ? "" : Addr(Index); }				set				{					_InUse = value.ToUpper();					Ini.setValue("DS1820inUse", _InUse);				}			}		}	}	class ds2438	{		public class Device		{			public string Addr { get; set; }			public string Place { get; set; }			public double Temp { get; set; }			public double Volt { get; set; }			public double Current { get; set; }			public Device(string addr, double temp, double current, double volt, string place = null)			{				Addr = addr;				Temp = temp;				Current = current;				Volt = volt;				if (place == null) Place = Ini.getValue(Addr, "(undefined)");				else Place = place;			}		}		public static int inList(string addr)		{			for (int i = 0; i<dev.Count; i++) { if ((dev[i] as Device).Addr == addr) return i; }			return -1;		}		public static ArrayList dev = new ArrayList();		public static int Count { get { return dev.Count; } }		public static string Addr(int i) { return (dev[i] as Device).Addr; }		public static string Place(int i) { return (dev[i] as Device).Place; }		public static void Place(int i, string Place) { (dev[i] as Device).Place = Place; }		public static double Temp(int i) { return (dev[i] as Device).Temp; }		public static double Current(int i) { return (dev[i] as Device).Current; }		public static double Volt(int i) { return (dev[i] as Device).Volt; }		public static void setData(int index, double Temp, double Current, double Volt) { 			(dev[index] as Device).Temp = Temp; 			(dev[index] as Device).Current = Current; 			(dev[index] as Device).Volt = Volt;		}		public class InUse		{			static string _InUse;			public static int Index			{				get				{					for (int i = 0; i < dev.Count; i++) { if (Addr(i) == _InUse) return i; }					if (dev.Count > 0) return 0; else return -1;				}			}			public static string Addr			{				get { return Index < 0 ? "" : Addr(Index); }				set				{					_InUse = value.ToUpper();					Ini.setValue("DS2438inUse", _InUse);				}			}		}	}}

(this code block display needs to be fixed!!!)

 



#27 Tal Tikotzki

Tal Tikotzki

    Member

  • Members
  • PipPip
  • 10 posts

Posted 20 January 2013 - 02:29 PM

Oh my, I didn't even notice that. In ReadTemps_Delegate, you're creating a timer. Which will then get garbage collected at some point, since its scope is limited to the function. Try creating a static variable for the timer outside of that function, and then instantiate it in that function instead. Chris

Hey Chris,

  Why would should I instantiate a timer inside the thread delegate and not at the main thread?

  Doesn't the timer callback returns in a worker thread every time? 

 

Tal






0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users

home    hardware    projects    downloads    community    where to buy    contact Copyright © 2016 Wilderness Labs Inc.  |  Legal   |   CC BY-SA
This webpage is licensed under a Creative Commons Attribution-ShareAlike License.