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.

Anshul's Content

There have been 15 items by Anshul (Search limited from 29-March 23)


By content type

See this member's

Sort by                Order  

#51187 Proper way to multithread on Netduino

Posted by Anshul on 08 July 2013 - 05:40 AM in Netduino 2 (and Netduino 1)

I have seen a few ways to do multithreading, and after reading a few posts on here I'm still unsure of what is the "correct" way to do multithreading. Specifically, I'm concerned with threads that will be monitoring inputs by constantly reading them and updating some output (like a brightness meter). 

 

Way 1 is to have a thread and have a while (true) loop in there with a Thread.Sleep(1) and the polling code. I have noticed that if I don't put a Thread.Sleep(1) in there, the debugger stops responding and there's no way to get Visual Studio to attach to the debugger without erasing the current program. (My guess is that the main CLR thread doesn't get enough time to both interrupt VS while it's waiting for the CLR debugger and receive the attach message from VS. But if we put Thread.Sleep(1) in the polling thread, the main CLR thread would get a lot more time to run while the polling thread is sleeping and is able to interrupt VS and also receive the attach message (or debugging symbols).)

 

Way 2 is from http://forums.netdui...ring-whileloop/. One of the responses was as follows:

 

 

[color=rgb(164,164,164);font-family:helvetica, arial, sans-serif;]Posted [/color]21 February 2013 - 09:18 AM

Hi Ties,

The way that threads work in NETMF is that each thread gets up to ~10ms to execute before the thread scheduler pulls the execution to another thread. In order to make sure that interrupts are fired in sequence, NETMF queues and timestamps them...and then fires them off in order.

In multi-threaded and interrupt-driven apps, we generally avoid loops or any action that ties up the processor for long periods of time. But if you'd like to run long loops for threads, you'll probably want to create a thread and launch it there. With the newer versions of .NET MF, you can even use anonymous methods to launch code on another thread "in-line" in your code.

You can also create background threads for each of your tasks and then have them wait on an AutoResetEvent waithandle. Then when your interrupt gets fired, just Set the waithandle and your background thread will come to life. This also helps keep thread count down and prevent unintentional re-entry.

There are a massive number of powertools available in the C# language and NETMF, so there should be one that's great for the application at hand. We're happy to help guide the selection process.

Chris

 

My question is what does "background threads" mean in the context of this message? I cannot find the class BackgroundThread in NETMF, so was wondering if setting the priority of the thread to BelowNormal or Lowest makes it a background thread? Would a background thread also require a Thread.Sleep(1) in its while loop? (Side question: How do you create a thread "in-line", as mentioned in the quote above?)

 

Those are the two ways that I'm aware of. I'd love to hear more suggestions, and also thoughts about which threading methods are suited for what applications (polling an input, blinking an LED, etc.)




#51222 Main Thread Hangs

Posted by Anshul on 08 July 2013 - 05:56 PM in Netduino Plus 2 (and Netduino Plus 1)

 

iam with nevyn, your main problem is the end of your main thread, in your code there is no loop.

 

or what does output0.Flash(); do ?

 

 

The main thread doesn't end, it goes in an infinite loop because output0.Flash() does the same thing as the other threads, either method 1 or method 2 whichever OP is using.

 

 

 

@banalogic: Have you figured out why the main thread does not get an execution cycles? I've noticed that when my main thread goes into a tight infinite loop (tight = no Thread.Sleep(n) in the loop), it doesn't even respond to the Visual Studio debugger. Only option is to erase the program by going into bootloader mode and then reconnect it to the computer.




#51223 Proper way to multithread on Netduino

Posted by Anshul on 08 July 2013 - 06:07 PM in Netduino 2 (and Netduino 1)

Hi!

 

There's no special class for "Background threads", they are the same as any System.Threading.Thread. In the post you refer to, the term is used to denote a Thread who's purpose is to process data produced by an interrupt service routine (ISR) in order to avoid lenghty operations in the ISR itself.

 

The AutoResetEvent is used to have the "background thread" wait for a signal before going to work. It's a good example of the common producer/consumer pattern where the ISR is the producer and the background thread is the consumer.

 

You can use a System.Connections.Queue object for the ISR to quickly tuck work items away (using the Enqueue method) to be processed by the background thread (using the dequeue method) at a slightly later point in time.

 

Yes, the background thread would typically run a while loop and perform a WaitOne on the AutoResetEvent as means of syncronization before dequeuing each work item for processing. When there are no items to be processed, the thread goes to sleep and will not wake up again until another work item has been enqueued. If necessary, you can use Thread.Sleep(n) to yield once in while in order not to choke the CPU degrading responsiveness of you application.

 

Hope this helps!

 

That's interesting to know. I didn't know there is already a construct in C# to handle producer/consumer scenarios. Do you know of any good examples where this is implemented using the AutoResetEvent? Any for polling an input constantly, I'm guessing an ISR is not the correct choice?




#51224 Proper way to multithread on Netduino

Posted by Anshul on 08 July 2013 - 06:09 PM in Netduino 2 (and Netduino 1)

I'd like to add to hanzibal's suggestion that also, the interrupts are delivered on an internal worker thread that runs at Highest priority.  You don't really want to do much significant work there beyond hanzi's suggestion of queueing it for further processing on other threads (I'm speaking form personal experience on that; it's confusing, then amusing, to see the rest of the system running in slo-mo just because you're doing work in a button event handler rather than handing it off).

 

Lastly, as you've observed, the first 'main' thread seems internally to have some other duties.  It also has some scheduling oddities, e.g. as reported in this thread (no pun intended):

http://forums.netdui...ngs/#entry50924

I think most folks mask that effect because they sleep, but still it's interesting to be aware of it.

 

Yeah it seems that the main thread seems to become unresponsive if another thread goes in an infinite loop. It would seem like the main thread's priority is effectively set to very low since it's not able to respond to the interrupts from the debugger (at least that's the best explanation I can come up with).




#55618 Shift register question.

Posted by Anshul on 25 January 2014 - 01:46 AM in General Discussion

Did you ever get this to work? Thanks.




#55639 PWM.SetPulse equivalent in .NETMF 4.2

Posted by Anshul on 25 January 2014 - 10:25 PM in Netduino Plus 2 (and Netduino Plus 1)

Is there a standard way of upgrading the PWM.SetPulse method from .NETMF4.1 to the newer "channel-based" PWM in .NETMF 4.2? I'm trying to port the following code:

public Tlc5940New(PWM gsclk, PWM blank, OutputPort xlat, OutputPort sin, OutputPort sclk)        {            GSCLKPin = gsclk;            BLANKPin = blank;            XLATpin = xlat;            SINPin = sin;            SCLKPin = sclk;            // Clear the channels, and disable the output            GSCLKPin.DutyCycle = 0;            BLANKPin.DutyCycle = 0;            XLATpin.Write(false);            SINPin.Write(false);            SCLKPin.Write(false);            GSCLKPin.SetPulse(gsclk_period, 1);            BLANKPin.SetPulse((gsclk_period * 4096), 1);                }

The error is happening on the lines GSCLKPin.SetPulse(gsclk_period, 1); and BLANKPin.SetPulse((gsclk_period * 4096), 1); because SetPulse is not supported by the new 4.2 libraries so I have to come up with equivalent code. I took this code from somewhere else so I do not know how exactly I should use the 4.2 PWM in place of this 4.1 code.

 

Any help is greatly appreciated.




#55644 Using the TLC5940 on .NETMF 4.2

Posted by Anshul on 25 January 2014 - 11:04 PM in Netduino Plus 2 (and Netduino Plus 1)

I have been scouring the deepest reaches of the internet for about a week trying to find a working example for using the TLC5940 16-channel PWM driver chip for dimming LED strips, but without any luck. Most of the examples are either incomplete (missing the wiring diagram) or just don't work. Here's a few examples that I couldn't get to work: 

 

1. http://forums.netdui...c/4123-tlc5940/

2. http://forums.netdui...940-pwm-driver/

 

All of these are old, so I'm fairly certain they target .NETMF 4.1. The first one didn't work (http://forums.netdui...c/4123-tlc5940/) because it uses PWM.SetPulse from .NETMF 4.1 which I tried to convert the code to 4.2, but it's still not working.

 

Here is my request: Can someone help me out with a program that simply fades an LED from 0 to full brightness and back to 0, and then repeats, using the TLC5940? 

 

Once I can get a single LED to PWM using the TLC5940, the rest of the work is already done and I have the high-power drivers for the LED strips already built. Thanks for the help.




#55659 Using the TLC5940 on .NETMF 4.2

Posted by Anshul on 26 January 2014 - 04:48 PM in Netduino Plus 2 (and Netduino Plus 1)

Do you know which chips do not require an external clock signal? The blog did have a wiring diagram but I don't have the components for creating a clock. Can you post any details on how you implemented it? Especially the wiring diagram and the basic algorithm. Thanks.



#55676 PWM.SetPulse equivalent in .NETMF 4.2

Posted by Anshul on 27 January 2014 - 01:31 AM in Netduino Plus 2 (and Netduino Plus 1)

Paul,

 

In 4.2, I believe the way to instantiate a PWM is like the following:

PWM blank = new PWM(Cpu.PWMChannel.PWM_3, 10000, 0, false);

so the Pins enumeration won't matter since it requires the PWM "channel" instead of the pin. Are you sure your statements are from 4.2? Maybe from an earlier version of 4.2? Also because it's 4.2, the SetPulse method isn't available at all, from what I'm seeing at least. Are you able to get that code to work in 4.2?




#55693 Using the TLC5940 on .NETMF 4.2

Posted by Anshul on 28 January 2014 - 02:45 AM in Netduino Plus 2 (and Netduino Plus 1)

Once this is working setup a second PWM which is a single pulse.  These pulses will occur at the greyscale clock frequency from above divided by 4096.  The pulse should be very narrow.

 

How do you do this on the Netduino in NETMF 4.2? You can change the frequency and/or period but how would you send a single pulse? 




#55694 PWM.SetPulse equivalent in .NETMF 4.2

Posted by Anshul on 28 January 2014 - 02:53 AM in Netduino Plus 2 (and Netduino Plus 1)

I'm also using a Netduino Plus v1. I am definitely using NETMF 4.2 :

 

Posted Image

 

That is a picture of the PWM reference in my project. Whenever I type in SetPulse, Visual Studio marks it as a syntax error. Could you post your using statements and check the version of the Microsoft.SPOT.Hardware.PWM assembly in your project references? I am not doubting that you are correct, I'm just trying to figure out why it won't work on my machine. 




#55715 Using the TLC5940 on .NETMF 4.2

Posted by Anshul on 29 January 2014 - 03:22 AM in Netduino Plus 2 (and Netduino Plus 1)

 

Once this is working setup a second PWM which is a single pulse.  These pulses will occur at the greyscale clock frequency from above divided by 4096.  The pulse should be very narrow.

 

 

 

Is the second PWM the latch signal?

 

I found a programming flowchart (http://www.ti.com/li...106/slvc106.pdf) that I've been following, but I'm still confused as to how exactly the values are moved inside the TLC5940. If some values are shifted out to the outputs, does that output constantly output a PWM signal with that duty cycle?

 

For example if I write out 011111111111 (binary) = 2048 (dec) = 0.5 duty cycle to the first output (OUT0), after I clock out the values by PWMing GSCLK and then pulsing the latch once, will OUT0 output a 0.5 duty cycle until something changes? That's what I thought the chip does but maybe I'm wrong.




#55718 Using the TLC5940 on .NETMF 4.2

Posted by Anshul on 29 January 2014 - 05:28 AM in Netduino Plus 2 (and Netduino Plus 1)

The second PWM signal is the "counter reset" signal.  If you do not pulse this pin then the counters start at 4095, count down to zero and then stop.  Pulsing the Blank pin tells the chip to restart.  That it why the pulses should come along every 4096 grey scale clock pulses.

 

The data is latched on the XLAT pulse.

 

Regards,

Mark

 

That clears it up a bit more. One question though, when you say that the data is latched on the XLAT pulse, is that latching the data from the serial input to the GS register or from the GS register to the outputs? 




#55726 PWM.SetPulse equivalent in .NETMF 4.2

Posted by Anshul on 29 January 2014 - 02:52 PM in Netduino Plus 2 (and Netduino Plus 1)

I see it now. Thanks for the help. Although I wanted to use this for porting some old code from 4.1 to 4.2, turns out that code is not working. So I wrote my own code and ended up not needing it at the moment :) But I will undoubtedly need it going forward and it's always good to know why there weird things are happening. 




#55727 Task Parallel Library support

Posted by Anshul on 29 January 2014 - 02:59 PM in Netduino Plus 2 (and Netduino Plus 1)

Anyone know if there are any plans to support the Task Parallel Library in NETMF? I ask because I think this could be a tremendous productivity boost with hardware programming, because hardware programming very naturally lends itself to the Task Asynchronous Pattern that's implemented by the Task Parallel Library.





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.