Author Topic: Program that can log/control many multimeters and other devices.  (Read 1107361 times)

flash2b, HKJ and 14 Guests are viewing this topic.

Offline KungFuJosh

  • Super Contributor
  • ***
  • Posts: 5959
  • Country: us
  • TEAS is real.
Re: Program that can log/control many multimeters and other devices.
« Reply #4725 on: September 27, 2025, 02:35:14 pm »
With this version I can't open the Setup dialog. This is the log when trying to open it:

I have uploaded a new version with the exceptions fixed.

I just downloaded from your link and ran it. Says V2.75. This happened when trying to open the Setup dialog:
Code: [Select]
Exception in thread "AWT-EventQueue-0" java.lang.NumberFormatException: For input string: "Unit"
        at java.base/java.lang.NumberFormatException.forInputString(NumberFormatException.java:67)
        at java.base/java.lang.Integer.parseInt(Integer.java:565)
        at java.base/java.lang.Integer.parseInt(Integer.java:662)
        at dk.hkj.devices.SetupFormats$ControlText.<init>(SetupFormats.java:4909)
        at dk.hkj.devices.SetupFormats$ControlInfo.getControl(SetupFormats.java:4495)
        at dk.hkj.devices.SetupFormats$MultiField.addGridBag(SetupFormats.java:5042)
        at dk.hkj.main.PopupSetupSelection.makePanel(PopupSetupSelection.java:246)
        at dk.hkj.main.PopupSetupSelection.makeMainPanel(PopupSetupSelection.java:163)
        at dk.hkj.main.PopupSetupSelection.<init>(PopupSetupSelection.java:95)
        at dk.hkj.main.DeviceInterface.showSetupPopup(DeviceInterface.java:801)
        at dk.hkj.main.PaneCommand.showSetupSelectionPopup(PaneCommand.java:1985)
        at dk.hkj.main.PaneCommand$38.actionPerformed(PaneCommand.java:1048)
        at java.desktop/javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:1972)
        at java.desktop/javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2314)
        at java.desktop/javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:407)
        at java.desktop/javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:262)
        at java.desktop/javax.swing.plaf.basic.BasicButtonListener.mouseReleased(BasicButtonListener.java:279)
        at java.desktop/java.awt.AWTEventMulticaster.mouseReleased(AWTEventMulticaster.java:299)
        at java.desktop/java.awt.Component.processMouseEvent(Component.java:6576)
        at java.desktop/javax.swing.JComponent.processMouseEvent(JComponent.java:3404)
        at java.desktop/java.awt.Component.processEvent(Component.java:6341)
        at java.desktop/java.awt.Container.processEvent(Container.java:2260)
        at java.desktop/java.awt.Component.dispatchEventImpl(Component.java:4958)
        at java.desktop/java.awt.Container.dispatchEventImpl(Container.java:2318)
        at java.desktop/java.awt.Component.dispatchEvent(Component.java:4790)
        at java.desktop/java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4917)
        at java.desktop/java.awt.LightweightDispatcher.processMouseEvent(Container.java:4560)
        at java.desktop/java.awt.LightweightDispatcher.dispatchEvent(Container.java:4501)
        at java.desktop/java.awt.Container.dispatchEventImpl(Container.java:2304)
        at java.desktop/java.awt.Window.dispatchEventImpl(Window.java:2671)
        at java.desktop/java.awt.Component.dispatchEvent(Component.java:4790)
        at java.desktop/java.awt.EventQueue.dispatchEventImpl(EventQueue.java:725)
        at java.desktop/java.awt.EventQueue.dispatchEvent(EventQueue.java:702)
        at java.desktop/java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:203)
        at java.desktop/java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:124)
        at java.desktop/java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:113)
        at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:109)
        at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
        at java.desktop/java.awt.EventDispatchThread.run(EventDispatchThread.java:90)
;; Magnova: Tx <:SYST:THER:STAT?>
;; IP: Tx: <:SYST:THER:STAT?.> 3A 53 59 53 54 3A 54 48 45 52 3A 53 54 41 54 3F 0A
;; IP: Rx: <WUP> 57 55 50 0A
;; Magnova: Rx <WUP>
;; Magnova: Rx after :readmath: replace(replace(replace(value,"COLD","Cold"),"WUP","Warming Up"),"STABle","Stable") <Warming Up>
;; Magnova: Tx <:ACQ:RCL?>
;; IP: Tx: <:ACQ:RCL?.> 3A 41 43 51 3A 52 43 4C 3F 0A
;; IP: Rx: <EXTernal> 45 58 54 65 72 6E 61 6C 0A
;; Magnova: Rx <EXTernal>
;; Magnova: Rx after :readmath: replace(replace(value,"INT","Int"),"EXT","Ext") <External>
;; Magnova: Tx <:ACQ:HRES?>
;; IP: Tx: <:ACQ:HRES?.> 3A 41 43 51 3A 48 52 45 53 3F 0A
;; IP: Rx: <12> 31 32 0A
;; Magnova: Rx <12>
;; Magnova: Tx <:ACQ:MDEP?>
;; IP: Tx: <:ACQ:MDEP?.> 3A 41 43 51 3A 4D 44 45 50 3F 0A
;; IP: Rx: <AFASt> 41 46 41 53 74 0A
;; Magnova: Rx <AFASt>
;; Magnova: Rx after :readmath: replace(replace(value,"AUTO","Auto"),"AFASt","Auto Fast") <Auto Fast>
;; Magnova: Tx <:ACQ:BAND?>
;; IP: Tx: <:ACQ:BAND?.> 3A 41 43 51 3A 42 41 4E 44 3F 0A
;; IP: Rx: <350000000> 33 35 30 30 30 30 30 30 30 0A
;; Magnova: Rx <350000000>
;; Magnova: Tx <:ACQ:SRAT?>
;; IP: Tx: <:ACQ:SRAT?.> 3A 41 43 51 3A 53 52 41 54 3F 0A
;; IP: Rx: <1600000000> 31 36 30 30 30 30 30 30 30 30 0A
;; Magnova: Rx <1600000000>
;; Magnova: Tx <*IDN?>
;; IP: Tx: <*IDN?.> 2A 49 44 4E 3F 0A
;; IP: Rx: <Batronix,Magnova,001216,1.6.3> 42 61 74 72 6F 6E 69 78 2C 4D 61 67 6E 6F 76 61 2C 30 30 31 32 31 36 2C 31 2E 36 2E 33 0A
;; Magnova: Rx <Batronix,Magnova,001216,1.6.3>
;; Magnova: Rx after :readmath: "Current: "+getElement(value,3, ",")"; <Current: 1.6.3>
;; Magnova: Cache Tx: <*IDN?> Rx: <Batronix,Magnova,001216,1.6.3>
;; Magnova: Rx after :readmath: "Latest: "+getElement(value,3, ",")"; <Latest: 1.6.3>
;; Magnova: Cache Tx: <:ACQ:HRES?> Rx: <12>
;; Magnova: Tx <:ACQ:MODE?>
;; IP: Tx: <:ACQ:MODE?.> 3A 41 43 51 3A 4D 4F 44 45 3F 0A
;; IP: Rx: <SAMPle> 53 41 4D 50 6C 65 0A
;; Magnova: Rx <SAMPle>
;; Magnova: Rx after :readmath: getElement("SAMP,PDET,AVER",listIndex(value,"Sample,Peak_Detect,Average")); <SAMP>
;; Magnova: Cache Tx: <:ACQ:MODE?> Rx: <SAMPle>
;; Magnova: Tx <:AUTO?>
;; IP: Tx: <:AUTO?.> 3A 41 55 54 4F 3F 0A
;; IP: Rx: <OFF> 4F 46 46 0A
;; Magnova: Rx <OFF>
;; Magnova: Tx <:ACQ:ROLL?>
;; IP: Tx: <:ACQ:ROLL?.> 3A 41 43 51 3A 52 4F 4C 4C 3F 0A
;; IP: Rx: <OFF> 4F 46 46 0A
;; Magnova: Rx <OFF>
;; Magnova: Rx after :readmath: (value=="ON")?1:0 <0>
;; Magnova: Rx as number <0.0>
;; Magnova: Tx <:TIM:REF?>
;; IP: Tx: <:TIM:REF?.> 3A 54 49 4D 3A 52 45 46 3F 0A
;; IP: Rx: <CENTer> 43 45 4E 54 65 72 0A
;; Magnova: Rx <CENTer>
;; Magnova: Rx after :readmath: getElement("CENT,LEFT,RIGH,TRIG",listIndex(value,"Center,Left,Right,Trigger")); <CENT>
;; Magnova: Tx <:TIM:OFFS?>
;; IP: Tx: <:TIM:OFFS?.> 3A 54 49 4D 3A 4F 46 46 53 3F 0A
;; IP: Rx: <0> 30 0A
;; Magnova: Rx <0>
;; Magnova: Tx <:TIM:SCAL?>
;; IP: Tx: <:TIM:SCAL?.> 3A 54 49 4D 3A 53 43 41 4C 3F 0A
;; IP: Rx: <2E-07> 32 45 2D 30 37 0A
;; Magnova: Rx <2E-07>
;; Magnova: Rx as numbers <0.0 2.0E-7>
;; Magnova: Tx <:CHAN1:STAT?>
;; IP: Tx: <:CHAN1:STAT?.> 3A 43 48 41 4E 31 3A 53 54 41 54 3F 0A
;; IP: Rx: <ON> 4F 4E 0A
;; Magnova: Rx <ON>
;; Magnova: Tx <:CHAN2:STAT?>
;; IP: Tx: <:CHAN2:STAT?.> 3A 43 48 41 4E 32 3A 53 54 41 54 3F 0A
;; IP: Rx: <OFF> 4F 46 46 0A
;; Magnova: Rx <OFF>
;; Magnova: Tx <:CHAN3:STAT?>
;; IP: Tx: <:CHAN3:STAT?.> 3A 43 48 41 4E 33 3A 53 54 41 54 3F 0A
;; IP: Rx: <OFF> 4F 46 46 0A
;; Magnova: Rx <OFF>
;; Magnova: Tx <:CHAN4:STAT?>
;; IP: Tx: <:CHAN4:STAT?.> 3A 43 48 41 4E 34 3A 53 54 41 54 3F 0A
;; IP: Rx: <OFF> 4F 46 46 0A
;; Magnova: Rx <OFF>
;; Magnova: Tx <:MEAS:RLEV:CHAN1:BASE?>
;; IP: Tx: <:MEAS:RLEV:CHAN1:BASE?.> 3A 4D 45 41 53 3A 52 4C 45 56 3A 43 48 41 4E 31 3A 42 41 53 45 3F 0A
;; IP: Rx: <VAMP> 56 41 4D 50 0A
;; Magnova: Rx <VAMP>
;; Magnova: Rx after :readmath: "Base: "+(value)"; <Base: VAMP>
Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException: Cannot invoke "javax.swing.JLabel.setText(String)" because "this.dataLabel" is null
        at dk.hkj.devices.SetupFormats$InfoField.syncValue(SetupFormats.java:3260)
        at dk.hkj.devices.SetupFormats$InfosField.syncValue(SetupFormats.java:3379)
        at dk.hkj.devices.SetupFormats.syncAll(SetupFormats.java:325)
        at dk.hkj.main.PopupSetupSelection.initialSync(PopupSetupSelection.java:124)
        at dk.hkj.main.PopupSetupSelection.timerUpdate(PopupSetupSelection.java:131)
        at dk.hkj.main.PopupSetupSelection.access$3(PopupSetupSelection.java:129)
        at dk.hkj.main.PopupSetupSelection$3.actionPerformed(PopupSetupSelection.java:88)
        at java.desktop/javax.swing.Timer.fireActionPerformed(Timer.java:289)
        at java.desktop/javax.swing.Timer$DoPostEvent.run(Timer.java:221)
        at java.desktop/java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:323)
        at java.desktop/java.awt.EventQueue.dispatchEventImpl(EventQueue.java:723)
        at java.desktop/java.awt.EventQueue.dispatchEvent(EventQueue.java:702)
        at java.desktop/java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:203)
        at java.desktop/java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:124)
        at java.desktop/java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:113)
        at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:109)
        at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
        at java.desktop/java.awt.EventDispatchThread.run(EventDispatchThread.java:90)

Quote
Code: [Select]
Starting
WARNING: A restricted method in java.lang.System has been called
WARNING: java.lang.System::loadLibrary has been called by com.fazecast.jSerialComm.SerialPort in an unnamed module (file:/TestController/TestController.jar)
WARNING: Use --enable-native-access=ALL-UNNAMED to avoid a warning for callers in this module
WARNING: Restricted methods will be blocked in a future release unless native access is enabled

I have no idea what this is, but it looks to be related to jSerialComm and that is a library I use, but do not have any control over.

That notice appeared after you enabled the extended logging.

Thanks,
Josh
"Experience is something you don't get until just after you need it." - Steven Wright
Best Continuity Tester Ever
 

Offline KungFuJosh

  • Super Contributor
  • ***
  • Posts: 5959
  • Country: us
  • TEAS is real.
Re: Program that can log/control many multimeters and other devices.
« Reply #4726 on: September 27, 2025, 07:28:32 pm »
To test further, using V2.75, I removed everything from cmdSetup except the Measure tab. The Measure tab works perfectly that way. No issue switching modes at all. Can be done with Current Values tab visible. No errors at all.

So, I started adding other stuff back in. The info section of the Main tab worked fine. Once the rest of the Main content was added, the Exception in thread "AWT-EventQueue-0" error came back (though it's odd, as the error occurs on the first read command in the Measure tab).

After a bunch of messing around, it appears the presence of a text variable in a control multi caused the error.

I had one multi with text on the Main (first) tab, and removing that stopped the error. I had 4 others on the Math (11th) tab (hidden with selectors), and trying to enable any of those channel selectors where the multi with text pops up gives an error:
Code: [Select]
;; Magnova: Tx <:MATH1:STAT ON>
;; IP: Tx: <:MATH1:STAT ON.> 3A 4D 41 54 48 31 3A 53 54 41 54 20 4F 4E 0A
;; Magnova: Tx <:MATH1:STAT?>
;; IP: Tx: <:MATH1:STAT?.> 3A 4D 41 54 48 31 3A 53 54 41 54 3F 0A
;; IP: Rx: <ON> 4F 4E 0A
;; Magnova: Rx <ON>
;; Magnova: Tx <:MATH:STAT?>
;; IP: Tx: <:MATH:STAT?.> 3A 4D 41 54 48 3A 53 54 41 54 3F 0A
;; IP: Rx: <ON> 4F 4E 0A
;; Magnova: Rx <ON>
;; Magnova: Cache Tx: <:MATH1:STAT?> Rx: <ON>
Exception in thread "AWT-EventQueue-0" java.lang.NumberFormatException: For input string: "Unit"
        at java.base/java.lang.NumberFormatException.forInputString(NumberFormatException.java:67)
        at java.base/java.lang.Integer.parseInt(Integer.java:565)
        at java.base/java.lang.Integer.parseInt(Integer.java:662)
        at dk.hkj.devices.SetupFormats$ControlText.<init>(SetupFormats.java:4909)
        at dk.hkj.devices.SetupFormats$ControlInfo.getControl(SetupFormats.java:4495)
        at dk.hkj.devices.SetupFormats$MultiField.addGridBag(SetupFormats.java:5042)
        at dk.hkj.devices.SetupFormats$SelectorField.doSelectHot(SetupFormats.java:4325)
        at dk.hkj.devices.SetupFormats$SelectorField.doSelect(SetupFormats.java:4307)
        at dk.hkj.devices.SetupFormats$SelectorField.calcSelectedSync(SetupFormats.java:4263)
        at dk.hkj.devices.SetupFormats$SelectorField.syncValue(SetupFormats.java:4428)
        at dk.hkj.devices.SetupFormats$SelectorField.syncValue(SetupFormats.java:4459)
        at dk.hkj.devices.SetupFormats.syncher(SetupFormats.java:451)
        at dk.hkj.devices.SetupFormats.requestSync(SetupFormats.java:478)
        at dk.hkj.devices.SetupFormats.requestSync(SetupFormats.java:459)
        at dk.hkj.devices.SetupFormats$ButtonsField.actionPerformed(SetupFormats.java:2638)
        at java.desktop/javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:1972)
        at java.desktop/javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2314)
        at java.desktop/javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:407)
        at java.desktop/javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:262)
        at java.desktop/javax.swing.plaf.basic.BasicButtonListener.mouseReleased(BasicButtonListener.java:279)
        at java.desktop/java.awt.AWTEventMulticaster.mouseReleased(AWTEventMulticaster.java:299)
        at java.desktop/java.awt.Component.processMouseEvent(Component.java:6576)
        at java.desktop/javax.swing.JComponent.processMouseEvent(JComponent.java:3404)
        at java.desktop/java.awt.Component.processEvent(Component.java:6341)
        at java.desktop/java.awt.Container.processEvent(Container.java:2260)
        at java.desktop/java.awt.Component.dispatchEventImpl(Component.java:4958)
        at java.desktop/java.awt.Container.dispatchEventImpl(Container.java:2318)
        at java.desktop/java.awt.Component.dispatchEvent(Component.java:4790)
        at java.desktop/java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4917)
        at java.desktop/java.awt.LightweightDispatcher.processMouseEvent(Container.java:4560)
        at java.desktop/java.awt.LightweightDispatcher.dispatchEvent(Container.java:4501)
        at java.desktop/java.awt.Container.dispatchEventImpl(Container.java:2304)
        at java.desktop/java.awt.Window.dispatchEventImpl(Window.java:2671)
        at java.desktop/java.awt.Component.dispatchEvent(Component.java:4790)
        at java.desktop/java.awt.EventQueue.dispatchEventImpl(EventQueue.java:725)
        at java.desktop/java.awt.EventQueue.dispatchEvent(EventQueue.java:702)
        at java.desktop/java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:203)
        at java.desktop/java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:124)
        at java.desktop/java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:113)
        at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:109)
        at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
        at java.desktop/java.awt.EventDispatchThread.run(EventDispatchThread.java:90)

I removed the text fields from the control multi stuff and now everything works as it should with V2.75. Having the text field work in control multi would be nice, but I'm glad everything else appears to be sorted now.

Thanks,
Josh
« Last Edit: September 28, 2025, 12:54:00 am by KungFuJosh »
"Experience is something you don't get until just after you need it." - Steven Wright
Best Continuity Tester Ever
 

Offline ander7

  • Contributor
  • Posts: 13
  • Country: by
Re: Program that can log/control many multimeters and other devices.
« Reply #4727 on: September 28, 2025, 08:22:28 am »
The issue is HID interface, I do not have a good library for that. If somebody makes a regular serial interface it can be supported (Together with a couple of other UNI-T meters).

Can you explain what's wrong with Hid4Java? I was able to convert python library (https://github.com/Aleks-nik-a/unit_ut61eplus) into Java code (https://github.com/tataranovich/ut61eplus-hid4java-example) and it can read UT61E+ and execute commands.
 

Online HKJTopic starter

  • Super Contributor
  • ***
  • Posts: 3909
  • Country: dk
    • Tests
Re: Program that can log/control many multimeters and other devices.
« Reply #4728 on: September 28, 2025, 10:57:08 am »
I just downloaded from your link and ran it. Says V2.75. This happened when trying to open the Setup dialog:

Doing something without testing do not always work, this time I have tested the code:

I used this (Both with and without :string:):
#cmdSetup multi vset
:write: INST OUT1;VOLT (value);INST OUT2;VOLT (value2);INST OUT3;VOLT (value3)
:read: INST OUT1;VOLT?;INST OUT2;VOLT?;INST OUT3;VOLT?
;:string:
text V1
text V2
text V3

It is possible to add a maximum length also: text V1 6
Default max. length is 10
 
The following users thanked this post: KungFuJosh

Online HKJTopic starter

  • Super Contributor
  • ***
  • Posts: 3909
  • Country: dk
    • Tests
Re: Program that can log/control many multimeters and other devices.
« Reply #4729 on: September 28, 2025, 10:58:32 am »
Can you explain what's wrong with Hid4Java? I was able to convert python library (https://github.com/Aleks-nik-a/unit_ut61eplus) into Java code (https://github.com/tataranovich/ut61eplus-hid4java-example) and it can read UT61E+ and execute commands.

It do not work, at least that was my problem.
I will check your code and probably get the meter to test.

I can see that it has been updated since I included it.
« Last Edit: September 28, 2025, 11:01:44 am by HKJ »
 

Offline KungFuJosh

  • Super Contributor
  • ***
  • Posts: 5959
  • Country: us
  • TEAS is real.
Re: Program that can log/control many multimeters and other devices.
« Reply #4730 on: September 28, 2025, 01:18:35 pm »
I used this (Both with and without :string:):
#cmdSetup multi vset
:write: INST OUT1;VOLT (value);INST OUT2;VOLT (value2);INST OUT3;VOLT (value3)
:read: INST OUT1;VOLT?;INST OUT2;VOLT?;INST OUT3;VOLT?
;:string:
text V1
text V2
text V3

It is possible to add a maximum length also: text V1 6
Default max. length is 10

Thank you! Everything is working now.

Question about :string: placement:
It works as in your sample with :string: placed as shown. It does not work with :string: placed inline with the text, which is fine. But didn't combo need it placed inline?

Anyway, doesn't matter to me, it works. More fun for your documentation updates. ;)

Thanks!
Josh
"Experience is something you don't get until just after you need it." - Steven Wright
Best Continuity Tester Ever
 

Offline KungFuJosh

  • Super Contributor
  • ***
  • Posts: 5959
  • Country: us
  • TEAS is real.
Re: Program that can log/control many multimeters and other devices.
« Reply #4731 on: September 28, 2025, 01:23:45 pm »
Is it possible to hide & disable #value sets?

For example, I'm currently deciding between having 5 or 8 measurement #values, but there's also 4 math channels that could possibly be monitored. I think that's a lot of clutter for anybody not using more than a couple measurements.

In troubleshooting and screwing things up, I've seen that things can be hidden unintentionally, so my question is if there's an easy way to hide and disable a #value/mode intentionally?

I think I could do it with a ton of if statements, but a cleaner method would be nicer. ;)

Thanks,
Josh
« Last Edit: September 28, 2025, 01:29:33 pm by KungFuJosh »
"Experience is something you don't get until just after you need it." - Steven Wright
Best Continuity Tester Ever
 

Online HKJTopic starter

  • Super Contributor
  • ***
  • Posts: 3909
  • Country: dk
    • Tests
Re: Program that can log/control many multimeters and other devices.
« Reply #4732 on: September 28, 2025, 02:42:22 pm »
Question about :string: placement:
It works as in your sample with :string: placed as shown. It does not work with :string: placed inline with the text, which is fine. But didn't combo need it placed inline?

All :...: tags are supposed to be placed between the # statement and the parameter lines.

More fun for your documentation updates. ;)

I have made most of it, but not uploaded it yet.
 
The following users thanked this post: KungFuJosh

Online HKJTopic starter

  • Super Contributor
  • ***
  • Posts: 3909
  • Country: dk
    • Tests
Re: Program that can log/control many multimeters and other devices.
« Reply #4733 on: September 28, 2025, 02:43:27 pm »
Is it possible to hide & disable #value sets?

The last parameter controls that, it must match a active mode for the parameter to be visible.
 

Offline KungFuJosh

  • Super Contributor
  • ***
  • Posts: 5959
  • Country: us
  • TEAS is real.
Re: Program that can log/control many multimeters and other devices.
« Reply #4734 on: September 28, 2025, 03:05:44 pm »
Is it possible to hide & disable #value sets?

The last parameter controls that, it must match a active mode for the parameter to be visible.

I assume you're referring to the {selector} part of the #value?

That does hide the #value row, but the measurements get shifted. For example:
Set defaults for M1&M2:
Code: [Select]
:setvar: meas1Chan="CHAN1"
:setvar: meas1Type="HFR"
:setvar: meas1Unit="None"
:setvar: meas2Chan="CHAN1"
:setvar: meas2Type="VAMP"
:setvar: meas2Unit="V2"

HFR = Horizontal, Frequency.
VAMP = Vertical, Amplitude.

The #value settings:
Code: [Select]
#value M1_Volts V SI V1
#value M1_Amps A SI A1
#value M1_Vs Vs SI Vs1
#value M1_Seconds s SI s1
#value M1_Hertz Hz SI Hz1
#value M1_Percent % D4 Percent1
#value M1_ _ SI noU1
#value M2_Volts V SI V2
#value M2_Amps A SI A2
#value M2_Vs Vs SI Vs2
#value M2_Seconds s SI s2
#value M2_Hertz Hz SI Hz2
#value M2_Percent % SI Percent2
#value M2_ _ SI noU2

In the attached screenshot, you can see M1 is hidden as expected, but the 1MHz frequency is now shifted to M2, which should be VAMP, which is now being shown on M3, etc.

So, is there a way to bypass the measurements & modes for disabled #values? Or will I need to get creative with if statements in the scpiCmds?

Thanks,
Josh
"Experience is something you don't get until just after you need it." - Steven Wright
Best Continuity Tester Ever
 

Online HKJTopic starter

  • Super Contributor
  • ***
  • Posts: 3909
  • Country: dk
    • Tests
Re: Program that can log/control many multimeters and other devices.
« Reply #4735 on: September 28, 2025, 03:26:54 pm »
I assume you're referring to the {selector} part of the #value?

Correct.

So, is there a way to bypass the measurements & modes for disabled #values? Or will I need to get creative with if statements in the scpiCmds?

You can do conditional stuff in #getvalues depending on modes.
 
The following users thanked this post: KungFuJosh

Offline KungFuJosh

  • Super Contributor
  • ***
  • Posts: 5959
  • Country: us
  • TEAS is real.
Re: Program that can log/control many multimeters and other devices.
« Reply #4736 on: September 28, 2025, 03:30:11 pm »
You can do conditional stuff in #getvalues depending on modes.

Do you have any examples of this?

Thanks,
Josh
"Experience is something you don't get until just after you need it." - Steven Wright
Best Continuity Tester Ever
 

Online HKJTopic starter

  • Super Contributor
  • ***
  • Posts: 3909
  • Country: dk
    • Tests
Re: Program that can log/control many multimeters and other devices.
« Reply #4737 on: September 28, 2025, 03:35:30 pm »
Do you have any examples of this?

It is somewhere in the documentation, it is done this way:

#askValues v1?;[mode:Mode2]v2?;

After a [mode:] the rest of the line (or until the next mode) is limited to that mode.
 

Offline KungFuJosh

  • Super Contributor
  • ***
  • Posts: 5959
  • Country: us
  • TEAS is real.
Re: Program that can log/control many multimeters and other devices.
« Reply #4738 on: September 28, 2025, 03:55:26 pm »
Do you have any examples of this?

It is somewhere in the documentation, it is done this way:

#askValues v1?;[mode:Mode2]v2?;

After a [mode:] the rest of the line (or until the next mode) is limited to that mode.

From your documentation:

Code: [Select]
If the mode on/off commands contain [localmode] the state of the mode is handled by TestController and need not be included in the #askMode. With local mode it may not be necessary to send commands to the device, but only to add more columns and modify the #askValues command with the [mode:xxx] tag.

Changing number of columns ad requested data, depending on device mode:
Code:
#value Value1 V D3
#value Value2 V D3 Mode2

#cmdMode Mode1 m2 SCPI commands
#cmdMode Mode2 m2 SCPI commands

#askValues v1?;[mode:Mode2]v2?;


Changing number of columns, device mode is not used (Note: m2 test is not used, but must be present).
Code:
#value Value1 V D3
#value Value2 V D3 Mode2

#cmdModeCheck Mode2 m2 0
[localMode]
[localMode]


#askValues v1?;[mode:Mode2]v2?;

The latter option appears to be the appropriate one, as I'm not using a #cmdMode button to set modes.

Assuming I have that right, I would then need either a dynamic or negative way of choosing the mode for each #askValues section. Considering:
- There are 7 modes for each of 8 #values
- We need to skip the value and the #modeFromVar for anything not desired.
- negative method would be for example: if (mode!=None)

For this part:
#cmdModeCheck Mode2 m2 0
[localMode]
[localMode]

Is [localMode] listed twice as an example of checking multiple mode options?

Thanks,
Josh
"Experience is something you don't get until just after you need it." - Steven Wright
Best Continuity Tester Ever
 

Online HKJTopic starter

  • Super Contributor
  • ***
  • Posts: 3909
  • Country: dk
    • Tests
Re: Program that can log/control many multimeters and other devices.
« Reply #4739 on: September 28, 2025, 04:02:03 pm »
Assuming I have that right, I would then need either a dynamic or negative way of choosing the mode for each #askValues section. Considering:
- There are 7 modes for each of 8 #values
- We need to skip the value and the #modeFromVar for anything not desired.
- negative method would be for example: if (mode!=None)

I am not sure what you mean.
The [mode:] allows a list of mode like this: [mode:m1,m2,m3,m4]
And it do not care about local or how the mode is defined


From Gossen Metrawatt Energy:
#askValues VAL:L?[mode:Energy,Power];VAL:E?[mode:Power_Quality];mains:num?
#askValuesReadFormat uuuuuuxxxx[mode:Energy]uuu
 
The following users thanked this post: KungFuJosh

Offline KungFuJosh

  • Super Contributor
  • ***
  • Posts: 5959
  • Country: us
  • TEAS is real.
Re: Program that can log/control many multimeters and other devices.
« Reply #4740 on: September 28, 2025, 04:10:46 pm »
From Gossen Metrawatt Energy:
#askValues VAL:L?[mode:Energy,Power];VAL:E?[mode:Power_Quality];mains:num?
#askValuesReadFormat uuuuuuxxxx[mode:Energy]uuu

That answers my question, thank you. I didn't know how messy it would get with all the mode options. ;)

Now I will test it out and see how it plays with the #modeFromVar switching part.

Thanks,
Josh
"Experience is something you don't get until just after you need it." - Steven Wright
Best Continuity Tester Ever
 

Offline KungFuJosh

  • Super Contributor
  • ***
  • Posts: 5959
  • Country: us
  • TEAS is real.
Re: Program that can log/control many multimeters and other devices.
« Reply #4741 on: September 28, 2025, 05:17:28 pm »
It works! Thank you. Switching works great still too.

The [mode=mode] tag has to go before what it's controlling, and it doesn't make sense that the Gossen has the semicolons after the mode tag (the mode tag ignores the semicolon and continues until the next mode tag, but it's an odd placement for the semicolon regardless). Functionally, it probably doesn't matter, but for use an example it's confusing.

I would also request adding a multimode example to the documentation: [mode:m1,m2,m3,m4]

Here's that fully functional (updated) section completed after testing:
Code: [Select]
; ******** #VALUE ********
; Format: #value ColumnName Unit Format {Selector}
#value M1_Volts V SI V1
#value M1_Amps A SI A1
#value M1_Vs Vs SI Vs1
#value M1_Seconds s SI s1
#value M1_Hertz Hz SI Hz1
#value M1_Percent % D4 Percent1
#value M1_ _ SI noU1
#value M2_Volts V SI V2
#value M2_Amps A SI A2
#value M2_Vs Vs SI Vs2
#value M2_Seconds s SI s2
#value M2_Hertz Hz SI Hz2
#value M2_Percent % SI Percent2
#value M2_ _ SI noU2
#value M3_Volts V SI V3
#value M3_Amps A SI A3
#value M3_Vs Vs SI Vs3
#value M3_Seconds s SI s3
#value M3_Hertz Hz SI Hz3
#value M3_Percent % SI Percent3
#value M3_ _ SI noU3
#value M4_Volts V SI V4
#value M4_Amps A SI A4
#value M4_Vs Vs SI Vs4
#value M4_Seconds s SI s4
#value M4_Hertz Hz SI Hz4
#value M4_Percent % SI Percent4
#value M4_ _ SI noU4
#value M5_Volts V SI V5
#value M5_Amps A SI A5
#value M5_Vs Vs SI Vs5
#value M5_Seconds s SI s5
#value M5_Hertz Hz SI Hz5
#value M5_Percent % SI Percent5
#value M5_ _ SI noU5
#value M6_Volts V SI V6
#value M6_Amps A SI A6
#value M6_Vs Vs SI Vs6
#value M6_Seconds s SI s6
#value M6_Hertz Hz SI Hz6
#value M6_Percent % SI Percent6
#value M6_ _ SI noU6
#value M7_Volts V SI V7
#value M7_Amps A SI A7
#value M7_Vs Vs SI Vs7
#value M7_Seconds s SI s7
#value M7_Hertz Hz SI Hz7
#value M7_Percent % SI Percent7
#value M7_ _ SI noU7
#value M8_Volts V SI V8
#value M8_Amps A SI A8
#value M8_Vs Vs SI Vs8
#value M8_Seconds s SI s8
#value M8_Hertz Hz SI Hz8
#value M8_Percent % SI Percent8
#value M8_ _ SI noU8

#askMode getallModes?
#askValues [Mode:V1,A1,Vs1,s1,Hz1,Percent1,noU1]DynamicM1?[Mode:V2,A2,Vs2,s2,Hz2,Percent2,noU2];DynamicM2?[Mode:V3,A3,Vs3,s3,Hz3,Percent3,noU3];DynamicM3?[Mode:V4,A4,Vs4,s4,Hz4,Percent4,noU4];DynamicM4?[Mode:V5,A5,Vs5,s5,Hz5,Percent5,noU5];DynamicM5?[Mode:V6,A6,Vs6,s6,Hz6,Percent6,noU6];DynamicM6?[Mode:V7,A7,Vs7,s7,Hz7,Percent7,noU7];DynamicM7?[Mode:V8,A8,Vs8,s8,Hz8,Percent8,noU8];DynamicM8?
#askValuesReadFormat [Mode:V1,A1,Vs1,s1,Hz1,Percent1,noU1]F[Mode:V2,A2,Vs2,s2,Hz2,Percent2,noU2]F[Mode:V3,A3,Vs3,s3,Hz3,Percent3,noU3]F[Mode:V4,A4,Vs4,s4,Hz4,Percent4,noU4]F[Mode:V5,A5,Vs5,s5,Hz5,Percent5,noU5]F[Mode:V6,A6,Vs6,s6,Hz6,Percent6,noU6]F[Mode:V7,A7,Vs7,s7,Hz7,Percent7,noU7]F[Mode:V8,A8,Vs8,s8,Hz8,Percent8,noU8]F
#modeFromVar allModes

I'm hoping a couple other modes will be added soon, so I'll need to expand slightly. ;)

Thanks!
Josh
« Last Edit: September 28, 2025, 05:40:22 pm by KungFuJosh »
"Experience is something you don't get until just after you need it." - Steven Wright
Best Continuity Tester Ever
 

Online HKJTopic starter

  • Super Contributor
  • ***
  • Posts: 3909
  • Country: dk
    • Tests
Re: Program that can log/control many multimeters and other devices.
« Reply #4742 on: September 28, 2025, 05:33:21 pm »
The [mode=mode] tag has to go before what it's controlling, and it doesn't make sense that the Gossen has the semicolons after the mode tag (the mode tag ignores the semicolon and continues until the next mode tag, but it's an odd placement for the semicolon regardless). Functionally, it probably doesn't matter, but for use an example it's confusing.

If you place the mode tag after the colon, the final line my look like: #askValues DynamicM1?;;;
By placing ; after the mode command I avoid extra semicolons.


I would also request adding a multimode example to the documentation: [mode:m1,m2,m3,m4]

I agree, the documentation needs a bit updating around that.
 

Offline KungFuJosh

  • Super Contributor
  • ***
  • Posts: 5959
  • Country: us
  • TEAS is real.
Re: Program that can log/control many multimeters and other devices.
« Reply #4743 on: September 28, 2025, 05:38:15 pm »
The [mode=mode] tag has to go before what it's controlling, and it doesn't make sense that the Gossen has the semicolons after the mode tag (the mode tag ignores the semicolon and continues until the next mode tag, but it's an odd placement for the semicolon regardless). Functionally, it probably doesn't matter, but for use an example it's confusing.

If you place the mode tag after the colon, the final line my look like: #askValues DynamicM1?;;;
By placing ; after the mode command I avoid extra semicolons.

Ah, I see. That makes sense. I guess that should be included in your documentation updates as well. ;)

I'll update the code in my post above to reflect that.

Thanks,
Josh
"Experience is something you don't get until just after you need it." - Steven Wright
Best Continuity Tester Ever
 

Offline KungFuJosh

  • Super Contributor
  • ***
  • Posts: 5959
  • Country: us
  • TEAS is real.
Re: Program that can log/control many multimeters and other devices.
« Reply #4744 on: September 29, 2025, 02:26:50 pm »
Is there a way to load the #value columnname from a variable or #scpiCmd that reads a variable?

Ideally, I would like to change this:
Code: [Select]
#value M1_Volts V SI V1
#value M1_Amps A SI A1
#value M1_Vs Vs SI Vs1
#value M1_Seconds s SI s1
#value M1_Hertz Hz SI Hz1
#value M1_Percent % D4 Percent1
#value M1_ _ SI noU1

To something like this instead:
Code: [Select]
#value M1:_getMeasType1? V SI V1
#value M1:_getMeasType1? A SI A1
#value M1:_getMeasType1? Vs SI Vs1
#value M1:_getMeasType1? s SI s1
#value M1:_getMeasType1? Hz SI Hz1
#value M1:_getMeasType1? % D4 Percent1
#value M1:_getMeasType1? _ SI noU1

That obviously doesn't work, but that's the idea anyway.

Doing it this way will allow me to have 7 to 10 #value options for each channel and show the correct type, rather than needing probably close to 40 for each channel.

Thanks,
Josh
"Experience is something you don't get until just after you need it." - Steven Wright
Best Continuity Tester Ever
 

Offline jmurray

  • Regular Contributor
  • *
  • Posts: 69
  • Country: au
Re: Program that can log from many multimeters.
« Reply #4745 on: September 30, 2025, 07:51:38 am »
Version  2.64 is up
I added a way to bypass TC automatic splitting into single commands (See documentation for more information).

EDIT: Never mind, the bypass appears to work for #askValues. I must have missed something somewhere.

Regarding the bypass of automatic split: I have this working successfully when typed from the command page, and again from the device definition as part of an "Other" button function (but does require an additional backslash to escape), but when implemented in #askValues TC just times out on the response (v2.64).

Debug outputs:
Code: ("Typed from command line:") [Select]
MEAS:VOLT?[|\]:FETC:CURR?
;; E4360A: Tx <MEAS:VOLT?;:FETC:CURR?>
;; E4360A: Rx <-1.741355E-02;+1.092257E-03>
;; -1.741355E-02;+1.092257E-03

Code: ("Response to #askValues") [Select]
;; E4360A: Tx <MEAS:VOLT?[|\]:FETC:CURR?>
;; E4360A: Rx Timeout
;; E4360A: Rx as numbers <No data (timeout?)>

FYI, the bypass of command splitting does not appear to work with the SCPIx driver.
« Last Edit: September 30, 2025, 07:56:11 am by jmurray »
 

Online HKJTopic starter

  • Super Contributor
  • ***
  • Posts: 3909
  • Country: dk
    • Tests
Re: Program that can log/control many multimeters and other devices.
« Reply #4746 on: September 30, 2025, 11:18:53 am »
Is there a way to load the #value columnname from a variable or #scpiCmd that reads a variable?

No, that would lead to a lot of issues. The column definition is the reference used throughout TC for units and formatting. 
Another detail is that when loading CSV files, TC matches the column names to get the units and formatting.
 

Online HKJTopic starter

  • Super Contributor
  • ***
  • Posts: 3909
  • Country: dk
    • Tests
Re: Program that can log from many multimeters.
« Reply #4747 on: September 30, 2025, 11:20:32 am »
FYI, the bypass of command splitting does not appear to work with the SCPIx driver.

Depends on the version and the commands used in SCPIx, the first with support for it, did not support SCPI command, but I have added it on a couple of commands.
 

Offline Pukker

  • Regular Contributor
  • *
  • Posts: 161
  • Country: nl
Re: Program that can log/control many multimeters and other devices.
« Reply #4748 on: September 30, 2025, 02:35:23 pm »
Is it possible to support Uni-T UT61E+? It's a HID device and it's communication protocol can be checked at https://github.com/Aleks-nik-a/unit_ut61eplus/. I can help with testing if you don't have this DMM at the moment.

The issue is HID interface, I do not have a good library for that. If somebody makes a regular serial interface it can be supported (Together with a couple of other UNI-T meters).

I've an UT-71B and used an USB-UART (with FTC232R chip) and made
connection as seen in the picture to make an Serial unit from an HID (UT-D040) Unit.
Ground is pin 8 and pin 3 is transmit on the CH9325 chip.
I didn't connect to pin 8, normal ground
is the same. In my case I left the original cable
as it was, so it works both, COM and HID.
In my case Red and Black 5 Volt, and White is RX on the Uart.

Testcontroller works out of the box.
The multimeter is recognized by Name and type.
Choosen selections on the device is also perfect recognizend,
exept uA, mA and A setting, that is all A.

The original software from Uni-T works with both options.

BTW, not my own idea, have seen this modification on internet.
 

Offline KungFuJosh

  • Super Contributor
  • ***
  • Posts: 5959
  • Country: us
  • TEAS is real.
Re: Program that can log/control many multimeters and other devices.
« Reply #4749 on: September 30, 2025, 03:10:12 pm »
Is there a way to load the #value columnname from a variable or #scpiCmd that reads a variable?

No, that would lead to a lot of issues. The column definition is the reference used throughout TC for units and formatting. 
Another detail is that when loading CSV files, TC matches the column names to get the units and formatting.

The selector is what determines the column definition currently (unless there isn't a selector defined). With a selector defined, the column definition is dependent on the Unit / Mode selector. For example, If I have 3 options chosen for measurements, those 3 options are what gets logged. If I select 3 different options, then those 3 wouldn't have matching columns anyway if I try to load data from a CSV.

Just the same, to change modes, logging needs to be disable first anyway.

In any case, with the addition of variable column names, you could match CSV data based on 2 variables instead of 1 (variable defined column + variable defined unit).

I do see what you're saying in that it's certainly easier on the selection logic with fixed column names.

Maybe a future feature request then. ;)

Oh well, off to make 1000 mode/column options.  :'(

Thanks,
Josh
"Experience is something you don't get until just after you need it." - Steven Wright
Best Continuity Tester Ever
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf