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

#1 nickNetduino

nickNetduino

    Member

  • Members
  • PipPip
  • 12 posts

Posted 11 November 2012 - 11:00 PM

Ok folks, I've spent a day hacking this together but it appears to finally work. However, I was hoping some of the more experienced coders here might be able to critique this code to see what I may have not done very elegantly. Basically what the code should do is check the temperatures of 2 sensors ( DS18B20 ) every 10 seconds and store it in a global variable that may be read by a web client or logged. Thanks much in advance.

Sample Debug Output:

11/11/2012 19:03:25 Temp Inside: 67.8 Temp Outside: 44.4
11/11/2012 19:03:35 Temp Inside: 67.9 Temp Outside: 44.4
11/11/2012 19:03:45 Temp Inside: 67.9 Temp Outside: 44.5
11/11/2012 19:03:55 Temp Inside: 67.9 Temp Outside: 44.5
11/11/2012 19:04:05 Temp Inside: 67.9 Temp Outside: 44.5

public class Program
    {
        static OutputPort led = new OutputPort(Pins.ONBOARD_LED, false);
        static OutputPort owPort0 = new OutputPort(Pins.GPIO_PIN_D0, false);
        static OneWire owBus0 = new OneWire(owPort0);

        static byte[] owSensor1 = new byte[8] { 40, 168, 176, 219, 3, 0, 0, 221 }; //sensor 1 inside building
        static byte[] owSensor2 = new byte[8] { 40, 172, 164, 219, 3, 0, 0, 98 }; //sensor 2 outside building

        static float owSensor1Temp = -99;
        static float owSensor2Temp = -99;
        static DateTime tempReadingTimestamp = DateTime.Now;

        public static void Main()
        {
            //set ip and get time from a time server
            Microsoft.SPOT.Net.NetworkInformation.NetworkInterface ni = Microsoft.SPOT.Net.NetworkInformation.NetworkInterface.GetAllNetworkInterfaces()[0];
            ni.EnableStaticIP("10.10.40.80", "255.255.255.0", "10.10.40.1");
            SetTime();

            //create a web server
            WebServer server = new WebServer(80);
            server.CommandReceived += new WebServer.CommandReceivedHandler(server_CommandReceived);
            server.AllowedCommands.Add(new WebCommand("getTemp", 1));
            server.Start();

            //thread to blink the led every 250ms
            Thread ledBlinkThread = new Thread(BlinkLed_Delegate);
            ledBlinkThread.Start();

            //thread to read temps every 10 seconds
            Thread readTempsThread = new Thread(ReadTemps_Delegate);
            readTempsThread.Start();
            
            //loop
            while (true)
            {
                //stay alive
            }
        }

        private static void ReadTemps_Delegate()
        {
            Timer readTempsTimer = new Timer(new TimerCallback(ReadTemps_Tick), null, 0, 10000);
        }

        private static void ReadTemps_Tick(Object obj)
        {
            tempReadingTimestamp = DateTime.Now;
            owSensor1Temp = GetOneWireTempByByteArray(owSensor1);
            owSensor2Temp = GetOneWireTempByByteArray(owSensor2);

            string debugString = tempReadingTimestamp.ToString();
            debugString += " Temp Inside: " + owSensor1Temp.ToString("N1");
            debugString += " Temp Outside: " + owSensor2Temp.ToString("N1");
            Debug.Print(debugString);
        }

        static float GetOneWireTempByByteArray(byte[] sensor)
        {
            float TemperatureC = 0;
            int tempLow = 0;
            int tempHigh = 0;
            int temptemp;

            owBus0.TouchReset(); //reset
            owBus0.TouchByte(0x55); //match rom
            foreach (byte b in sensor) //send the whole byte array
            {
                owBus0.TouchByte(B);
            }
            owBus0.TouchByte(0x44); //start temp conversion
            while (owBus0.ReadByte() == 0) ; //wait while busy
            owBus0.TouchReset(); //reset
            owBus0.TouchByte(0x55); //match rom
            foreach (byte b in sensor) //send the whole byte array
            {
                owBus0.TouchByte(B);
            }
            owBus0.TouchByte(0xBE); //read scratchpad
            tempLow = owBus0.ReadByte(); //LSB
            tempHigh = owBus0.ReadByte(); //MSB
            temptemp = (((int)(tempHigh) << 8) | tempLow);
            TemperatureC = temptemp * 0.0625f;

            // temperature is negative if sign bit set
            if (!((tempHigh & 0x80) == 0))
            {
                short t = 0;
                float result = 0f;

                // construct complete temp value
                t = (short)((tempHigh << 8) + tempLow);

                // if negative, take two's complement to get absolute value
                t = (short)-t;

                // get integer part if any
                result = (float)(t >> 8);

                // remove zero bits and add fractional part if any
                result += ((t >> 3) & 0x1f) * 0.03125f;

                // return value with correct sign
                TemperatureC = -result;
            }
            return (float)((TemperatureC * 9.00 / 5.00) + 32.00);
        }

  //left out some non essential code
}

  • James , Larre and M8in like this

#2 Chris Walker

Chris Walker

    Secret Labs Staff

  • Moderators
  • 7767 posts
  • LocationNew York, NY

Posted 11 November 2012 - 11:06 PM

Awesome, nickNetduino. Thank you for forging new paths and sharing this! First Netduino Plus 2 OneWire sample (using the NETMF OneWire classes). Cool :) I'll leave it to others to comment on the code. We're cooking up something here which I'm supposed to be approving the spec for...and working out a test plan for baxter's networking scenario...and I'll get too distracted if I dig in and start wiring up sensors using your code :) Chris

#3 nickNetduino

nickNetduino

    Member

  • Members
  • PipPip
  • 12 posts

Posted 11 November 2012 - 11:11 PM

One thing I would like comments on is: I put the LED blink routine and temp reading routine in different threads as I thought this would be best practice (is it?). However, why does the LED stutter every 10 seconds when the temps are read?

#4 carb

carb

    Advanced Member

  • Members
  • PipPipPip
  • 352 posts
  • LocationCrystal River, Florida

Posted 11 November 2012 - 11:16 PM

Sample Debug Output:

11/11/2012 19:03:25 Temp Inside: 67.8 Temp Outside: 44.4
11/11/2012 19:03:35 Temp Inside: 67.9 Temp Outside: 44.4
11/11/2012 19:03:45 Temp Inside: 67.9 Temp Outside: 44.5
11/11/2012 19:03:55 Temp Inside: 67.9 Temp Outside: 44.5
11/11/2012 19:04:05 Temp Inside: 67.9 Temp Outside: 44.

Nick,

Looks cold outside, it 83 outside here in Florida, A/C is running.

What sensors are you using.

Thanks for postiong the code to help others get started,
Chuck

#5 nickNetduino

nickNetduino

    Member

  • Members
  • PipPip
  • 12 posts

Posted 11 November 2012 - 11:19 PM


What sensors are you using.


DS18B20

#6 Chris Walker

Chris Walker

    Secret Labs Staff

  • Moderators
  • 7767 posts
  • LocationNew York, NY

Posted 11 November 2012 - 11:39 PM

Hi nickNetduino,

I put the LED blink routine and temp reading routine in different threads as I thought this would be best practice (is it?). However, why does the LED stutter every 10 seconds when the temps are read?

Do you have the blink routine on a timer? Or is it sitting in a tight loop in a thread?

NETMF's multi-tasking works best if routines don't "block" in tight loops. Also if the temp reading code takes a little while to execute (10s of ms) then the native code execution can hold up your managed code temporarily.

Chris

#7 nickNetduino

nickNetduino

    Member

  • Members
  • PipPip
  • 12 posts

Posted 11 November 2012 - 11:57 PM

Hi nickNetduino,


Do you have the blink routine on a timer? Or is it sitting in a tight loop in a thread?

NETMF's multi-tasking works best if routines don't "block" in tight loops. Also if the temp reading code takes a little while to execute (10s of ms) then the native code execution can hold up your managed code temporarily.

Chris


LED Blink is done using:


        //thread to blink the led every 250ms
        Thread ledBlinkThread = new Thread(BlinkLed_Delegate);
        ledBlinkThread.Start();

        private static void BlinkLed_Delegate()
        {
            Timer blinkTimer = new Timer(new TimerCallback(BlinkLed_Tick), null, 0, 250);
        }

        private static void BlinkLed_Tick(Object obj)
        {
            led.Write(!led.Read());
        }



#8 Chris Walker

Chris Walker

    Secret Labs Staff

  • Moderators
  • 7767 posts
  • LocationNew York, NY

Posted 11 November 2012 - 11:59 PM

nickNetduino, Hmm, it may just be the OneWire code taking a lot of time then. Do you have a feel for how long the actual OneWire transaction takes? Chris

#9 nickNetduino

nickNetduino

    Member

  • Members
  • PipPip
  • 12 posts

Posted 12 November 2012 - 12:03 AM

nickNetduino,

Hmm, it may just be the OneWire code taking a lot of time then. Do you have a feel for how long the actual OneWire transaction takes?

Chris



I think the stutter is ok after doing more research... The reads may take a full second. What really is buggin me now is after ~5 mins running, the led stops totally (randomly high or low) BUT the webserver still responds.

#10 Chris Walker

Chris Walker

    Secret Labs Staff

  • Moderators
  • 7767 posts
  • LocationNew York, NY

Posted 12 November 2012 - 12:08 AM

I think the stutter is ok after doing more research... The reads may take a full second. What really is buggin me now is after ~5 mins running, the led stops totally (randomly high or low) BUT the webserver still responds.

Hmm, very curious.

Can you put a Debug.Print at the front of the LED blinking function, and one at the beginning of the web server "accept" code?

And then we can see if the timer is stopped being called?

If so, there may be a NETMF bug to fix. Adventure :)

Chris

#11 nickNetduino

nickNetduino

    Member

  • Members
  • PipPip
  • 12 posts

Posted 12 November 2012 - 12:30 AM

Hmm, very curious.

Can you put a Debug.Print at the front of the LED blinking function, and one at the beginning of the web server "accept" code?

And then we can see if the timer is stopped being called?

If so, there may be a NETMF bug to fix. Adventure :)

Chris


Ok here is the latest... I've disable the web server entirely and the thing still hangs so I'm thinking the sensor reading code is screwing something up so back to my first post and hopefully someone can spot a big bug. Here is the debug output:


--NORMAL RUN FOR ABOUT 1 MINUTE....
LED BLINK 11/11/2012 20:27:26
LED BLINK 11/11/2012 20:27:27
LED BLINK 11/11/2012 20:27:28
11/11/2012 20:27:29 Temp Inside: 67.4 Temp Outside: 42.8
LED BLINK 11/11/2012 20:27:31
LED BLINK 11/11/2012 20:27:31
LED BLINK 11/11/2012 20:27:32
LED BLINK 11/11/2012 20:27:33
LED BLINK 11/11/2012 20:27:34
LED BLINK 11/11/2012 20:27:35
LED BLINK 11/11/2012 20:27:36
LED BLINK 11/11/2012 20:27:37
LED BLINK 11/11/2012 20:27:38
11/11/2012 20:27:39 Temp Inside: 67.3 Temp Outside: 42.6
LED BLINK 11/11/2012 20:27:41
LED BLINK 11/11/2012 20:27:41
--FROZEN BUT NO VISUAL STUDIO EXCEPTION THROWN

#12 Chris Walker

Chris Walker

    Secret Labs Staff

  • Moderators
  • 7767 posts
  • LocationNew York, NY

Posted 12 November 2012 - 01:03 AM

Hi nickNetduino, To confirm...is all your code stopping? Or is the web server code still working but the LED stops blinking? Chris

#13 nickNetduino

nickNetduino

    Member

  • Members
  • PipPip
  • 12 posts

Posted 12 November 2012 - 01:15 AM

Hi nickNetduino,

To confirm...is all your code stopping? Or is the web server code still working but the LED stops blinking?

Chris


The output in the previous post is where I have totally disabled the webserver and both timers still appear to stop. With the webserver enabled, it appears to stay running even after the 2 timers die.

#14 nickNetduino

nickNetduino

    Member

  • Members
  • PipPip
  • 12 posts

Posted 12 November 2012 - 03:06 AM

Could garbage collection be at issue? Similar to http://forums.netdui...tes-five-times/

#15 Chris Walker

Chris Walker

    Secret Labs Staff

  • Moderators
  • 7767 posts
  • LocationNew York, NY

Posted 12 November 2012 - 03:25 AM

Could garbage collection be at issue? Similar to http://forums.netdui...tes-five-times/


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

#16 TalbotEv

TalbotEv

    New Member

  • Members
  • Pip
  • 7 posts

Posted 14 November 2012 - 10:59 AM

Does this also works for the Netduino Plus Version 1 ?

Also at the tick you create a new string everytime, i myself would make a public static string and fill that evertime.

string debugString = tempReadingTimestamp.ToString();

So i would change this to:

debugString = tempReadingTimestamp.ToString();

and at the the static declarations at the top:

...
static DateTime tempReadingTimestamp = DateTime.Now;

static string debugString;


#17 nickNetduino

nickNetduino

    Member

  • Members
  • PipPip
  • 12 posts

Posted 14 November 2012 - 10:31 PM

Does this also works for the Netduino Plus Version 1 ?

Also at the tick you create a new string everytime, i myself would make a public static string and fill that evertime.

string debugString = tempReadingTimestamp.ToString();

So i would change this to:

debugString = tempReadingTimestamp.ToString();

and at the the static declarations at the top:

...
static DateTime tempReadingTimestamp = DateTime.Now;

static string debugString;



Thanks, I've made quite a few improvements and the code is a bit different now but I dont believe it will work with the original netduino plus because it needs to support native onewire. I believe there is a custom firmware with it's own onewire implementation that you can go with though.

#18 richy759

richy759

    New Member

  • Members
  • Pip
  • 3 posts

Posted 04 January 2013 - 12:55 PM

Just got my Netduino plus 2, this may seem like an obvios question but what namespace is OneWire under? I can't seemt to find it. I've updated to sdk version 4.2.1.

Thanks in advance,

Rich



#19 Chris Walker

Chris Walker

    Secret Labs Staff

  • Moderators
  • 7767 posts
  • LocationNew York, NY

Posted 04 January 2013 - 10:50 PM

Hi Rich, You'll want to add the Microsoft.SPOT.Hardware.OneWire.dll assembly as a reference to your project. The class is Microsoft.SPOT.Hardware.OneWire. Chris
  • M8in likes this

#20 richy759

richy759

    New Member

  • Members
  • Pip
  • 3 posts

Posted 05 January 2013 - 04:12 PM

Thanks Chris






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.