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.
See if this is any better, I already put my logic analyzer away.
Imports Microsoft.SPOT
Imports Microsoft.SPOT.Hardware
Imports SecretLabs.NETMF.Hardware
Imports SecretLabs.NETMF.Hardware.NetduinoPlus
Module Module1
Dim led1 As New OutputPort(Pins.GPIO_PIN_D0, False)
Dim led2 As New OutputPort(Pins.GPIO_PIN_D1, False)
Dim led3 As New OutputPort(Pins.GPIO_PIN_D2, False)
Dim led4 As New OutputPort(Pins.GPIO_PIN_D3, False)
Private _thread1Wait As AutoResetEvent
Private _thread2Wait As AutoResetEvent
Private _thread3Wait As AutoResetEvent
Private _threadX As Thread
Private _threadY As Thread
Private _threadZ As Thread
Sub Main()
_thread1Wait = New AutoResetEvent(False)
_thread2Wait = New AutoResetEvent(False)
_thread3Wait = New AutoResetEvent(False)
_threadX = New Thread(AddressOf led1t)
_threadY = New Thread(AddressOf led2t)
_threadZ = New Thread(AddressOf led3t)
_threadX.Start()
_threadY.Start()
_threadZ.Start()
_thread1Wait.Set()
_thread2Wait.Set()
_thread3Wait.Set()
System.Threading.WaitHandle.WaitAll(New System.Threading.AutoResetEvent() {_thread1Wait, _thread2Wait, _thread3Wait})
led4.Write(True)
Thread.Sleep(Timeout.Infinite) ' Call this here or your program will exit..
End Sub
Sub led1t()
_thread1Wait.WaitOne()
Dim x As Integer = 0
While x < 30
x += 1
led1.Write(True)
Thread.Sleep(25)
led1.Write(False)
Thread.Sleep(25)
Debug.Print("Led1 Blink Count = " & x.ToString)
End While
_thread1Wait.Set()
_threadZ.Join()
End Sub
Sub led2t()
_thread2Wait.WaitOne()
Dim y As Integer = 0
While y < 15
y += 1
led2.Write(True)
Thread.Sleep(25)
led2.Write(False)
Thread.Sleep(25)
Debug.Print("Led2 Blink Count = " & y.ToString)
End While
_thread2Wait.Set()
_threadZ.Join()
End Sub
Sub led3t()
_thread3Wait.WaitOne()
Dim z As Integer = 0
While z < 55
z += 1
led3.Write(True)
Thread.Sleep(25)
led3.Write(False)
Thread.Sleep(25)
Debug.Print("Led3 Blink Count = " & z.ToString)
End While
_thread3Wait.Set()
End Sub
End Module
I have this code that blinks 3 LED's at the same time and also counts a value in each thread.
The problem is when I deploy the project and everything starts running the LED's are out of sync and i get pauses whenever a value is reached until I push the reset button on the Netduino then everything runs as expected, but then I lose the ability to monitor the values in the debugger. Am I missing something or is this a glitch in .NETMF
Code Below
Imports Microsoft.SPOT
Imports Microsoft.SPOT.Hardware
Imports SecretLabs.NETMF.Hardware
Imports SecretLabs.NETMF.Hardware.Netduino
Module Module1
Dim led1 As New OutputPort(Pins.GPIO_PIN_D0, False)
Dim led2 As New OutputPort(Pins.GPIO_PIN_D1, False)
Dim led3 As New OutputPort(Pins.GPIO_PIN_D2, False)
Dim led4 As New OutputPort(Pins.GPIO_PIN_D3, False)
Public led1done As Boolean = False
Public led2done As Boolean = False
Public led3done As Boolean = False
Sub Main()
Dim x As New Thread(AddressOf led1t)
Dim y As New Thread(AddressOf led2t)
Dim z As New Thread(AddressOf led3t)
Dim Done As New Thread(AddressOf DBit)
x.Start()
y.Start()
z.Start()
Done.Start()
End Sub
Sub led1t()
Dim x As Integer = 0
While x < 30
x += 1
led1.Write(True)
Thread.Sleep(25)
led1.Write(False)
Thread.Sleep(25)
Debug.Print("Led1 Blink Count = " & x.ToString)
If x = 30 Then led1done = True
End While
End Sub
Sub led2t()
Dim y As Integer = 0
While y < 15
y += 1
led2.Write(True)
Thread.Sleep(25)
led2.Write(False)
Thread.Sleep(25)
Debug.Print("Led2 Blink Count = " & y.ToString)
If y = 15 Then led2done = True
End While
End Sub
Sub led3t()
Dim z As Integer = 0
While z < 55
z += 1
led3.Write(True)
Thread.Sleep(25)
led3.Write(False)
Thread.Sleep(25)
Debug.Print("Led3 Blink Count = " & z.ToString)
If z = 55 Then led3done = True
End While
End Sub
Sub DBit()
While True
If led1done And led2done And led3done = True Then
led4.Write(True)
Thread.Sleep(Timeout.Infinite)
End If
End While
End Sub
End Module
Ok, you have a few things going on here, mainly your program is exiting as soon as it initializes everything
In your sub main you need to add Thread.Sleep(Timeout.Infinite) or the app will exit and I am pretty sure the CLR will dump it.
Also your threads are scoped locally, so even if the CLR does not dump they are falling out of scope, and the GC more than likely will collect them.
More of a stylistic, there is no need for the 4th thread, and using a ManualResetEvent for thread synchronization is a much better mechanism than a boolean. also you do not need to check if you reached your max value every loop of the while, the while will auto exit when it has reached its exit condition, so you can put your thread finished notification outside of the loop saving cpu cycles.
Here is a quick sample I pulled together for you (cannot run because I am at work, but looks correct)
Imports System.Threading
Imports Microsoft.SPOT
Imports Microsoft.SPOT.Hardware
Imports SecretLabs.NETMF.Hardware
Imports SecretLabs.NETMF.Hardware.Netduino
Module Module1
Dim led1 As New OutputPort(Pins.GPIO_PIN_D0, False)
Dim led2 As New OutputPort(Pins.GPIO_PIN_D1, False)
Dim led3 As New OutputPort(Pins.GPIO_PIN_D2, False)
Private _thread1Wait As ManualResetEvent
Private _thread2Wait As ManualResetEvent
Private _thread3Wait As ManualResetEvent
Private _threadX As Thread
Private _threadY As Thread
Private _threadZ As Thread
Sub Main()
_thread1Wait = New ManualResetEvent(False)
_thread2Wait = New ManualResetEvent(False)
_thread3Wait = New ManualResetEvent(False)
_threadX = New Thread(AddressOf led1t)
_threadY = New Thread(AddressOf led2t)
_threadZ = New Thread(AddressOf led3t)
_threadX.Start()
_threadY.Start()
_threadZ.Start()
System.Threading.WaitHandle.WaitAll(New System.Threading.ManualResetEvent() {_thread1Wait, _thread2Wait, _thread3Wait})
led4.Write(True)
Thread.Sleep(Timeout.Infinite) ' Call this here or your program will exit..
End Sub
Sub led1t()
Dim x As Integer = 0
While x < 30
x += 1
led1.Write(True)
Thread.Sleep(25)
led1.Write(False)
Thread.Sleep(25)
Debug.Print("Led1 Blink Count = " & x.ToString)
End While
_thread1Wait.Set()
End Sub
Sub led2t()
Dim y As Integer = 0
While y < 15
y += 1
led2.Write(True)
Thread.Sleep(25)
led2.Write(False)
Thread.Sleep(25)
Debug.Print("Led2 Blink Count = " & y.ToString)
End While
_thread1Wait.Set()
End Sub
Sub led3t()
Dim z As Integer = 0
While z < 55
z += 1
led3.Write(True)
Thread.Sleep(25)
led3.Write(False)
Thread.Sleep(25)
Debug.Print("Led3 Blink Count = " & z.ToString)
End While
_thread1Wait.Set()
End Sub
End Module
thanks for making some corrections but unfortunately your code does the same thing as mines. I uploaded a video showing what it does right at deploy and then after a reset (what i want it to do ).
There is quite a bit of overhead required for creating a thread, and starting it so I synchronized the thread start of execution by making the threads wait until all of them were started and in the running state.
Imports Microsoft.SPOT
Imports Microsoft.SPOT.Hardware
Imports SecretLabs.NETMF.Hardware
Imports SecretLabs.NETMF.Hardware.Netduino
Module Module1
Dim led1 As New OutputPort(Pins.GPIO_PIN_D0, False)
Dim led2 As New OutputPort(Pins.GPIO_PIN_D1, False)
Dim led3 As New OutputPort(Pins.GPIO_PIN_D2, False)
Dim led4 As New OutputPort(Pins.GPIO_PIN_D3, False)
Private _thread1Wait As AutoResetEvent
Private _thread2Wait As AutoResetEvent
Private _thread3Wait As AutoResetEvent
Private _threadX As Thread
Private _threadY As Thread
Private _threadZ As Thread
Sub Main()
_thread1Wait = New AutoResetEvent(False)
_thread2Wait = New AutoResetEvent(False)
_thread3Wait = New AutoResetEvent(False)
_threadX = New Thread(AddressOf led1t)
_threadY = New Thread(AddressOf led2t)
_threadZ = New Thread(AddressOf led3t)
_threadX.Start()
_threadY.Start()
_threadZ.Start()
_thread1Wait.Set()
_thread2Wait.Set()
_thread3Wait.Set()
System.Threading.WaitHandle.WaitAll(New System.Threading.AutoResetEvent() {_thread1Wait, _thread2Wait, _thread3Wait})
led4.Write(True)
Thread.Sleep(Timeout.Infinite) ' Call this here or your program will exit..
End Sub
Sub led1t()
_thread1Wait.WaitOne()
Dim x As Integer = 0
While x < 30
x += 1
led1.Write(True)
Thread.Sleep(25)
led1.Write(False)
Thread.Sleep(25)
Debug.Print("Led1 Blink Count = " & x.ToString)
End While
_thread1Wait.Set()
End Sub
Sub led2t()
_thread2Wait.WaitOne()
Dim y As Integer = 0
While y < 15
y += 1
led2.Write(True)
Thread.Sleep(25)
led2.Write(False)
Thread.Sleep(25)
Debug.Print("Led2 Blink Count = " & y.ToString)
End While
_thread2Wait.Set()
End Sub
Sub led3t()
_thread3Wait.WaitOne()
Dim z As Integer = 0
While z < 55
z += 1
led3.Write(True)
Thread.Sleep(25)
led3.Write(False)
Thread.Sleep(25)
Debug.Print("Led3 Blink Count = " & z.ToString)
End While
_thread3Wait.Set()
End Sub
End Module
Just expecting for all leds blink at the same time after deploying without resetting the netduino.In the first half of the video you can see that the leds aren't flashing at the same time, (whice is the part I don't want).
In the second half of the video I press the reset button and then you can see all the leds flashing in sync that's what I want right from the get go not needing to reset the netduino
Something else to keep in mind, .NetMF is not a real time OS, there are no exact timing guarantees. Sleep(25) just means that the thread will sleep for no less than 25ms, but it could take a little bit longer depending what the CPU is doing. That and the fact that these devices are single core devices so even though you can create threads only one can actually run at a time, the rest is handled by the thread scheduler.
Alright tested your new code it deploys and runs as expected (blinks 3 LEDS at the same time) but after led2 reaches count it goes out of sync again. I read up about the timing on .netmf I was just testing some multi threading for fun, but I guess I can scrap the code now since I cant get it working. Thanks for your effort !
What would be an alternate way of flashing 3 leds in sync if I may ask. Is there another route?
I think what you are seeing is the thread exiting, you can even fix that still by having it Join the other threads so they do not exit until all of them are done....
You could try putting them in one thread and using one loop.
You could connect the LEDs to a shift register and use SPI to control it (I actually this one on a bigger project I am doing)
I just took a look at you pic. After observing I can see in the middle section on channel 0 and channel 2 that it goes out of sync Ch0 starts high and ch 2 starts low causing the ping pong light effect. I'm guessing the timing is causing this ?
See if this is any better, I already put my logic analyzer away.
Imports Microsoft.SPOT
Imports Microsoft.SPOT.Hardware
Imports SecretLabs.NETMF.Hardware
Imports SecretLabs.NETMF.Hardware.NetduinoPlus
Module Module1
Dim led1 As New OutputPort(Pins.GPIO_PIN_D0, False)
Dim led2 As New OutputPort(Pins.GPIO_PIN_D1, False)
Dim led3 As New OutputPort(Pins.GPIO_PIN_D2, False)
Dim led4 As New OutputPort(Pins.GPIO_PIN_D3, False)
Private _thread1Wait As AutoResetEvent
Private _thread2Wait As AutoResetEvent
Private _thread3Wait As AutoResetEvent
Private _threadX As Thread
Private _threadY As Thread
Private _threadZ As Thread
Sub Main()
_thread1Wait = New AutoResetEvent(False)
_thread2Wait = New AutoResetEvent(False)
_thread3Wait = New AutoResetEvent(False)
_threadX = New Thread(AddressOf led1t)
_threadY = New Thread(AddressOf led2t)
_threadZ = New Thread(AddressOf led3t)
_threadX.Start()
_threadY.Start()
_threadZ.Start()
_thread1Wait.Set()
_thread2Wait.Set()
_thread3Wait.Set()
System.Threading.WaitHandle.WaitAll(New System.Threading.AutoResetEvent() {_thread1Wait, _thread2Wait, _thread3Wait})
led4.Write(True)
Thread.Sleep(Timeout.Infinite) ' Call this here or your program will exit..
End Sub
Sub led1t()
_thread1Wait.WaitOne()
Dim x As Integer = 0
While x < 30
x += 1
led1.Write(True)
Thread.Sleep(25)
led1.Write(False)
Thread.Sleep(25)
Debug.Print("Led1 Blink Count = " & x.ToString)
End While
_thread1Wait.Set()
_threadZ.Join()
End Sub
Sub led2t()
_thread2Wait.WaitOne()
Dim y As Integer = 0
While y < 15
y += 1
led2.Write(True)
Thread.Sleep(25)
led2.Write(False)
Thread.Sleep(25)
Debug.Print("Led2 Blink Count = " & y.ToString)
End While
_thread2Wait.Set()
_threadZ.Join()
End Sub
Sub led3t()
_thread3Wait.WaitOne()
Dim z As Integer = 0
While z < 55
z += 1
led3.Write(True)
Thread.Sleep(25)
led3.Write(False)
Thread.Sleep(25)
Debug.Print("Led3 Blink Count = " & z.ToString)
End While
_thread3Wait.Set()
End Sub
End Module
If you look carefully you see the pauses are directly correlated to when another channel is finished, the CLR has to cleanup the thread and notify the debugger. When you hit reset the debugger is not attached, so the overhead of notifying the debugger that the thread exited and releasing the debugging hooks is not incurred.
I just took a look at you pic. After observing I can see in the middle section on channel 0 and channel 2 that it goes out of sync Ch0 starts high and ch 2 starts low causing the ping pong light effect. I'm guessing the timing is causing this ?
You could do that with a shift register easily, you write a byte to the SPI bus. Each bit of that byte represents the desired state of one of the 8 output pins, it latches them all at the exact time, and you can get very fast timings out of the SPI bus. You would just have to use some bit wise logic and thinking to determine which motor to turn on if you wanted them to step in sync but at different duty cycles.
I was thinking about controlling 3 steppers motors and having them receive the same step pulses in sync.
If you look at the last line in in led1t and led2t they do a .Join on _threadZ
A join causes the existing thread to block until the Joined thread exits. This causes the overhead of the thread exit cleanup by the CLR, etc to be delayed until the timing cycle is complete.
It basically puts thread 1 and 2 into a wait state, and they wake up and execute the next line when the Joined thread exits.
You very well could have continued executing code in thread 1 and 2 after the join.
It just so happens that the next line of code in those methods is the exit sub, which signals to the CLR that the threads are finished and it can clean them up.
Edit: in this case we could have gotten the exact same results by calling _thread3Wait.WaitOne()
So in short it just tells thread1 and 2 to hop into the other timing cycle until Thread z is done then the CLR kicks in?