I have two Freedom boards attached to my computer each using Segger/JLink Comm Plugin (with different serial numbers). I have a Freemaster project for each of these boards (ProjectFile1, ProjectFile2), and I can run both projects at the same time and communicate with board boards with no issues.
I also have a working VB program that uses the FreeMASTER ActiveX library (3.1.1.6) to open one of these projects and communicate with one of the boards:
pcm1 = New McbPcmLib.McbPcm
pcm1.OpenProject(ProjectFile1)
and this works perfectly.
However, if I add another instance:
pcm2 = New McbPcmLib.McbPcm
pcm2.OpenProject(projfile2)
it replaces the first instance of Freemaster with the second one.
Is there a way to start the second instance from the VB program without loosing the first one?
Solved! Go to Solution.
Dear Barry,
thank you for your effort when testing this case in your Visual Basic application. Let me summarize the features of the MCB.MULT object and what is working and what is not working in FreeMASTER 3.1.2:
The same experiment with Visual Basic for Applications (VBA) in Excel shows that the MCB.MULT access to system’s Running Object Table is limited in this framework. VBA apparently cannot fetch the objects registered under so-called “objref monikers”. This is the reason the VB code below will NOT work in VBA with FreeMASTER 3.1.2.
Changes to be included in FreeMASTER 3.1.3:
Below, you can see a screenshot of a simple VB project edited in Visual Studio 2019. Pay special attention to highlighted parts. The full code snippet is also copied below.
Thank you again for your cooperation,
Michal
Private Sub OnTest1(sender As Object, e As EventArgs) Handles ButtonTest1.Click
' add the following COM Dependencies:
' McbPcmLib as FreeMASTER ActiveX Type Library
' McbMultLib - browse for mmaster.dll in FreeMASTER installation
Dim mult As McbMultLib.IMcbMult
Dim a, b As McbPcmLib.IMcbPcm
Dim vVal, tVal, msg As Object
mult = New McbMultLib.McbMult
' see pcmaster.exe /help for startup flags
' &H01=start freemaster if needed
' &H10=close port, &H20=open port
a = mult.GetAppObject("A", &H21)
b = mult.GetAppObject("B", &H11)
' wait up to 10 seconds for instance fully initialized
' this step should not be needed in FreeMASTER 3.1.3 anymore
For i = 1 To 10
If IsNothing(a) Or IsNothing(b) Then
Threading.Thread.Sleep(1000)
a = mult.GetAppObject("A")
b = mult.GetAppObject("B")
Else
Exit For
End If
Next
' both instances should be valid now
If IsNothing(a) Or IsNothing(b) Then
MsgBox("Error: timeout when connecting to FreeMASTER")
Exit Sub
End If
' open port and load example project (assuming fmstr_uart default demo app)
a.StartStopComm(True)
a.OpenProject("fmstr://demo.pmp.zip")
' read variable from the running instance
If a.ReadVariable("var16", vVal, tVal, msg) <> 0 Then
MsgBox("From instance a " + tVal)
Else
MsgBox(msg)
End If
' exit both instances
a.Exit()
b.Exit()
End Sub
Hello,
yes, the COM+/ActiveX object creation always looks up the first running instance so there is no direct way how to specify that you want a different one. Actually, there are two solutions.
The first and a recommended one is to use JSON-RPC interface instead of ActiveX (refer to user documentation and online webinars for more information). When you start the FreeMASTER process (pcmaster.exe), you can specify a TCP/WebSocket port it will listen on using /rpcs PORT command-line option. The default port is 41000. You would assign a different port to your 2nd instance and your two JSON-RPC clients would then connect to each server individually.
The 2nd solution enables to stay with an ActiveX technology so it is more suitable for VB and VBA, but using it is quite tricky. This is also a reason why it remains as an experimental feature and is only partly documented - see User Guide section 6.9. Also, the official release currently only supports 32bit clients (like Internet Explorer). We have the 64bit support ready internally, I can share it with you if needed. But let me give you the whole story first:
<OBJECT id="mult" name="mult" height="1" width="1"
classid="clsid:A8E26DF5-85A1-4552-AD0E-6C8AA10641EA">
</OBJECT>
<script>
pcmA = mult.GetAppObject(“A”);
pcmB = mult.GetAppObject(“B”);
</script>
Issues and limitations:
Sub mmult_test()
Dim a As McbPcm
Dim b As McbPcm
Dim mult As McbMult
Set mult = New McbMult
Set a = mult.GetAppObject("A")
Set b = mult.GetAppObject("B")
If a.ReadVariable("var16", v1, t1, m1) Then
MsgBox ("Variable from instance A " + t1)
Else
MsgBox ("Error reading from instance A: " + m1)
End If
If b.ReadVariable("var16", v2, t2, m2) Then
MsgBox ("Variable from instance B " + t2)
Else
MsgBox ("Error reading from instance B: " + m2)
End If
End Sub
Regards,
Michal
Dear Barry,
thank you for your effort when testing this case in your Visual Basic application. Let me summarize the features of the MCB.MULT object and what is working and what is not working in FreeMASTER 3.1.2:
The same experiment with Visual Basic for Applications (VBA) in Excel shows that the MCB.MULT access to system’s Running Object Table is limited in this framework. VBA apparently cannot fetch the objects registered under so-called “objref monikers”. This is the reason the VB code below will NOT work in VBA with FreeMASTER 3.1.2.
Changes to be included in FreeMASTER 3.1.3:
Below, you can see a screenshot of a simple VB project edited in Visual Studio 2019. Pay special attention to highlighted parts. The full code snippet is also copied below.
Thank you again for your cooperation,
Michal
Private Sub OnTest1(sender As Object, e As EventArgs) Handles ButtonTest1.Click
' add the following COM Dependencies:
' McbPcmLib as FreeMASTER ActiveX Type Library
' McbMultLib - browse for mmaster.dll in FreeMASTER installation
Dim mult As McbMultLib.IMcbMult
Dim a, b As McbPcmLib.IMcbPcm
Dim vVal, tVal, msg As Object
mult = New McbMultLib.McbMult
' see pcmaster.exe /help for startup flags
' &H01=start freemaster if needed
' &H10=close port, &H20=open port
a = mult.GetAppObject("A", &H21)
b = mult.GetAppObject("B", &H11)
' wait up to 10 seconds for instance fully initialized
' this step should not be needed in FreeMASTER 3.1.3 anymore
For i = 1 To 10
If IsNothing(a) Or IsNothing(b) Then
Threading.Thread.Sleep(1000)
a = mult.GetAppObject("A")
b = mult.GetAppObject("B")
Else
Exit For
End If
Next
' both instances should be valid now
If IsNothing(a) Or IsNothing(b) Then
MsgBox("Error: timeout when connecting to FreeMASTER")
Exit Sub
End If
' open port and load example project (assuming fmstr_uart default demo app)
a.StartStopComm(True)
a.OpenProject("fmstr://demo.pmp.zip")
' read variable from the running instance
If a.ReadVariable("var16", vVal, tVal, msg) <> 0 Then
MsgBox("From instance a " + tVal)
Else
MsgBox(msg)
End If
' exit both instances
a.Exit()
b.Exit()
End Sub
Michal,
Thank you very much for your quick and thorough responses. I have it working now and I am looking forward to the new releases.
Barry