Temperature Graph

Hello,

i got a little problem and hope that someone here can help me.

I found this tutorial: http://www.gadgeteering.net/content/graphing-altimeter
I liked the graph and tried to use it with my DS1820.

In my Program.cs i get the temp from my DS1820 with this code:

// Spider: EMX.Pin.IO16 = Socket #8, Pin #6
            using (OneWireBus.OneWireBus oneWireBus = new OneWireBus.OneWireBus(EMX.Pin.IO16))
            {
                 OneWireDevice[] oneWireDevices = oneWireBus.Devices;
                 //Debug.Print("Found " + oneWireDevices.Length + " devices");
                 //Debug.Print(string.Empty);
                 while(true){
                    foreach (OneWireDevice oneWireDevice in oneWireDevices)
                    {

                        //Debug.Print("Device: " + oneWireDevice.DeviceAddress);

                        // We only handle temperature devices
                        TemperatureDevice temperatureDevice = oneWireDevice as TemperatureDevice;
                        if (temperatureDevice == null)
                        {
                            continue;
                        }

                        Debug.Print(MeasurementsTaken+"Synchronous temperature: " + temperatureDevice.GetTemperature() + "C");

                        // Collect a number of measurments to have smoother data
                        if (MeasurementsTaken < MeasurementsToAverage)
                        {
                            //TemperatureAsyncResult temperatureAsyncResult = temperatureDevice.BeginGetTemperature();
                            //AverageTemperature += temperatureAsyncResult.End() * 8;
                            AverageTemperature += 20.00;
                            MeasurementsTaken++;
                        }
                        else
                        {
                            // Calculate averages of sensor data
                            AverageTemperature = AverageTemperature / MeasurementsTaken;
                            Debug.Print("Average temperature: " + AverageTemperature + "C");

                            // Display the altitude as text. The use of .ToString("f2") means that only two decimal 
                            // values will be printed
                            altitudeText.TextContent = "Altitude: " + AverageTemperature.ToString("f2") + " meters above sea level.";

                            // Plot the new altitude value on the graph
                            altitudeGraph.Plot(AverageTemperature);

                            // Reset values and start a new averaging phase
                            AverageTemperature = 0;
                            MeasurementsTaken = 0;
                        }


                        //display.SimpleGraphics.Clear();
                        //display.SimpleGraphics.DisplayText(""+temperatureDevice.GetTemperature()*8,Resources.GetFont(Resources.FontResources.NinaB), Colors.Green, 100, 100);

                        //TemperatureAsyncResult temperatureAsyncResult = temperatureDevice.BeginGetTemperature();
                        //Debug.Print("Asynchronous temperature: " + temperatureAsyncResult.End() + "C");

                        //Debug.Print(string.Empty);
                    }
               }
            }

For using it with the altimeter tutorial i removed the while loop and wrote this program.cs:

using GHIElectronics.NETMF.Hardware;
using TempDS1820.OneWireBus;
using TempDS1820.OneWireBus.Devices;

using Gadgeteer.Modules.GHIElectronics;

using System;
using System.Collections;
using System.Threading;
using Microsoft.SPOT;
using Microsoft.SPOT.Presentation;
using Microsoft.SPOT.Presentation.Controls;
using Microsoft.SPOT.Presentation.Media;
using Microsoft.SPOT.Touch;

using Gadgeteer.Networking;
using GT = Gadgeteer;
using GTM = Gadgeteer.Modules;
using Gadgeteering;

namespace TempDS1820
{

    public partial class Program
    {
        GT.Timer sensorUpdateTimer;
        const int MeasurementsToAverage = 3;
        int MeasurementsTaken = 0;
        double AverageTemperature = 0;

        void ProgramStarted()
        {
            PrepareWindow();

                sensorUpdateTimer = new GT.Timer(100); // Request a new reading every 100 millseconds
                sensorUpdateTimer.Tick += new GT.Timer.TickEventHandler(sensorUpdateTimer_Tick);
                sensorUpdateTimer.Start();

            Debug.Print("Starting ...");

            
        }

        void sensorUpdateTimer_Tick2(GT.Timer timer)
        {
            AverageTemperature += 0.1;
            altitudeGraph.Plot(AverageTemperature);

        }
        void sensorUpdateTimer_Tick(GT.Timer timer)
        {

            altitudeGraph.Plot(20.0);

            // Spider: EMX.Pin.IO16 = Socket #8, Pin #6
            using (OneWireBus.OneWireBus oneWireBus = new OneWireBus.OneWireBus(EMX.Pin.IO16))
            {
                 OneWireDevice[] oneWireDevices = oneWireBus.Devices;

                    foreach (OneWireDevice oneWireDevice in oneWireDevices)
                    {

                        // We only handle temperature devices
                        TemperatureDevice temperatureDevice = oneWireDevice as TemperatureDevice;
                        if (temperatureDevice == null)
                        {
                            continue;
                        }

                        Debug.Print(MeasurementsTaken+"Synchronous temperature: " + temperatureDevice.GetTemperature() + "C");

                        // Collect a number of measurments to have smoother data
                        if (MeasurementsTaken < MeasurementsToAverage)
                        {
                            //TemperatureAsyncResult temperatureAsyncResult = temperatureDevice.BeginGetTemperature();
                            //AverageTemperature += temperatureAsyncResult.End() * 8;
                            AverageTemperature += 20.00;
                            MeasurementsTaken++;
                        }
                        else
                        {
                            // Calculate averages of sensor data
                            AverageTemperature = AverageTemperature / MeasurementsTaken;
                            Debug.Print("Average temperature: " + AverageTemperature + "C");

                            // Display the altitude as text. The use of .ToString("f2") means that only two decimal 
                            // values will be printed
                            altitudeText.TextContent = "Altitude: " + AverageTemperature.ToString("f2") + " meters above sea level.";

                            // Plot the new altitude value on the graph
                            altitudeGraph.Plot(AverageTemperature);

                            // Reset values and start a new averaging phase
                            AverageTemperature = 0;
                            MeasurementsTaken = 0;
                        }

                        //TemperatureAsyncResult temperatureAsyncResult = temperatureDevice.BeginGetTemperature();
                        //Debug.Print("Asynchronous temperature: " + temperatureAsyncResult.End() + "C");
                        //Debug.Print(string.Empty);
                    }
                // Test to dispose ... no effect
                //oneWireBus.Dispose();
                //oneWireBus.Release();
            }     
        }

        // Graphical user interface elements
        Window window;
        Canvas canvas;
        Text altitudeText;
        SimpleGraph altitudeGraph;

        void PrepareWindow()
        {
            // Get a reference to the WPFWindow from the display
            window = display.WPFWindow;

            // Create a new canvas, which will be used to lay out all the
            // other elements
            canvas = new Canvas();

            // Add the canvas as the only child of the window.
            window.Child = canvas;

            // Load a font from the resources.
            Font defaultFont = Resources.GetFont(Resources.FontResources.NinaB);

            // Crete a graph that is 200 pixels high, and 300 wide.
            // The graph will be used to plot altitudes between 0 and 20 meters
            // Change these values according to desired plotting range.
            // The graph is also configured to plot 300 values in one screenful
            // which is 5 minutes of data (with the sensor update interval at 1 second).
            // After the graph is full, it will automatically start to scroll.
            altitudeGraph = new SimpleGraph(200, 300, 0, 100, 300, 1, Colors.Blue);
...

            altitudeGraph.Clear();
        }
    }
}

But i always get this Error:

[quote]3Synchronous temperature: 3.0625C
Average temperature: 20C
#### Exception System.Threading.ThreadAbortException - 0x00000000 (47) ####
#### Message:
#### System.Threading.Thread::Sleep [IP: 0000] ####
#### TempDS1820.OneWireBus.OneWireBus::AsyncTaskQueueThread [IP: 0050] ####
Eine Ausnahme (erste Chance) des Typs “System.Threading.ThreadAbortException” ist in mscorlib.dll aufgetreten.[/quote]

If i call sensorUpdateTimer_Tick2(), the graph is drawn perfectly.
I have also tried something like that:

But then i got this message:

[quote]Using mainboard GHIElectronics-FEZSpider version 1.0
#### Exception System.Threading.ThreadAbortException - 0x00000000 (3) ####
#### Message:
#### System.Threading.Thread::Sleep [IP: 0000] ####
#### TempDS1820.OneWireBus.OneWireBus::AsyncTaskQueueThread [IP: 0050] ####
Eine Ausnahme (erste Chance) des Typs “System.Threading.ThreadAbortException” ist in mscorlib.dll aufgetreten.
Der Thread ‘’ (0x3) hat mit Code 0 (0x0) geendet.
Starting …
#### Exception System.ObjectDisposedException - CLR_E_OBJECT_DISPOSED (1) ####
#### Message:
#### GHIElectronics.NETMF.Hardware.OneWire::Reset [IP: 0000] ####
#### TempDS1820.OneWireBus.OneWireBus::Reset [IP: 0008] ####
#### TempDS1820.OneWireBus.Devices.OneWireDevice::Select [IP: 0008] ####
#### TempDS1820.OneWireBus.Devices.DS18B20::GetTemperature [IP: 0015] ####
#### TempDS1820.Program::sensorUpdateTimer_Tick [IP: 0058] ####
#### Gadgeteer.Timer::dt_Tick [IP: 0018] ####
#### Microsoft.SPOT.DispatcherTimer::FireTick [IP: 0010] ####
#### Microsoft.SPOT.Dispatcher::PushFrameImpl [IP: 004a] ####
#### Microsoft.SPOT.Dispatcher::PushFrame [IP: 001d] ####
#### Microsoft.SPOT.Dispatcher::Run [IP: 0006] ####
#### Gadgeteer.Program::Run [IP: 001c] ####
#### TempDS1820.Program::Main [IP: 001a] ####
Eine Ausnahme (erste Chance) des Typs “System.ObjectDisposedException” ist in GHIElectronics.NETMF.Hardware.dll aufgetreten.
In System.ObjectDisposedException ist eine Ausnahme vom Typ “GHIElectronics.NETMF.Hardware.dll” aufgetreten, doch wurde diese im Benutzercode nicht verarbeitet.
[/quote]

Maybe someone can help me to fix it :slight_smile:

King Regards

Yuri

If thats a help, this code works:

void ProgramStarted()
        {
            PrepareWindow();
            // Spider: EMX.Pin.IO16 = Socket #8, Pin #6
            using (OneWireBus.OneWireBus oneWireBus = new OneWireBus.OneWireBus(EMX.Pin.IO16))
            {
                oneWireDevices = oneWireBus.Devices;
                sensorUpdateTimer = new GT.Timer(100); // Request a new reading every 100 millseconds
                sensorUpdateTimer.Tick += new GT.Timer.TickEventHandler(sensorUpdateTimer_Tick2);
                sensorUpdateTimer.Start();
            }
            Debug.Print("Starting ...");

            
        }

        void sensorUpdateTimer_Tick2(GT.Timer timer)
        {
            foreach (OneWireDevice oneWireDevice in oneWireDevices)
                    {

                        //Debug.Print("Device: " + oneWireDevice.DeviceAddress);

                        // We only handle temperature devices
                        TemperatureDevice temperatureDevice = oneWireDevice as TemperatureDevice;
                        if (temperatureDevice == null)
                        {
                            continue;
                        }

                        //Debug.Print(MeasurementsTaken+"Synchronous temperature: " + temperatureDevice.GetTemperature() + "C");

             }

        }

But if temperatureDevice.GetTemperature() is called, the system freezes … saying theres a problem in GHIElectronics.NETMF.Hardware.dll marking this line:

[quote]///


/// Sends the reset command across the one wire bus
///

/// Returns true if there are devices on the one wire bus
public bool Reset()
{
return _oneWire.Reset();
}[/quote]

Hi,
Welcome to the community…
first i would move the


            using (OneWireBus.OneWireBus oneWireBus = new OneWireBus.OneWireBus(EMX.Pin.IO16))
            {
OneWireDevice[] oneWireDevices = oneWireBus.Devices;
 
                    foreach (OneWireDevice oneWireDevice in oneWireDevices)
                    {

outside of the timer since you only need to run this code once, when the device starts up and save the onewiredevices into an array variable for later use… i don’t see the point of calling this on every single tick since it will never change once the device starts.

see if that change helps.

Hello Jay Jay,

thanks for your help.
Heres my new code:

using GHIElectronics.NETMF.Hardware;
using TempDS1820.OneWireBus;
using TempDS1820.OneWireBus.Devices;

using Gadgeteer.Modules.GHIElectronics;

using System;
using System.Collections;
using System.Threading;
using Microsoft.SPOT;
using Microsoft.SPOT.Presentation;
using Microsoft.SPOT.Presentation.Controls;
using Microsoft.SPOT.Presentation.Media;
using Microsoft.SPOT.Touch;

using Gadgeteer.Networking;
using GT = Gadgeteer;
using GTM = Gadgeteer.Modules;
using Gadgeteering;

namespace TempDS1820
{
    /// <summary>
    /// Test program to test the one wire library
    /// <remarks>Assumes that an EMX device is connected and that pin EMX.Pin.IO16 (Socket #8, pin #6 on the Spider) is used for the one wire bus - Multiple devices are allowed on the bus</remarks>
    /// </summary>
    public partial class Program
    {
        GT.Timer sensorUpdateTimer;
        const int MeasurementsToAverage = 3;
        int MeasurementsTaken = 0;
        double AverageTemperature = 0;
        OneWireDevice[] oneWireDevices;
        TemperatureDevice temperatureDevice;
        /// <summary>
        /// The main entry point
        /// </summary>
        void ProgramStarted()
        {
            PrepareWindow();
            // Spider: EMX.Pin.IO16 = Socket #8, Pin #6
            using (OneWireBus.OneWireBus oneWireBus = new OneWireBus.OneWireBus(EMX.Pin.IO16))
            {
                oneWireDevices = oneWireBus.Devices;
                //Debug.Print("Found " + oneWireDevices.Length + " devices");
                //Debug.Print(string.Empty);
                foreach (OneWireDevice oneWireDevice in oneWireDevices)
                {
                    //Debug.Print("Device: " + oneWireDevice.DeviceAddress);
                    // We only handle temperature devices
                    temperatureDevice = oneWireDevice as TemperatureDevice;
                    if (temperatureDevice == null)
                    {
                        continue;
                    }

                    sensorUpdateTimer = new GT.Timer(100); // Request a new reading every 100 millseconds
                    sensorUpdateTimer.Tick += new GT.Timer.TickEventHandler(sensorUpdateTimer_Tick);
                    sensorUpdateTimer.Start();
                }
            }
            Debug.Print("Starting ...");


        }

        void sensorUpdateTimer_Tick2(GT.Timer timer)
        {
            AverageTemperature += 0.1;
            altitudeGraph.Plot(AverageTemperature);

        }
        void sensorUpdateTimer_Tick(GT.Timer timer)
        {

            altitudeGraph.Plot(20.0);

            Debug.Print(MeasurementsTaken + "Synchronous temperature: " + temperatureDevice.GetTemperature() + "C");

            // Collect a number of measurments to have smoother data
            if (MeasurementsTaken < MeasurementsToAverage)
            {
                //TemperatureAsyncResult temperatureAsyncResult = temperatureDevice.BeginGetTemperature();
                //AverageTemperature += temperatureAsyncResult.End() * 8;
                AverageTemperature += 20.00;
                MeasurementsTaken++;
            }
            else
            {
                // Calculate averages of sensor data
                AverageTemperature = AverageTemperature / MeasurementsTaken;
                Debug.Print("Average temperature: " + AverageTemperature + "C");

                // Display the altitude as text. The use of .ToString("f2") means that only two decimal 
                // values will be printed
                altitudeText.TextContent = "Altitude: " + AverageTemperature.ToString("f2") + " meters above sea level.";

                // Plot the new altitude value on the graph
                altitudeGraph.Plot(AverageTemperature);

                // Reset values and start a new averaging phase
                AverageTemperature = 0;
                MeasurementsTaken = 0;
            }


            //display.SimpleGraphics.Clear();
            //display.SimpleGraphics.DisplayText(""+temperatureDevice.GetTemperature()*8,Resources.GetFont(Resources.FontResources.NinaB), Colors.Green, 100, 100);

            //TemperatureAsyncResult temperatureAsyncResult = temperatureDevice.BeginGetTemperature();
            //Debug.Print("Asynchronous temperature: " + temperatureAsyncResult.End() + "C");

            //Debug.Print(string.Empty);




        }

        // Graphical user interface elements
        Window window;
        Canvas canvas;
        Text altitudeText;
        SimpleGraph altitudeGraph;

        void PrepareWindow()
        {
            // Get a reference to the WPFWindow from the display
            window = display.WPFWindow;

            // Create a new canvas, which will be used to lay out all the
            // other elements
            canvas = new Canvas();

            // Add the canvas as the only child of the window.
            window.Child = canvas;

            // Load a font from the resources.
            Font defaultFont = Resources.GetFont(Resources.FontResources.NinaB);

            // Crete a graph that is 200 pixels high, and 300 wide.
            // The graph will be used to plot altitudes between 0 and 20 meters
            // Change these values according to desired plotting range.
            // The graph is also configured to plot 300 values in one screenful
            // which is 5 minutes of data (with the sensor update interval at 1 second).
            // After the graph is full, it will automatically start to scroll.
            altitudeGraph = new SimpleGraph(200, 300, 0, 100, 300, 1, Colors.Blue);

            // Display a background grid, with a vertical line every 60 pixels (one minute 
            // intervals), and a horizontal line every 20 pixels (two meter intervals). 
            altitudeGraph.DisplayGridLines(60, 20, GT.Color.LightGray);

            // Add the graph to the layout canvas
            canvas.Children.Add(altitudeGraph);

            // Set the top of the graph 40 pixels away from the top of the canvas
            Canvas.SetTop(altitudeGraph, 30);

            // Set the left of the graph 10 pixels away from the left of the canvas
            Canvas.SetLeft(altitudeGraph, 10);

            // Configure the text box to display the altitude value.
            altitudeText = new Text(defaultFont, "Altitude: ");
            altitudeText.ForeColor = Colors.Blue;
            canvas.Children.Add(altitudeText);
            Canvas.SetLeft(altitudeText, 10);
            Canvas.SetTop(altitudeText, 8);

            altitudeGraph.Clear();
        }

    }
}

Here is the error:

[quote]Using mainboard GHIElectronics-FEZSpider version 1.0
#### Exception System.Threading.ThreadAbortException - 0x00000000 (3) ####
#### Message:
#### System.Threading.Thread::Sleep [IP: 0000] ####
#### TempDS1820.OneWireBus.OneWireBus::AsyncTaskQueueThread [IP: 0050] ####
Eine Ausnahme (erste Chance) des Typs “System.Threading.ThreadAbortException” ist in mscorlib.dll aufgetreten.
Der Thread ‘’ (0x3) hat mit Code 0 (0x0) geendet.
Starting …
#### Exception System.ObjectDisposedException - CLR_E_OBJECT_DISPOSED (1) ####
#### Message:
#### GHIElectronics.NETMF.Hardware.OneWire::Reset [IP: 0000] ####
#### TempDS1820.OneWireBus.OneWireBus::Reset [IP: 0008] ####
#### TempDS1820.OneWireBus.Devices.OneWireDevice::Select [IP: 0008] ####
#### TempDS1820.OneWireBus.Devices.DS18B20::GetTemperature [IP: 0015] ####
#### TempDS1820.Program::sensorUpdateTimer_Tick [IP: 0031] ####
#### Gadgeteer.Timer::dt_Tick [IP: 0018] ####
#### Microsoft.SPOT.DispatcherTimer::FireTick [IP: 0010] ####
#### Microsoft.SPOT.Dispatcher::PushFrameImpl [IP: 004a] ####
#### Microsoft.SPOT.Dispatcher::PushFrame [IP: 001d] ####
#### Microsoft.SPOT.Dispatcher::Run [IP: 0006] ####
#### Gadgeteer.Program::Run [IP: 001c] ####
#### TempDS1820.Program::Main [IP: 001a] ####
Eine Ausnahme (erste Chance) des Typs “System.ObjectDisposedException” ist in GHIElectronics.NETMF.Hardware.dll aufgetreten.
In System.ObjectDisposedException ist eine Ausnahme vom Typ “GHIElectronics.NETMF.Hardware.dll” aufgetreten, doch wurde diese im Benutzercode nicht verarbeitet.

Das Programm “[12] Micro Framework application: Verwaltet” wurde mit Code 0 (0x0) beendet.
[/quote]

Like above: If temperatureDevice.GetTemperature() is called, the system freezes … saying theres a problem in GHIElectronics.NETMF.Hardware.dll marking this line:

[quote]/// <summary> /// Sends the reset command across the one wire bus
/// </summary>
/// <returns>Returns <c>true</c> if there are devices on the one wire bus</returns>
public bool Reset()
{
            return _oneWire.Reset();
}[/quote]

What does happen if you do it this way : ?


var myVar = temperatureDevice.GetTemperature();

Debug.Print(MeasurementsTaken + "Synchronous temperature: " + myVar + "C");

Make oneWireBus a class variable and don use using statement.



    public partial class Program
    {
        GT.Timer sensorUpdateTimer;
        const int MeasurementsToAverage = 3;
        int MeasurementsTaken = 0;
        double AverageTemperature = 0;
        OneWireDevice[] oneWireDevices;
        TemperatureDevice temperatureDevice;

        OneWireBus.OneWireBus oneWireBus;

        /// <summary>
        /// The main entry point
        /// </summary>
        void ProgramStarted()
        {
            PrepareWindow();
            // Spider: EMX.Pin.IO16 = Socket #8, Pin #6
            oneWireBus = new OneWireBus.OneWireBus(EMX.Pin.IO16);
            
                oneWireDevices = oneWireBus.Devices;
                //Debug.Print("Found " + oneWireDevices.Length + " devices");
                //Debug.Print(string.Empty);
                foreach (OneWireDevice oneWireDevice in oneWireDevices)
                {
                    //Debug.Print("Device: " + oneWireDevice.DeviceAddress);
                    // We only handle temperature devices
                    temperatureDevice = oneWireDevice as TemperatureDevice;
                    if (temperatureDevice == null)
                    {
                        continue;
                    }
 
                    sensorUpdateTimer = new GT.Timer(100); // Request a new reading every 100 millseconds
                    sensorUpdateTimer.Tick += new GT.Timer.TickEventHandler(sensorUpdateTimer_Tick);
                    sensorUpdateTimer.Start();
                }           
            Debug.Print("Starting ...");
        }
...

Hello Architect,

your tipp fixed it -> see the photo :slight_smile:

Thanks to all for their help!

Awesome! Glad to hear it. :wink:

Looks good…
please mark your post as answered … :slight_smile:

Graph is awesome, the wiring mess, not so much!

@ loco shoot me an email to steve at stevepresley.net and I’ll hook you up with one of my prototype mounting boards and hardware to clean things up for your next pics!

And up the code up in Codeshare too if you get a chance!

Most of the code is not mine, its from codeshare and the tuturial from my first post.
Am i allowed to upload the whole project to codeshare?
I just changed the program.cs and joined two projects …

I would make sure to give credit in your description to code sources you used.

Gadgeteering is not anymore online… can you share with me the DS1820 library?

Thanks

@ Architect - Where i can find the TemperatureDevice class?

@ AlbeNET - It must have been part of the project zip file on that site. Sorry can’t help you here.

To bad wayback machine didn’t cached the zip file. But you can still read the article:

http://web.archive.org/web/20131209091118/http://www.gadgeteering.net/content/graphing-altimeter

Thanks!