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.

shimoda

Member Since 07 Feb 2011
Offline Last Active Dec 28 2019 06:25 PM
-----

Posts I've Made

In Topic: Reading an InterruptPort from a thread does not work!

11 September 2015 - 03:08 AM

Hi Chris, 

 

You got it right! Moving the interruptPort into the Run function works. This code sample is just a part of a bigger project I have and I am more confuse on how to deal with threads.

 

Is there a way to make Visual Studio debugger showing more relevant information to nail down thread and event issues? 

 

The big picture of my project is the following: 

- The program will consist of a sequence of steps. 

- An interrupt can Suspend and Resume the program not matter which step is processing. 
- Each step will have few different interrupts that will live through it. 

 

I would appreciate any information sources on how I can architecture threads in my program to reach my goal.


In Topic: How to pause a program execution without a timer?

09 September 2015 - 07:57 PM

Here is the solution I have developed based on my search.

 

I will be happy to learn from your comments.

using System;
using System.Threading;
using Microsoft.SPOT;
using Microsoft.SPOT.Hardware;
using SecretLabs.NETMF.Hardware;
using SecretLabs.NETMF.Hardware.Netduino;

namespace ReadInterruptGPIOfromThread
{
    public class Program
    {
        InterruptPort button = new InterruptPort(Pins.ONBOARD_BTN, true, Port.ResistorMode.PullUp, Port.InterruptMode.InterruptEdgeLevelHigh);

        Thread runT = new Thread(new ThreadStart(p.Run));     //Thread to execute the main program.
        protected Boolean runTRunning = false;

        public static Program p = new Program();
        public static void Main()
        {
            p.Subscribe();
            Thread.Sleep(Timeout.Infinite); //Waiting for an event.
        }

        public void Subscribe()
        {
            button.OnInterrupt += new NativeEventHandler(doOnButton);
        }

        public void Run()
        {
            while (true)
            {
                Print();  
                Thread.Sleep(1000);
            }
        }

        public void Print() //The content of this function will be replaced by the real purpose of the program.
        {
            Debug.Print("Running");
        }

        public void doOnButton(uint data1, uint data2, DateTime time)
        {
            Debug.Print("Button triggered!: " + data2);
            button.ClearInterrupt();
            if (!runT.IsAlive)
            { //On the first button pressed, the program starts. Next times it toggles between Suspend and Resume (else condition).
                Debug.Print("Started!" + data2);
                runTRunning = true; 
                runT.Start();
            }
            else
            {
                if (runTRunning == false)
                {
                    Debug.Print("Resumed!" + data2);
                    runT.Resume();
                    runTRunning = true;
                }
                else
                {
                    Debug.Print("Suspended!" + data2);
                    runT.Suspend();
                    runTRunning = false;
                }
            }
        }
    }
}


In Topic: How to pause a program execution without a timer?

09 September 2015 - 07:51 PM

 

Hi, 

 

I am not sure I fully understood what how the GPIO port behaves in your example, but assuming it can generate interrupts as the board's button does, I would use a Timer instead of a while loop and write something like the following example. 

 

N.B. I did not get the occasion to compile/test the following code, adapted from something I did here. It's thus just the general idea of what I would do. 

 

using System.Timers;
 
public class Process
{
    const int STARTUP_TIME = 5000;
    const int PERIOD = 1000; //We assume that ReadSensorValuesAndDoStuff() execution takes less than 1 second
 
    bool isEnabled = true; 
 
    InterruptPort button = new InterruptPort(Pins.ONBOARD_SW1, false, Port.ResistorMode.Disabled, Port.InterruptMode.InterruptEdgeBoth);
 
    public Process() 
    {
          button.OnInterrupt += new NativeEventHandler(button_OnInterrupt);
 
          TimerCallback workTimerCallBack = DoWork;
          Timer workTimer = new Timer(workTimerCallBack, null, STARTUP_TIME, PERIOD);
     }
 
     private void DoWork(object state)
     {
          if (isEnabled)
          {
               ReadSensorValuesAndDoStuff();
          }
     }
 
    void button_OnInterrupt(uint data1, uint data2, DateTime time)
     {
          isEnabled = !isEnabled; 
     }
}
 
Every second, DoWork() will be called and, if isActive is true (which is the default value), ReadSensorValuesAndDoStuff() will be called.
 
When the board's button is pushed, the _OnInterrupt handler will be called and the isActive will be inverted, going from true to false, stopping the calls to ReadSensor...(). When the button will be released or pushed again (depending on the chosen Port.InterruptMode), the isActive variable will be returned to true, and ReadSensorValuesAndDoStuff() will be called again. 
 
Note that with .NET, a Timer has an "enabled" property that I would use instead of the isEnabled variable.
 
Hope it helps, 
 
Paul 
 
P.S. While verifying my posted answer, I noticed the "without a Timer" in the title of your post  :unsure:  

 

Thanks Paul for you idea. It opens my mind to concept I did not know. Therefore, in my context my system will be doing stuff none stop, so timer is not the best option unless I put the period to 0 second.


In Topic: How to pause a program execution without a timer?

27 August 2015 - 01:54 AM

        public static void Run() {
            while (true)
            {
                if (errorSignal.Read() == false) 
                //Read the signal on the GPIO port. This signal is maintain until the switch is reset.
                {
                    //The emergency stop switch is active. Pause the program execution.
                    emergencyStopEvent(new object(), EventArgs.Empty); //Stop all heating components, timers...
                    while (true)
                    {
                        if (errorSignal.Read() == true) 
                        //Read the signal on the GPIO port. The switch has been reset.
                        {
                            //There is a request to resume the program execution.
                            break;
                        }
                    }
                }
                ReadSensorValuesAndDoStuff();
            }
        }

What would be a better approach to wait for the activation/desactivation of the GPIO port (user emergency switch) in order to pause and resume the program execution?  


In Topic: How to pause a program execution without a timer?

27 August 2015 - 01:51 AM

        public static void Run() {
            while (true)
            {
                if (errorSignal.Read() == false) 
                //Read the signal on the GPIO port. This signal is maintain until the switch is reset.
                {
                    //The emergency stop switch is active. Pause the program execution.
                    emergencyStopEvent(new object(), EventArgs.Empty); //Stop all heating components, timers...
                    while (true)
                    {
                        if (errorSignal.Read() == true) 
                        //Read the signal on the GPIO port. The switch has been reset.
                        {
                            //There is a request to resume the program execution.
                            break;
                        }
                    }
                }
                ReadSensorValuesAndDoStuff();
            }
        }

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.