Hello Everyone,
Im trying to build a Vj project driven by a six channel maestro. It works with beat measurement, this is the calculation:
(Beats per minute / 60 seconds) - Servo turning time = Servo Pausing time
Both turning time and pausing time are used by timers which holds and starts the servo on the beat, Servo turning time is a variable because of the various types of servos. Im using visual basic.
The problem is that with everytime my loop is completed the turning time adds up until my maestro crashes, it simply will take no more commands.
The standard polulu software allows you to delay every single command you give it instead of setting TrySetTarget() is this also possible with VB/C?
Here is my code
Sub Turn()
If Stoploop = 0 Then
aTimer.Enabled = False
TrySetTarget(0, 4000)
aTimer.Enabled = True
aTimer.Interval = 2000
aTimer.AutoReset = True
bTimer.Enabled = True
bTimer.Interval = 1000
AddHandler bTimer.Elapsed, AddressOf Pauseshit
AddHandler aTimer.Elapsed, AddressOf Turn
Sleep(1000)
End If
End Sub
Sub Pauseshit()
TrySetTarget(0, 0)
bTimer.Enabled = False
End Sub
Forgot this one: its a continious rotation servo
The units of your formula look wrong the way you wrote them. The quantity “beats per minute / 60 seconds” would have units of 1/time^2, but you are subtracting a time from it. What are you really trying to do?
Could you please simplify your program down to the simplest thing that demonstrates the problem and then post your entire code? You posted the definitions of two subroutines but you didn’t post the code that actually calls the subroutines. You didn’t post the definitions of either of the timers so I don’t know which of the three .NET timer classes you are using.
What do you mean by “my Maestro crashes, it simply will take no more commands”. How do you know the Maestro crashed and not your program? What is the expected behavior of your system and what is the actual behavior?
Yes, it is possible to write VB or C programs that have delays.
–David
Ehm, im sorry maybe my english is a bit poor.
First id like to explain that dividing the BPM through seconds is impossible because the amount of beats per second would be >1. It would mean you have less then one second to turn the screen, pause it and make a new projection on it. Therefor i’m dividing the BPM through 2 or 4.
And of course its 60 seconds / BPM instead of BPM / 60 Seconds
But the question is; is there a way to use this format directly in VB, it would make writing different turning patterns much easier
begin
4000 0 servo # set servo 0 to 1.00 ms
500 delay
5000 0 servo # 1.25 ms
500 delay
6000 0 servo # 1.50 ms
500 delay
7000 0 servo # 1.75 ms
500 delay
8000 0 servo # 2.00 ms
500 delay
repeat
For now id like to use 1 second delays just to test the script, the calculations with BPM arent used yet. I’d tried the following timer methods in VB
Public Declare Function GetTickCount Lib "kernel32" () As Long
Dim t As new Timer
Both do more or less the same; when the script starts it makes rotations for 1 second and after that it pauses for 1 second. Then the loop starts again and the turning time increases with every loop until i get a message like: Connection denied through device.
A VB example with two timers would be nice, because i dont understand why this happens
Fixed
Private Shared Timer1 As New System.Timers.Timer
Private Shared Timer2 As New System.Timers.Timer
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
TimerOn()
End Sub
Public Sub TimerOn()
Timer1.Interval = 10000
Timer1.Enabled = True
Timer1.AutoReset = True
AddHandler Timer1.Elapsed, AddressOf TimerinTimer
AddHandler Timer1.Elapsed, AddressOf OnTimedEvent
End Sub
Sub OnTimedEvent()
MessageBox.Show("Tick")
End Sub
Sub TimerinTimer()
Timer2.Interval = 3000
Timer2.Enabled = True
AddHandler Timer2.Elapsed, AddressOf OnTimedEvent2
End Sub
Sub OnTimedEvent2()
Timer2.Enabled = False
MessageBox.Show("Tick2")
End Sub
By adding TrySetTarget() to OnTimedEvent and OnTimedEvent2, might be useful?
I’m glad you were able to fix your problem. --David
Another problem:
Now my timer code is working, but my maestro throws: access was denied when trying to connect to device. I’ve read that it could be the maestro pulling to much power from the USB Port, I already set USB Dual Port.
Leds are dimming on servoactions but are not going completely out.
It works like this:
Starting looped timer ->starting timer 2-> Trysettarget(0,8000) -> timer 2 elapsed -> TrySetTarget(0,0) -> Looped timer elapsed… Starts all over
im using the example functions TrySetTarget which is using the Using/End Using block. Am i overloading this function?
Is it necessary to attach 12V to the maestro board to solve this problem?
You will get an access denied error if you try to open/connect to the native USB interface of a Maestro when it is already opened by another program or by another part of your program. This has nothing to do with the Maestro pulling too much power from the USB port and it has nothing to do with setting the serial mode to USB Dual Port.
You need to write your code to ensure that you don’t call TrySetTarget at the same time in two different threads. Only one handle to the Maestro’s native USB interface can be open at a time, so the second thread that tries to open a handle to the Maestro will get an access denied error. The easiest way to satisfy this requirement is to use System.Windows.Forms.Timer instead of System.Timers.Timer because the former will run all your event handlers in the UI thread. For more information, read:
msdn.microsoft.com/en-us/magazine/cc164015.aspx
It’s unlikely that you are overloading TrySetTarget, but I think your problem is that you are calling it at the same time in two different threads. Attaching 12 V to the Maestro board will not solve this problem.
–David