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

Multiple Threads v. While Loop


  • Please log in to reply
13 replies to this topic

#1 Dan Kowalczyk

Dan Kowalczyk

    Advanced Member

  • Members
  • PipPipPip
  • 44 posts
  • LocationSeattle

Posted 20 October 2012 - 07:12 PM

Hello Netduino Community,

I'm very excited to be getting into microcontrollers and am grateful for the contributions that have led to the Netduino. I am especially grateful for the lucid publications that have come out through O'Reilly that have taught me how to make sense of all the technology. I have never been a fan of forums because of how disorganized they seem to be, but I am thankful for the troubleshooting posts here.

I have been having fun getting acquainted with Netduino through examples and modifying them with my own "what if" questions, but I'm now at the point where I'm trying to probe its limits so I can understand which of my grand project ideas are immediately possible. The main limit I see from Netduino examples (and Arduino) is that most programs hinge on a single while loop. The complexity of your project is limited by how much logic you can fit into it.

My brother is software programmer and told me that video games (at a basic level) hinge on a single while loop that changes any given frame of the video based on the many parameters going into the frame. So, I see how much can be done with a while loop, however it seems like Threading could be a better way.

I played with both these implementations in the following experiment: Two LEDs blinking at different rates. In the implementation using a single while loop, I kept a counter on the number of cycles of the while loop and blinked the first (slower) light at a multiple of the delay of the second light. I checked a condition on the counter and blinked the first light appropriately. However, by using the Threading technique, I ran two threads running its own while loop and delayed each light as usual. This way also allowed me to decouple the rates of the blinks in code completely i.e. I didn't have to keep track of whether one light's delay was a multiple of the other. (Note: I have gotten both these approaches to work, but I'm not posting code in order to keep this a conversational post for now).

Given this background, my main question for the forum is which implementation is better practice? What limitations exist in Threading at a hardware level i.e. with respect responsiveness? Is there a "magic door #3" that is a better way to manage complexity beyond while loop tricks and Threading? How do you all manage complexity and squeeze as much control out of the Netduino? To the best of my knowledge, Arduino does not have Threading, so how do those users approach problems like I presented? How would they add to such a project and, for example, also control another device that relies on input from a potentiometer continuously without being slowed by the delays of the lights? How would I do that without the use of Threading?

Thanks for your time and I look forward to the discussion!

If you want a treat and don't mind the treatment...

#2 NooM

NooM

    Advanced Member

  • Members
  • PipPipPip
  • 490 posts
  • LocationAustria

Posted 20 October 2012 - 08:02 PM

my _opinoin_: threads are slower than the while loop, aviod em as much as possible. first: its only one core, so its just software. everytime a thread switch happens you loose some cycles (saving data to registers, switching to the next thread and restoring its state...). i am using a timespan object to keep track of the time elapsed between the last cycle, and every class gets the time from the main loop, so every object (class) can implement a different timing. ofc thats overkill for some blinking leds, but other things: while i wanna poll data from my eeprom every clycle, i can update my display just every 100msec (or whatever value) and so on. i got this method from xna (c# game programming). ofc netduino is no game programming, but it seems very usefull to me.

#3 Chris Walker

Chris Walker

    Secret Labs Staff

  • Moderators
  • 7767 posts
  • LocationNew York, NY

Posted 20 October 2012 - 08:15 PM

For commercial NETMF products, we almost never use a single while loop. We generally use quite a few Threads, WaitHandles, Events, and Timers. They're kicked off from the Main() function. And then the firmware goes to sleep when no action is taking place. Threads are pretty lightweight in NETMF--but they are not switched as rapidly as their desktop counterparts. We avoid while(condition) wait loops in threads since those can hog a lot of MCU cycles; it's generally much better to use events or to insert a Thread.Sleep in the while(definition) wait loop. Both approaches have their benefits. Chris

#4 Dan Kowalczyk

Dan Kowalczyk

    Advanced Member

  • Members
  • PipPipPip
  • 44 posts
  • LocationSeattle

Posted 20 October 2012 - 10:03 PM

my _opinoin_: threads are slower than the while loop, aviod em as much as possible.
first: its only one core, so its just software. everytime a thread switch happens you loose some cycles (saving data to registers, switching to the next thread and restoring its state...).

i am using a timespan object to keep track of the time elapsed between the last cycle, and every class gets the time from the main loop, so every object (class) can implement a different timing. ofc thats overkill for some blinking leds, but other things:
while i wanna poll data from my eeprom every clycle, i can update my display just every 100msec (or whatever value) and so on.

i got this method from xna (c# game programming). ofc netduino is no game programming, but it seems very usefull to me.


This is precisely the technique that my brother told me about, I just couldn't describe it as well as you.

How complex does it become to manage your objects from Timespan object input? My concern about this is the same as I stated with my first dual rate light blinker implementation: arbitrary timing conditions. Is it easy to specify that you want your display to refresh every 100ms, like you said? How are you interpreting the timing from Timespan in the subscriber object?
If you want a treat and don't mind the treatment...

#5 Dan Kowalczyk

Dan Kowalczyk

    Advanced Member

  • Members
  • PipPipPip
  • 44 posts
  • LocationSeattle

Posted 20 October 2012 - 10:25 PM

For commercial NETMF products, we almost never use a single while loop.

We generally use quite a few Threads, WaitHandles, Events, and Timers. They're kicked off from the Main() function. And then the firmware goes to sleep when no action is taking place.

Threads are pretty lightweight in NETMF--but they are not switched as rapidly as their desktop counterparts. We avoid while(condition) wait loops in threads since those can hog a lot of MCU cycles; it's generally much better to use events or to insert a Thread.Sleep in the while(definition) wait loop.

Both approaches have their benefits.

Chris


Hi Chris,

I appreciate your quick response. I have learned a great deal from your book, by the way. Thanks for writing it and giving me a solid understanding of the basics!

In my other projects that use event handlers for button input, I do just as you say: kick off the program from main with a while(definition) loop and sleep it after initializing the event handlers. This leads me to another related question. If I wanted to control a certain output when an analog value is in a certain range, wouldn't I be limited to launching a Thread with a while(condition) loop (what you don't recommend). Even if I were able to implement that with a custom made event class, wouldn't I still need to use a while(condition) loop to be able to fire its delegate?

I haven't used WaitHandles. Could you describe them more or refer me to a good resource? Could you share a good example of their use?
If you want a treat and don't mind the treatment...

#6 Chris Walker

Chris Walker

    Secret Labs Staff

  • Moderators
  • 7767 posts
  • LocationNew York, NY

Posted 21 October 2012 - 12:05 AM

Hi Dan,

This leads me to another related question. If I wanted to control a certain output when an analog value is in a certain range, wouldn't I be limited to launching a Thread with a while(condition) loop (what you don't recommend). Even if I were able to implement that with a custom made event class, wouldn't I still need to use a while(condition) loop to be able to fire its delegate?

Yes, that is true. ADCs aren't interrupt based, but you can emulate this by polling them from time to time. You could either do that by running a function on a timer every once in a while or by creating a while() loop in a thread. If you create the while() loop in a thread, be sure to use Thread.Sleep() to put that thread to sleep between readings. This is a pattern we follow from time to time.

I haven't used WaitHandles. Could you describe them more or refer me to a good resource? Could you share a good example of their use?

The most popular WaitHandle is AutoResetEvent. This is useful for when you want one thread to wait on an action to occur in another thread. You basically just call myAutoResetEvent.Wait###() to wait for the WaitHandle to be triggered. Then you trigger it from the other thread using myAutoReserEvent.Set().

You can also wait for "any of the following WaitHandles" to be set. We use this in the GoBus UART transport (C# implementation). The frame-sending code waits to be signaled that an ACK or a data frame needs to be sent (two different WaitHandles) and when either occurs it creates the packets on its thread, queues them up, and then returns to the wait state.

BTW, thank you for buying and reading my book :) I'm really glad it's been useful for you!

Chris

#7 NooM

NooM

    Advanced Member

  • Members
  • PipPipPip
  • 490 posts
  • LocationAustria

Posted 21 October 2012 - 12:49 AM

well for me its not complex. i implemented an Update(Timespan Elapsed) funtion in all objects (classes) i needed it. this i call than from my main loop. in the update funtion in each object i handle how much time is elapsed (uses anohter timespan) my stm32f4 chip runs now with 5600 updates per second, and still drives a led matrix (8x8) if you wanna look at my timecounter object, feel free todo so. (updatecounter also included) (even if i just use it for scrolling here) http://forums.netdui...913-led-matrix/ //edit: i work with interrupts too. for input i like that very much, and i changed my trackball to a chip wich supports interrupts, so i dont have to poll it all the time

#8 Dan Kowalczyk

Dan Kowalczyk

    Advanced Member

  • Members
  • PipPipPip
  • 44 posts
  • LocationSeattle

Posted 22 October 2012 - 03:49 AM


The most popular WaitHandle is AutoResetEvent. This is useful for when you want one thread to wait on an action to occur in another thread. You basically just call myAutoResetEvent.Wait###() to wait for the WaitHandle to be triggered. Then you trigger it from the other thread using myAutoResetEvent.Set().


I will try experimenting with this pattern. I'm just starting with Threading, but this gives me a good direction to head.


BTW, thank you for buying and reading my book :) I'm really glad it's been useful for you!

Chris


You're welcome! I'm very happy to find a tool that brings together so many of my passions and interests. Thanks for helping me learn to use it.
If you want a treat and don't mind the treatment...

#9 Dan Kowalczyk

Dan Kowalczyk

    Advanced Member

  • Members
  • PipPipPip
  • 44 posts
  • LocationSeattle

Posted 22 October 2012 - 04:08 AM

if you wanna look at my timecounter object, feel free todo so. (updatecounter also included)
(even if i just use it for scrolling here)
http://forums.netdui...913-led-matrix/


That project is impressive. I'm going to look into the source code when I have a bit more time. I want to understand better how you're calculating the elapsed time and utilizing it.

my stm32f4 chip runs now with 5600 updates per second, and still drives a led matrix (8x8)


How did you clock the number of updates per second?
If you want a treat and don't mind the treatment...

#10 Dan Kowalczyk

Dan Kowalczyk

    Advanced Member

  • Members
  • PipPipPip
  • 44 posts
  • LocationSeattle

Posted 22 October 2012 - 04:18 AM

Yes, that is true. ADCs aren't interrupt based, but you can emulate this by polling them from time to time.


By the way, how is emulating interrupts different from an actual interrupt? Are they better optimized? And how? From my use of InterruptPort for buttons, it seems like the edge behavior is being analyzed similarly to how you're describing I would analyze an ADC signal.
If you want a treat and don't mind the treatment...

#11 Dan Kowalczyk

Dan Kowalczyk

    Advanced Member

  • Members
  • PipPipPip
  • 44 posts
  • LocationSeattle

Posted 22 October 2012 - 11:21 PM

I found some information on XNA game programming through the O'Reilly book on it called Learning XNA. It has a section that talks a little bit about polling that is relevant to my most recent questions.

In contrast [to event driven programs], game development is driven by polling for events, rather than waiting to
hear that an event has taken place. Instead of the system telling the game that the user
has moved the mouse, for example, your game will have to ask the system whether the
mouse has moved. In the meantime, the application is always performing actions, re-
gardless of user input.


The author also says that:

In reality, all applications are built with loops that function in similar
ways to a game loop. Windows itself uses a messaging and events system
that constantly loops and lets applications know when they need to
repaint themselves and perform other functions. Access to these loops
is hidden by default, however, because most applications don’t require
access to such nonuser-driven events.


Thanks for leading me to these ideas. Hope they will help others pattern their work. If anyone has more experience and would like to add, this is still an open discussion.
If you want a treat and don't mind the treatment...

#12 Chris Walker

Chris Walker

    Secret Labs Staff

  • Moderators
  • 7767 posts
  • LocationNew York, NY

Posted 23 October 2012 - 05:25 AM

By the way, how is emulating interrupts different from an actual interrupt? Are they better optimized? And how? From my use of InterruptPort for buttons, it seems like the edge behavior is being analyzed similarly to how you're describing I would analyze an ADC signal.

Hardware-based interrupts are very very fast. You can capture very quick changes in level which could be missed by a software-emulated interrupt. And software-emulated interrupts can take a while to be polled and, therefore, surfaced to your application.

Chris

#13 Coding Smackdown

Coding Smackdown

    Advanced Member

  • Members
  • PipPipPip
  • 78 posts
  • LocationLewisville, TX USA

Posted 24 October 2012 - 02:23 PM

My Netduino based Brew Controller uses both interrupts and threads and would probably be a good example for you to see one way of doing things. I use interrupts to handle the main panel buttons and I use threads to handle the various services; temperature monitoring, mash profile, web Server, Internet Time Service and NETBIOS Services. You can find the complete code over at https://github.com/l...yBrewController Hope it helps.
Brewing Award Winning Beer with a Netduino!
http://diybrewery.com

#14 Dan Kowalczyk

Dan Kowalczyk

    Advanced Member

  • Members
  • PipPipPip
  • 44 posts
  • LocationSeattle

Posted 24 October 2012 - 09:22 PM

Thanks for sharing your project with me!
If you want a treat and don't mind the treatment...




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.