How do I write VB.NET program to remotely control 6060B (electric load) - vb.net

I am writing a vb.net program to remotely control the 6060B (electric load). So far I have successfully connected my pc to the 6060B and I am able to query information from the load. Below is the part of the code I wrote:
Dim mbSession As MessageBasedSession;
mbSession = ResourceManager.GetLocalManager().Open("GPIB::6::INSTR");
Dim responseString As String = mbSession.Query("*idn?");
This returns me the information of the load -- "responseString is HEWLETT-PACKARD...". However, I don't know what should I do to change/set the current, voltage ect just as I normally do from the panel. I search on the internet and I found that I could use HPSL programming language but what should I remotely control the 6060B using vb.net? I am using NI-VISA.NET API.

You need to find the command reference. There is a standard, SCPI, which has commands generally in the form
MEASure:CURRent?
Again this is a standard, and you should find the specific command reference for your device, HP (Keysight / Agilent) 6060B 300 Watt DC Electronic Load.
A search engine result for hp 6060b manual should yield some good results. Look for an operating or programming manual which usually has the command reference.
This should work for you:
' This example sets the current level to 0.75 amps
' and then reads back the actual current value.
' set input off
mbSession.Write("INPUT OFF")
' set mode to current
mbSession.Write("MODE:CURR")
' set current range
mbSession.Write("CURR:RANG 1")
' set current value
mbSession.Write("CURR 0.75")
' set input on
mbSession.Write("INPUT ON")
' measure current
Dim result As String
result = mbSession.Query("MEAS:CURR?")
Dim measuredCurrent As Single = Single.Parse(result)
Example taken from page 70 of this operating manual I found.
In general, things are usually easier if you are provided example code. I will usually use the example code to get a baseline working operation, then copy the code to my project and manipulate as needed.

Related

Word automation failing on server, but dev station works great

I am automating a oft-used paper form by querying the user on a web page, then modifying a base Word document and feeding that modified doc file to the user's browser for hand-off to Word.
The code is Visual Basic, and I am using the Microsoft.Office.Interop module to manipulate the document by manipulating Word. Works fine on the development system (Visual Studio 2015) but not on the production server (IIS 8.5).
Both the Documents.Open() call and the doc.SaveAs() call fail with Message="Command failed" Source="Microsoft Word" HResult=0x800A1066
Things I've tried:
Added debugging out the whazoo: Single-stepping is not an option on the production machine, so I pinpointed the problem lines with debug output.
Googled and found that this problem has been reported as early as 2007, but no viable solutions were reported.
A couple sites mentioned timing issues, so I added several pauses and retries -- none helped.
Some mentioned privileging, so I tried changing file permissions & application pool users -- neither helped.
Enhanced my exception handling reports to show more details and include all inner exceptions. That yielded the magic number 800A1066 which led to many more google hits, but no answers.
Added fall-back code: if you can't open the main document, create a simple one. That's when I found the SaveAs() call also failing.
Dropped back to the development system several times to confirm that yes, the code does still work properly in the right environment.
Greatly condensed sample code does not include fallback logic. My Word document has a number of fields whose names match the XML tokens passed as parameters into this function. saveFields() is an array of those names.
Dim oWord As Word.Application
Dim oDoc As Word.Document
oWord = CreateObject("Word.Application")
oWord.Visible = True
oDoc = oWord.Documents.Open(docName)
Dim ev As String
For i = 0 To saveFields.Length - 1
Try
ev = dataXD.Elements(saveFields(i))(0).Value
Catch
ev = Nothing
End Try
If ev IsNot Nothing Then
Try
Dim field = oDoc.FormFields(saveFields(i))
If field IsNot Nothing Then
If field.Type = Word.WdFieldType.wdFieldFormTextInput Then
field.Result = ev
End If
End If
Catch e As Exception
ErrorOut("Caught exception! " & e.Message)
End Try
End If
Next
...
oDoc.SaveAs2(localDir & filename)
oDoc.Close()
oWord.Quit(0, 0, 0)
The code should generate a modified form (fields filled in with data from the parameters); instead it fails to open, and the fallback code fails to save the new document.
On my dev system the document gets modified as it should, and if I break at the right place and change the right variable, the fallback code runs and generates the alternate document successfully -- but on the production server both paths fail with the same error.
Barring any better answers here, my next steps are to examine and use OpenXML and/or DocX, but making a few changes to the existing code is far preferable to picking a new tool and starting over from scratch.
Unfortunately, Lex Li was absolutely correct, and of course, the link to the reason why is posted on a site my company considers off limits, thus never showed up in my google searches prior to coding this out.
None of the tools I tried were able to handle the form I was trying to automate either -- I needed to fill in named fields and check/uncheck checkboxes, abilities which seemed beyond (or terribly convoluted in) the tools I evaluated ...
Eventually I dug into the document.xml format myself; I developed a function to modify the XML to check a named checkbox, and manipulated the raw document.xml to replace text fields with *-delimited token names. This reduced all of the necessary changes to simple string manipulation -- the rest was trivial.
The tool is 100% home-grown, not dependent upon any non-System libraries and works 100% for this particular form. It is not a generic solution by any stretch, and I suspect the document.xml file will need manual changes if and when the document is ever revised.
But for this particular problem -- it is a solution.
This was the closest I got to a complicated part. This function will check (but not uncheck) a named checkbox from a document.xml if the given condition is true.
Private Shared Function markCheckbox(xmlString As String, cbName As String, checkValue As Boolean) As String
markCheckbox = xmlString
If checkValue Then ' Checkbox needs to be checked, proceed
Dim pos As Integer = markCheckbox.IndexOf("<w:ffData><w:name w:val=""" & cbName & """/>")
If pos > -1 Then ' We have a checkbox
Dim endPos As Integer = markCheckbox.IndexOf("</w:ffData>", pos+1)
Dim cbEnd As Integer = markCheckbox.IndexOf("</w:checkBox>", pos+1)
If endPos > cbEnd AndAlso cbEnd > -1 Then ' Have found the appropriate w:ffData element (pos -> endPos) and the included insert point (cbEnd)
markCheckbox = markCheckbox.Substring(0, cbEnd) & "<w:checked/>" & markCheckbox.Substring(cbEnd)
End If
' Any other logic conditions, return the original XML string unmangled.
End If
End If
End Function

Running SAS Stored Process in Excel fails after two runs

I hope this is an appropriate place to ask this question.
I have recently built a data analysis tool in Excel that works by submitting inputs to a SAS Stored Process (as an 'input stream'), running the processes and displaying the results in Excel.
I also use some code to check for and remove all active stored processes from the workbook before running the process again.
This runs successfuly the first 2 times, but fails on the third attempt. It always fails on the third attempt and I can't figure out why.
Is there some kind of memory allocation for Excel VBA that's exhausted by this stage? Or some other buffer that's maxed out? I've stepped-in to every line of the VBA code and it appears to hang (on the third run) at the following line:
SAS.InsertStoredProcess processLoc, _
outputSheet.Range("A1"), , , inputStream
Code used to initiate SAS Add-in for Microsoft Office:
Dim SAS As SASExcelAddIn
Set SAS = Application.COMAddIns.Item("SAS.ExcelAddIn").Object
Code used to delete stored processes from target output sheet:
Dim Processes As SASStoredProcesses
Set Processes = SAS.GetStoredProcesses(outputSheet)
Dim i As Integer
For i = 1 To Processes.Count
' MsgBox Processes.Item(i).DisplayName
Processes.Item(i).Delete
Next i
Code used to insert and run stored process:
Dim inputStream As SASRanges
Set inputStream = New SASRanges
inputStream.Add "Prompts", inputSheet.Range("DrillDown_Input")
SAS.InsertStoredProcess processLoc, _
outputSheet.Range("A1"), , , inputStream
Cheers
On reflection, my theory here would be that you are hitting the limit of multibridge connections. Each multibridge connection represents a port, and the more ports you have the more parallel connections are enabled. By default there are three, perhaps you have two, or you are kicking off another STP at the same time?
This would explain the behaviour. I had a spreadsheet that called STPs and it would always fail on the fourth call because the first three were running. You can get around this by either a) increasing the number of multibridge connections or b) chaining your processes so they run sequentially.
I don't know if this'll be useful, but I had a similar problem running a DLL written in C++ through VBA. The problem occurred because the function in the DLL returned a double value, which I didn't need and so the code in VBA did
Call SomeProcessFromDLL()
But the process was returning a double floating point value which was 'filling up' some buffer memory in VBA and VBA has a limited buffer (I think it gave up at 8 tries). So the solution for me was
Dim TempToDiscard as Double
TempToDiscard = SomeProcessFromDLL()
Maybe looking at the documentation of the process being called would help here, especially if it's returning some value to be discarded anyway, like a
Return 0;
I never liked using the IOM in VBA, mainly due to issues with references and having to do client installs when rolling out applications. Last year I found a MUCH better way to connect Excel and SAS - using the Stored Process web application. Simply set up your server side SAS process with streaming output, and pass your inputs via an Excel Web query. No client installs, no worries about SAS version upgrades, hardly any code - am surprised it's not used more often!
See: http://rawsas.blogspot.co.uk/2016/11/sas-as-service-easy-way-to-get-sas-into.html

How do I read and change lines in a command script with VB?

Short Version: I know there is not an easy way to do this but how do I change line in a command file with VB?
Long: Working in a login script that will(eventually) populate an RDP file for a specific user based on their username(IE: user#blahdeblah.com goes to
full address:s:blahdeblah.blahdeblah.com and so forth). Multiple server location in part one of the address. I've done the easy part of pulling the file up, capturing the username and where they should be going, but I lack the knowledge on how to populate the file. I've seen some posts here about reading the text and then changing the words as they would appear in a column, but would the same practice work in rows?
If the overall text file in the RDP is 47 rows could I just say "replace row 45 with _"?
I know that was a pain to read through.
Any and all help would be appreciated.
You'd almost certainly want to do something more like find the line with "full address" and then replace it with the other line, line numbers are a pretty breakable thing. I'm not where I can easily test the whole thing, but you want something like:
Dim oFSO
Dim inTS,OutTS
Dim tline
Set oFSO = CreateObject("Scripting.FileSystemObject")
Set inTS = oFSO.OpenTextFile("default.rdp",1,1)
Set outTS = oFSO.CreateTextFile("mynew.rdp", true,true)
While inTS.AtEndOfStream = false
tline = inTS.ReadLine
If InStr(1,tline,"full address:",1) > 0 Then
WScript.Echo("found " &InStr(tline,"full address:"))
outTs.WriteLine("full address:s:SERVER")
Else
outTs.WriteLine(tline)
End If
Wend
inTS.Close
outTS.Close
Though you might have some trouble with unicode you might have better luck with something like running gnuwin32's sed version

Agilent Power Supply Programming using GPIB

On looking at the examples provided in the documentation of the Power supply. The Programming has been done by adding two libraries AgilentRMLib and VisComLib in the C#. When
i try to add the AgilentRMLib by Selecting the Add Reference->Agilent VISA COM Resourse Manager 1.0, an error is shown at the reference.
I tried adding the agtRM.dll directly from the Program Files. Still the error persists. Has anyone faced this problem before? Any Solutions for this? Do you have any other method to program the Power Supply from PC using Agilent IO.
I was able to use the VisaComLib(GlobMgr.dll) instead to program the GPIB using C# programming language.
The pdf file link!
was used as reference.
If you don't mind using VBA, this code can help you accomplish what you are trying to do, make sure it has VISA COM 488.2 Formatted I/O in the References:
Public Sub TestVISA()
Dim Dev_IO As VisaComLib.FormattedIO488
Dim io_manager As VisaComLib.ResourceManager
'Start of Open GPIB port (or any VISA resource)
Set io_manager = New VisaComLib.ResourceManager
Set Dev_IO = New VisaComLib.FormattedIO488
Set Dev_IO.IO = io_manager.Open("GPIB0::x::INSTR") ' x is the GPIB address number of the Dev_IOument
Set io_manager = Nothing
Dev_IO.IO.Timeout = 10000 'set time out to 10 seconds, use this line to change timeout to any time out value per VISA spec
'End of Open GPIB port
'Send some SCPI command to the Dev_IOumnet
Dev_IO.WriteString ("*IDN?")
MsgBox ("Connected to: " & Dev_IO.ReadString)
'Close the port upon completion
Dev_IO.IO.Close
Set Dev_IO = Nothing 'release the object
End Sub
As you are using GPIB protocol, better use GPIB libraries and wrapper then code with native SCPI commands. That way your software will be more dependent to your applications and you can control almost everything. With VISA interface you have to worry about another layer but with this approach you can directly control your devices efficiently. I worked with VISA for couple of years but after that hardworking times now I can build my measurement systems with direct GPIB programming. You can find required libraries from NI's or Agilent's website.

Ensure connection to a POSPrinter connected via COM

I need to make sure that the connection to a POS printer is successful before writing data to the database and then printing a receipt. The POSprinter is normally of type BTP 2002NP but may differ. The common thing is that they are all connected via COM-port and NOT usb, so no drivers installed at all on the client.
Can I send some kind of "ping" on a COM-port and check if a device is connected and turned on? Any help or suggestions are very much appreciated.
Additional information, the application is developed in VB.net and Visual Studio 2008
About all you can do is write out a character string to the com port and wait and see if your printer responds with a reply. However the string you write and the string you expect will depend on the printer itself.
Refer to the BTP 2002NP printers programming manual for examples (the first link in google that I looked at)
From looking at the manual an appropriate string to send to the printer is the "DLE EOT n" command which requests that the printer send back its current status.
As for other printers in the range, check out this list of drivers and manuals
btw, this is what i came up with in the end.
Public Function ComTest() As Byte()
Dim TXT As String
TXT = Chr(&H10S) & Chr(&H4S) & Chr(1) 'DLE EOT 1
If OpenCom() Then 'Connect to com
moRS232.PurgeBuffer(Rs232.PurgeBuffers.TxClear Or Rs232.PurgeBuffers.RXClear)
moRS232.Write(TXT)
moRS232.Read(1)
Return moRS232.InputStream
Else
Return Nothing
End If
End Function
the function returns 1 byte. i can then from the manual translate this byte into what state the printer is currently in. this probably works for all ESC/P printers.