Power consumption measurement

Revision as of 15:57, 17 June 2024 by Registered User

On this page, you can find explanations and methods related to STM32 MCU application power consumption measurements. It is a key element of any electronic application to correctly manage its power consumption and even more for low power or high performance applications where energy usage is the important criteria.

1. What is power current consumption?

The power current consumption indicates the amount of energy in Watt consumed per an electrical system. Its value can be computed with the following formula:

  • power consumption (Watt) = supply voltage (Volt) x current consumption (Amps)

Usually, the supply voltage is known and stable while the current consumption varies. Measuring the current consumption knowing the supply voltage is a simple method to calculate the power consumption of an electrical system.

2. How to measure power current consumption?

There are several methods to measure/acquire the current consumption in Amps of an electrical system and calculate its power current consumption in Watt.

  • An ammeter tied into the electrical circuit of the application.
  • A source meter unit that delivers the supply and measures the current consumption of the application.
  • An oscilloscope with a shunt-resistor tied into the electrical circuit to acquire the current consumption waveform.

The measurement tool must have several measurement ranges to fit the various levels of current consumption. The oscilloscope method may require the usage of several shunt-resistors

3. Power measurement solutions available in STM32 ecosystem

There are several available hardware solutions in the STM32 ecosystem to measure the current consumption. Our available solutions are combining a programmable voltage source with multiple shut-resistors to provide a high dynamic current measurement range:

Solutions Current range Voltage range Price Comments
X-NUCLEO-LPM01A 100 nA to 50 mA 1.8 V to 3.3 V ~70 $ Standalone solution with Arduino™ Uno and Nano connectors
STM32L562E-DK 300 nA to 150 mA 1.8 V or 3.3 V ~75 $ Full solution schematic available for development
STLINK-V3PWR 100 nA to 500 mA 1.6 V to 3.6 V ~95 $ Debugger probe with power consumption code execution synchronization

All those hardware solutions are compatible with the STM32CubeMonitorPower software. This software tool allows to update acquisition parameters and data rendering in real time and the execution of EEMBC® ULPBench™ to provide an estimation of the ULPMark™ CoreProfile score.

  • STM32CubeMonitor-Power ST.com webpage: STM32CubeMonPwr
  • STM32CubeMonitor-Power software user manual UM2202[1]


3.1. X-NUCLEO-LPM01A

The X-NUCLEO-LPM01A is a Programmable Power Supply source with advanced power consumption measurement capabilities. The STM32 power shield enables developers to analyze the low-power performances of their STM32 application. In addition, the X-NUCLEO-LPM01A is also capable of doing static measurement down to 1 nA, knowing that this feature is not supported by STM32CubeMonitorPower software, the expansion board standalone mode must be used.

  • STM32 X-NUCLEO-LPM01A "Powershield" ST.com webpage: X-NUCLEO-LPM01A
  • STM32 Nucleo expansion board for power consumption measurement user manual UM2243[2]


3.2. STM32L562E-DK

The discovery kit with STM32L562QE MCU has an on-board current power supply source and an acquisition consumption circuitry with 300 nA-150 mA range. It is a full application example with board schematic circuitry and layout to develop your own embedded power consumption measurement solution. In addition, it can be connected to an external application board to monitor its current consumption.

  • Discovery kit with STM32L562QE MCU ST.com webpage: STM32L562QE
  • Discovery kit with STM32L562QE MCU user manual UM2617[3]

3.3. STLINK-V3PWR

The STLINK-V3PWR is a programmable supply source and can measure current consumption up to 500 mA. It also includes an STLINKV3 debugger and programmer for STM32. The main functionality of this product is the simultaneous current consumption and the debug trace acquisition while the target is running code. It can display the state of the firmware execution synchronized with the current consumption waveform.

  • STLINK-V3PWR ST.com webpage: STLINK-V3PWR
  • STLINK-V3PWR user manual UM3097 [4]

4. How to use STLINK-V3PWR to monitor power consumption on STM32 MCU (AN5999) [5]

4.1. Application note content overview

We strongly recommend referring to the dedicated application note "How to use STLINK-V3PWR to monitor power consumption on STM32 MCU AN5999" that covers the usage of the STLINK-V3PWR debug probe.

  • The first chapters present an overview of the STLINK-V3PWR, the measurement methods to acquire the current consumption of an embedded application and the STLINK-V3PWR interfaces: power, debug, and bridge.
  • The next chapters describe how to connect the STLINK-V3PWR to a generic application board and an STM32 Nucleo, discovery, or evaluation board.
  • Then a chapter introduces the software tools associated with the power functions of the probe: STM32CubeMonitor-Power, STM32CubeMonitor or GNU Octave 7.3.
  • The next chapters present how to connect the debug interface of the probe with STM32CubeIDE and also with IAR Embedded Workbench IDE or Arm μVision®.
  • The last chapter is a basic application example using the power and the bridge interfaces of the STLINK-V3PWR.

5. How to use STM32CubeMonitor and Octave to control the STLINK-V3PWR power interface

The application note AN5999 presents two application examples using STM32CubeMonitor or Octave software. You can find the source code of both examples below.

5.1. How to use STM32CubeMonitor and the STLINK-V3PWR power interface

Find below the flow code example you can import into the STM32CubeMonitor software environment for the main menu [6]. The serial port must be changed to match your computer system (refer to "type": "serial-port" container). You can refer to the application note AN5999 USB communication chapter for more information. Copy the following flow application and import it into STM32CubeMonitor.

[    {
        "id": "7284a1cc.fc435",
        "type": "tab",
        "label": "STLINK-V3PWR Example",
        "disabled": false,
        "info": "My first flow\n"
    },
    {
        "id": "e90e5ee0.d857d",
        "type": "ui_button",
        "z": "7284a1cc.fc435",
        "name": "",
        "group": "9aead2a4.e86de",
        "order": 5,
        "width": 1,
        "height": 1,
        "passthru": false,
        "label": "ON",
        "tooltip": "",
        "color": "",
        "bgcolor": "red",
        "icon": "",
        "payload": "pwr on",
        "payloadType": "str",
        "topic": "",
        "topicType": "str",
        "x": 510,
        "y": 200,
        "wires": [
            [
                "be0ec0a9.8075a",
                "254a182f.6a1fa8"
            ]
        ]
    },
    {
        "id": "1aca5d03.671543",
        "type": "ui_button",
        "z": "7284a1cc.fc435",
        "name": "",
        "group": "9aead2a4.e86de",
        "order": 7,
        "width": 1,
        "height": 1,
        "passthru": false,
        "label": "OFF",
        "tooltip": "",
        "color": "",
        "bgcolor": "green",
        "icon": "",
        "payload": "pwr off",
        "payloadType": "str",
        "topic": "",
        "x": 510,
        "y": 240,
        "wires": [
            [
                "c58c0b89.a1f448",
                "254a182f.6a1fa8"
            ]
        ]
    },
    {
        "id": "3f8f1573.8240da",
        "type": "ui_text",
        "z": "7284a1cc.fc435",
        "group": "fa48ed7a.a0d7c",
        "order": 8,
        "width": 8,
        "height": 1,
        "name": "",
        "label": "Last message:",
        "format": "{{msg.payload}}",
        "layout": "row-left",
        "x": 1760,
        "y": 120,
        "wires": []
    },
    {
        "id": "aac02613.2a5c98",
        "type": "ui_text",
        "z": "7284a1cc.fc435",
        "group": "9aead2a4.e86de",
        "order": 2,
        "width": 3,
        "height": 3,
        "name": "Stats",
        "label": "",
        "format": "{{msg.payload}}",
        "layout": "row-left",
        "x": 1870,
        "y": 460,
        "wires": []
    },
    {
        "id": "6ce22ff3.edca",
        "type": "ui_button",
        "z": "7284a1cc.fc435",
        "name": "",
        "group": "9aead2a4.e86de",
        "order": 1,
        "width": 1,
        "height": 1,
        "passthru": true,
        "label": "MEAS",
        "tooltip": "",
        "color": "",
        "bgcolor": "black",
        "icon": "",
        "payload": "start",
        "payloadType": "str",
        "topic": "",
        "topicType": "str",
        "x": 510,
        "y": 280,
        "wires": [
            [
                "254a182f.6a1fa8"
            ]
        ]
    },
    {
        "id": "10e4d8f.5740727",
        "type": "ui_switch",
        "z": "7284a1cc.fc435",
        "name": "",
        "label": "LOOP",
        "tooltip": "Repeat/loop Mode",
        "group": "9aead2a4.e86de",
        "order": 6,
        "width": 2,
        "height": 1,
        "passthru": true,
        "decouple": "false",
        "topic": "",
        "topicType": "str",
        "style": "",
        "onvalue": "true",
        "onvalueType": "bool",
        "onicon": "",
        "oncolor": "",
        "offvalue": "false",
        "offvalueType": "bool",
        "officon": "",
        "offcolor": "",
        "animate": true,
        "x": 110,
        "y": 440,
        "wires": [
            [
                "f34856a9.02ce08"
            ]
        ]
    },
    {
        "id": "f34856a9.02ce08",
        "type": "function",
        "z": "7284a1cc.fc435",
        "name": "Global enable loop",
        "func": "var temp_string=msg.payload;\n\nif( msg.payload==true)\n{flow.set('global_loop',\"on\")}\nelse\n{flow.set('global_loop',\"off\")}\n// Redefine msg.payload and return:\n//msg.payload = [{\"series\":[\"current\"], \"labels\":[\"current data\"], \"data\":[pl_new]}];\n\n\nreturn msg;",
        "outputs": 1,
        "noerr": 0,
        "x": 330,
        "y": 440,
        "wires": [
            []
        ]
    },
    {
        "id": "94663d0f.6e461",
        "type": "function",
        "z": "7284a1cc.fc435",
        "name": "Loop_control",
        "func": "var temp_string=msg.payload;\n\nif( flow.get('global_loop')==\"on\")\n{msg.payload=\"loop_on\"}\nelse\n{msg.payload=\"loop_off\";}\n// Redefine msg.payload and return:\n//msg.payload = [{\"series\":[\"current\"], \"labels\":[\"current data\"], \"data\":[pl_new]}];\n\n\nreturn msg;",
        "outputs": 1,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "x": 1890,
        "y": 500,
        "wires": [
            [
                "573aec73.e112e4"
            ]
        ]
    },
    {
        "id": "898007dd.d33f88",
        "type": "ui_switch",
        "z": "7284a1cc.fc435",
        "name": "",
        "label": "AVG.",
        "tooltip": "Average mode",
        "group": "9aead2a4.e86de",
        "order": 8,
        "width": 2,
        "height": 1,
        "passthru": true,
        "decouple": "false",
        "topic": "",
        "topicType": "str",
        "style": "",
        "onvalue": "true",
        "onvalueType": "bool",
        "onicon": "",
        "oncolor": "",
        "offvalue": "false",
        "offvalueType": "bool",
        "officon": "",
        "offcolor": "",
        "animate": true,
        "x": 110,
        "y": 480,
        "wires": [
            [
                "f79afdd5.01f8a"
            ]
        ]
    },
    {
        "id": "144402d5.a94bcd",
        "type": "ui_text",
        "z": "7284a1cc.fc435",
        "group": "fa48ed7a.a0d7c",
        "order": 4,
        "width": 5,
        "height": 3,
        "name": "Log",
        "label": "",
        "format": "{{msg.payload}}",
        "layout": "row-left",
        "x": 1730,
        "y": 80,
        "wires": []
    },
    {
        "id": "e4f1fa0e.79f7c8",
        "type": "function",
        "z": "7284a1cc.fc435",
        "name": "Log message",
        "func": "//var last_time=flow.get('log_time')\n//var new_time=flow.set('log_time', Date().getTime())\n//var delta_time= new_time-last_time;\n \nlast_msg={payload:msg.payload};\nvar currentdate = new Date(); \nvar datetime = currentdate.getHours() + \":\"+ currentdate.getMinutes() + \":\"+ currentdate.getSeconds()+\" 🡆 \";\nmsg.payload=datetime+msg.payload+\"<br>\"+flow.get('log_message');\narray_message=msg.payload.split(\"<br>\")\nmsg.payload=array_message[0]+\"<br>\";\nfor (i=1;i<6;i++)\n{msg.payload=msg.payload+array_message[i]+\"<br>\";}\nflow.set('log_message',msg.payload)\nmsg.payload=\"<u>Log:</u></br>\"+msg.payload\nreturn [msg,last_msg];",
        "outputs": 2,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "x": 1540,
        "y": 100,
        "wires": [
            [
                "144402d5.a94bcd"
            ],
            [
                "3f8f1573.8240da"
            ]
        ]
    },
    {
        "id": "abdf62b7.29e4b",
        "type": "ui_dropdown",
        "z": "7284a1cc.fc435",
        "name": "",
        "label": "CMD",
        "tooltip": "",
        "place": "Select option",
        "group": "fa48ed7a.a0d7c",
        "order": 6,
        "width": 5,
        "height": 1,
        "passthru": false,
        "multiple": false,
        "options": [
            {
                "label": "start 100ms",
                "value": "acqtime 100m|start",
                "type": "str"
            },
            {
                "label": "start 200ms",
                "value": "acqtime 200m|start",
                "type": "str"
            },
            {
                "label": "start 400ms",
                "value": "acqtime 400m|start",
                "type": "str"
            },
            {
                "label": "version",
                "value": "version",
                "type": "str"
            },
            {
                "label": "Set VOUT 3.3V",
                "value": "volt 3300m",
                "type": "str"
            },
            {
                "label": "Get Voltage",
                "value": "volt get",
                "type": "str"
            }
        ],
        "payload": "",
        "topic": "",
        "topicType": "str",
        "x": 110,
        "y": 160,
        "wires": [
            [
                "fbdd1c45.3be48"
            ]
        ]
    },
    {
        "id": "377f84f1.6af85c",
        "type": "ui_button",
        "z": "7284a1cc.fc435",
        "name": "",
        "group": "fa48ed7a.a0d7c",
        "order": 7,
        "width": 1,
        "height": 1,
        "passthru": true,
        "label": "CLEAR",
        "tooltip": "",
        "color": "",
        "bgcolor": "grey",
        "icon": "",
        "payload": "",
        "payloadType": "str",
        "topic": "",
        "x": 1120,
        "y": 100,
        "wires": [
            [
                "5cfa8781.5764a8"
            ]
        ]
    },
    {
        "id": "5cfa8781.5764a8",
        "type": "function",
        "z": "7284a1cc.fc435",
        "name": "Clear Log message",
        "func": "\nflow.set('log_message',\"<br><br><br><br><br><br><br>\")\nmsg.payload=\".\"\nreturn msg;",
        "outputs": 1,
        "noerr": 0,
        "x": 1310,
        "y": 100,
        "wires": [
            [
                "e4f1fa0e.79f7c8"
            ]
        ]
    },
    {
        "id": "d80d6382.df747",
        "type": "link in",
        "z": "7284a1cc.fc435",
        "name": "Log window",
        "links": [
            "ec0643c0.92ad2",
            "c9d0a9b7.e4b978"
        ],
        "x": 1385,
        "y": 60,
        "wires": [
            [
                "e4f1fa0e.79f7c8"
            ]
        ]
    },
    {
        "id": "d3a7154.67334e8",
        "type": "ui_button",
        "z": "7284a1cc.fc435",
        "name": "",
        "group": "fa48ed7a.a0d7c",
        "order": 1,
        "width": 1,
        "height": 1,
        "passthru": true,
        "label": "INIT",
        "tooltip": "Host take control + init",
        "color": "",
        "bgcolor": "black",
        "icon": "",
        "payload": "",
        "payloadType": "str",
        "topic": "",
        "topicType": "str",
        "x": 110,
        "y": 360,
        "wires": [
            [
                "9c6d6bcc.a3cf78"
            ]
        ]
    },
    {
        "id": "b38aed57.c6a2d",
        "type": "split",
        "z": "7284a1cc.fc435",
        "name": "",
        "splt": "|",
        "spltType": "str",
        "arraySplt": 1,
        "arraySpltType": "len",
        "stream": false,
        "addname": "",
        "x": 510,
        "y": 360,
        "wires": [
            [
                "254a182f.6a1fa8"
            ]
        ]
    },
    {
        "id": "c2fbe2f8.d3473",
        "type": "ui_button",
        "z": "7284a1cc.fc435",
        "name": "",
        "group": "fa48ed7a.a0d7c",
        "order": 5,
        "width": 1,
        "height": 1,
        "passthru": true,
        "label": "STATUS",
        "tooltip": "",
        "color": "",
        "bgcolor": "black",
        "icon": "",
        "payload": "version|status|echo test ok|pwr get|volt get|range",
        "payloadType": "str",
        "topic": "",
        "topicType": "str",
        "x": 100,
        "y": 320,
        "wires": [
            [
                "b38aed57.c6a2d"
            ]
        ]
    },
    {
        "id": "5d825e3b.d9cfb",
        "type": "delay",
        "z": "7284a1cc.fc435",
        "name": "",
        "pauseType": "delay",
        "timeout": "150",
        "timeoutUnits": "milliseconds",
        "rate": "1",
        "nbRateUnits": "1",
        "rateUnits": "second",
        "randomFirst": "1",
        "randomLast": "5",
        "randomUnits": "seconds",
        "drop": false,
        "outputs": 1,
        "x": 350,
        "y": 280,
        "wires": [
            [
                "6ce22ff3.edca"
            ]
        ]
    },
    {
        "id": "8b00baa9.367ce8",
        "type": "ui_switch",
        "z": "7284a1cc.fc435",
        "name": "",
        "label": "REL.",
        "tooltip": "Relative mode",
        "group": "9aead2a4.e86de",
        "order": 3,
        "width": 2,
        "height": 1,
        "passthru": true,
        "decouple": "false",
        "topic": "",
        "topicType": "str",
        "style": "",
        "onvalue": "true",
        "onvalueType": "bool",
        "onicon": "",
        "oncolor": "",
        "offvalue": "false",
        "offvalueType": "bool",
        "officon": "",
        "offcolor": "",
        "animate": true,
        "x": 110,
        "y": 520,
        "wires": [
            [
                "67b23362.f9c6ec"
            ]
        ]
    },
    {
        "id": "7935d92b.951768",
        "type": "link in",
        "z": "7284a1cc.fc435",
        "name": "Loop_feedback",
        "links": [
            "85d08137.28f7c"
        ],
        "x": 235,
        "y": 280,
        "wires": [
            [
                "5d825e3b.d9cfb"
            ]
        ]
    },
    {
        "id": "85d08137.28f7c",
        "type": "link out",
        "z": "7284a1cc.fc435",
        "name": "",
        "links": [
            "7935d92b.951768"
        ],
        "x": 2195,
        "y": 500,
        "wires": []
    },
    {
        "id": "3798f42b.b5eddc",
        "type": "function",
        "z": "7284a1cc.fc435",
        "name": "STLP Acquisition data translate",
        "func": "var acquisition_array=msg.payload;\nvar units=1;\nvar units_str=\"A\";\nvar relative_current_value\nvar Sampling_frequency = 1;\nvar flow_stlinkv3pwr_status;\nvar average_count=1;\nvar average_value = 0;\n\nif((flow.get('global_relative_current')||\"off\")==\"off\")\n{relative_current_value=0}\nelse\n{relative_current_value=flow.get('global_relative_current_value')||0}\n\nflow_stlinkv3pwr_status=flow.get('flow_stlinkv3pwr_status',msg.payload)\n\n\nif(flow_stlinkv3pwr_status.freq==\"freq 100Hz\")\n{Sampling_frequency=100};\n\nif(flow_stlinkv3pwr_status.freq==\"freq 1kHz\")\n{Sampling_frequency=1000};\n\nif(flow_stlinkv3pwr_status.freq==\"freq 5kHz\")\n{Sampling_frequency=5000};\n\nif(flow_stlinkv3pwr_status.freq==\"freq 10kHz\")\n{Sampling_frequency=10000};\n\nif(flow_stlinkv3pwr_status.freq==\"freq 20kHz\")\n{Sampling_frequency=20000};\n\nif(flow_stlinkv3pwr_status.freq==\"freq 50kHz\")\n{Sampling_frequency=50000};\n\nif(flow_stlinkv3pwr_status.freq==\"freq 100kHz\")\n{Sampling_frequency=100000};\n\nvar i;\nvar x = [];\nvar y = [];\nvar pl_new = [];\nvar pl_new_uA = [];\nvar current_data = new Date();\nvar current_time= current_data.getTime();\ncurrent_time=0\n  \nfor (i = 0; i<acquisition_array.length; i++) {\n    // get data info x and y, and convert to unix time format:\n    x[i] =current_time + i * (1/Sampling_frequency) * 1000; //s to ms\n    x[i] =Math.round(x[i]*1000000000)/1000000000; //max x res\n    y[i]=parseFloat(acquisition_array[i+1]-relative_current_value);\n    // generate key-value pair:\n    pl_new[i] = {\"x\":Number(x[i]), \"y\":Number(y[i])};\n    pl_new_uA[i] = {\"x\":Number(x[i]), \"y\":Number(y[i]*1e6)};\n\n}\n\nif((flow.get('global_average')||\"off\")==\"on\")\n{\n    average_value=flow.get('global_average_value')||y;\n    average_count=flow.get('global_average_count')||0;\n\n    for (i = 0; i<acquisition_array.length; i++) {\n         y[i]=(y[i]+average_value[i])/2;\n         pl_new[i].y =y[i];\n    }\n    average_count++;\n}\nelse\n{\n    average_count=0;\n}\nflow.set('global_average_value',y)\nflow.set('global_average_count',average_count)\n\n\n\nvar min_value=999999999;\nvar max_value=0;\nvar std_dev=0;\nvar average_value=y[0];\nfor (i = 1; i<(acquisition_array.length-1); i++) {\naverage_value=(average_value+y[i])/2;\nif(y[i]<min_value){min_value=y[i]}\nif(y[i]>max_value){max_value=y[i]}\n}\n\nif((flow.get('global_relative_current')||\"off\")==\"off\")\n\n{flow.set('global_relative_current_value',average_value)}\n\n\nfor (i = 0; i<acquisition_array.length-2; i++) {\nstd_dev=std_dev+(y[i]-average_value)*(y[i]-average_value)\n//std_dev=std_dev+(y[i]-average_value)\n// pl_new[i].y= pl_new[i].y*units;\n}\nstd_dev=Math.sqrt(std_dev/(acquisition_array.length-2))\n\nvar relative_current=flow.get('global_relative_current')||\"off\";\n\naverage_value=number_to_scientific_base(average_value,3,true);\nmin_value=number_to_scientific_base(min_value,3,true);\nmax_value=number_to_scientific_base(max_value,3,true);\nstd_dev=number_to_scientific_base(std_dev,3,true);\nrelative_current_value=number_to_scientific_base(relative_current_value,3,true);\n// Redefine msg.payload and return:\nvar msg_node_red_graph = {\"payload\":[{\"series\":[\"current\"],\"data\":[y],\"labels\":x}]}\nmsg_js_chart = {payload:\"\"}\nmsg_js_chart.payload = {}\nmsg_js_chart.payload.structdata_xy1 = JSON.stringify(pl_new)\nmsg_js_chart.payload.structdata_xy2 = JSON.stringify(pl_new)\nmsg.payload = [{\"series\":[\"current(uA)\"], \"labels\":[\"current data\"], \"data\":[pl_new_uA]}];\nvar average_text=\"Mean: \"+average_value+\"A\"\nvar summary_string=\"<h4><u>\"+average_text.fontsize(5)+\"</u></br>Max: \"+max_value+\"A</br>Min:\"+min_value+\"A</br>StdDev:\"+std_dev+\"A</br>Null:\"+relative_current_value+\"A</br>AvgCnt:\"+average_count+\"</h4>\"//+summary_string\n\nvar string_display = { payload: summary_string };\nvar debug={payload: \"acqsize:\"+(acquisition_array.length)}\n\nreturn [msg_js_chart,string_display,debug,msg]\n\nfunction number_to_scientific_base(input_number,digits,string_mode)\n{\n    var unit_string=\"NA\";\n    var unit = \"NA\";\n    if(Math.abs(input_number)<1){input_number=input_number*1000;unit=\"e-3\";unit_string=\"m\";}\n    if(Math.abs(input_number)<1){input_number=input_number*1000;unit=\"e-6\";unit_string=\"µ\";}\n    if(Math.abs(input_number)<1){input_number=input_number*1000;unit=\"e-9\";unit_string=\"n\";}\n    if(Math.abs(input_number)<1){input_number=input_number*1000;unit=\"e-12\";unit_string=\"p\";}\n    if(Math.abs(input_number)<1){input_number=input_number*1000;unit=\"e-15\";unit_string=\"f\";}\n    if(string_mode==true)\n    {return input_number.toFixed(digits)+unit_string}\n    else\n    {return input_number.toFixed(digits)+unit}\n}\n",
        "outputs": 4,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 1450,
        "y": 440,
        "wires": [
            [],
            [
                "aac02613.2a5c98",
                "94663d0f.6e461"
            ],
            [],
            [
                "ba003014.1c2f3"
            ]
        ]
    },
    {
        "id": "bf310bba.5334a8",
        "type": "ui_text",
        "z": "7284a1cc.fc435",
        "group": "fa48ed7a.a0d7c",
        "order": 3,
        "width": 3,
        "height": 2,
        "name": "Status",
        "label": "",
        "format": "{{msg.payload}}",
        "layout": "row-left",
        "x": 890,
        "y": 380,
        "wires": []
    },
    {
        "id": "be0ec0a9.8075a",
        "type": "function",
        "z": "7284a1cc.fc435",
        "name": "Power ON state",
        "func": "msg.payload=\"Pwr is ON\"\nmsg.payload=msg.payload.fontsize(2)\nmsg.payload=msg.payload.fontcolor(\"red\")\nmsg.payload=\"<u>Status:</u></br>\"+msg.payload\n\nreturn msg\n\n",
        "outputs": 1,
        "noerr": 0,
        "x": 740,
        "y": 200,
        "wires": [
            []
        ]
    },
    {
        "id": "c58c0b89.a1f448",
        "type": "function",
        "z": "7284a1cc.fc435",
        "name": "Power OFF state",
        "func": "msg.payload=\"Pwr is off\"\nmsg.payload=msg.payload.fontsize(2)\nmsg.payload=msg.payload.fontcolor(\"green\")\nmsg.payload=\"<u>Status:</u></br>\"+msg.payload\nreturn msg\n\n",
        "outputs": 1,
        "noerr": 0,
        "x": 750,
        "y": 240,
        "wires": [
            []
        ]
    },
    {
        "id": "99bee931.5ac228",
        "type": "ui_text_input",
        "z": "7284a1cc.fc435",
        "name": "",
        "label": "Command",
        "tooltip": "",
        "group": "fa48ed7a.a0d7c",
        "order": 2,
        "width": 5,
        "height": 1,
        "passthru": true,
        "mode": "text",
        "delay": "0",
        "topic": "",
        "x": 90,
        "y": 120,
        "wires": [
            [
                "fbdd1c45.3be48"
            ]
        ]
    },
    {
        "id": "fbdd1c45.3be48",
        "type": "split",
        "z": "7284a1cc.fc435",
        "name": "",
        "splt": "|",
        "spltType": "str",
        "arraySplt": 1,
        "arraySpltType": "len",
        "stream": false,
        "addname": "",
        "x": 250,
        "y": 160,
        "wires": [
            [
                "254a182f.6a1fa8"
            ]
        ]
    },
    {
        "id": "254a182f.6a1fa8",
        "type": "function",
        "z": "7284a1cc.fc435",
        "name": "Set flow_stdebug_data",
        "func": "cmd={}\ncmd.payload=msg.payload\nflow_stlinkv3pwr_status=flow.get('flow_stlinkv3pwr_status',msg.payload)\n\nstore_status=true;\nif(msg.payload.includes(\"pwr get\")) {store_status=false}\nif(msg.payload.includes(\"volt get\")) {store_status=false}\nif(msg.payload.includes(\"start\"))\n{\n    store_status=false\n    acqtime_array=flow_stlinkv3pwr_status.acqtime.split(\" \");\n}\n\nif(store_status)\n{\n\nif(msg.payload.includes(\"pwr\"))\n{flow_stlinkv3pwr_status.pwr=msg.payload}\n\nif(msg.payload.includes(\"acqtime\"))\n{flow_stlinkv3pwr_status.acqtime=msg.payload+\"s\"}\n\nif(msg.payload.includes(\"freq\"))\n{flow_stlinkv3pwr_status.freq=msg.payload+\"Hz\"}\n\nif(msg.payload.includes(\"volt\"))\n{flow_stlinkv3pwr_status.volt=msg.payload+\"V\"}\n\nflow.set('flow_stlinkv3pwr_status',flow_stlinkv3pwr_status)\n}\n\n\n msg.payload=\"<u>Status:</u></br>\"\n msg.payload=msg.payload+flow_stlinkv3pwr_status.pwr+\"</br>\"   \n msg.payload=msg.payload+flow_stlinkv3pwr_status.acqtime+\"</br>\"   \n msg.payload=msg.payload+flow_stlinkv3pwr_status.freq+\"</br>\"   \n msg.payload=msg.payload+flow_stlinkv3pwr_status.volt+\"</br>\"   \ncmd.payload=cmd.payload+\"\\r\"\n\nreturn [msg,cmd]",
        "outputs": 2,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "x": 700,
        "y": 420,
        "wires": [
            [
                "bf310bba.5334a8"
            ],
            [
                "d4384d94.9d8b3"
            ]
        ]
    },
    {
        "id": "f79afdd5.01f8a",
        "type": "function",
        "z": "7284a1cc.fc435",
        "name": "Global enable average",
        "func": "var temp_string=msg.payload;\n\nif( msg.payload==true)\n{flow.set('global_average',\"on\")}\nelse\n{flow.set('global_average',\"off\")}\n// Redefine msg.payload and return:\n//msg.payload = [{\"series\":[\"current\"], \"labels\":[\"current data\"], \"data\":[pl_new]}];\n\n\nreturn msg;",
        "outputs": 1,
        "noerr": 0,
        "x": 340,
        "y": 480,
        "wires": [
            []
        ]
    },
    {
        "id": "67b23362.f9c6ec",
        "type": "function",
        "z": "7284a1cc.fc435",
        "name": "Global enable filter1",
        "func": "var temp_string=msg.payload;\n\nif( msg.payload==true)\n{flow.set('global_relative_current',\"on\")}\nelse\n{flow.set('global_relative_current',\"off\")}\n// Redefine msg.payload and return:\n//msg.payload = [{\"series\":[\"current\"], \"labels\":[\"current data\"], \"data\":[pl_new]}];\n\n\nreturn msg;",
        "outputs": 1,
        "noerr": 0,
        "x": 340,
        "y": 520,
        "wires": [
            []
        ]
    },
    {
        "id": "9c6d6bcc.a3cf78",
        "type": "function",
        "z": "7284a1cc.fc435",
        "name": "init flow_stlinkv3pwr_status",
        "func": "flow_stlinkv3pwr_status={}\nflow_stlinkv3pwr_status.pwr=\"pwr off\"\nflow_stlinkv3pwr_status.acqtime=\"100ms\"\nflow_stlinkv3pwr_status.freq=msg.payload+\"1000Hz\"\nflow_stlinkv3pwr_status.volt=msg.payload+\"3.3V\"\nflow.set('flow_stlinkv3pwr_status',flow_stlinkv3pwr_status)\nflow.set('global_loop',\"off\")\nflow.set('global_average',\"off\")\nflow.set('global_relative_current',\"off\")\nmsg.payload=\"power_monitor|format bin_hexa|volt 3300m|acqtime 100m|freq 10k\"\nreturn msg",
        "outputs": 1,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "x": 300,
        "y": 360,
        "wires": [
            [
                "b38aed57.c6a2d"
            ]
        ]
    },
    {
        "id": "d4384d94.9d8b3",
        "type": "serial request",
        "z": "7284a1cc.fc435",
        "name": "",
        "serial": "642279c6.c139b8",
        "x": 900,
        "y": 420,
        "wires": [
            [
                "439c36e1.9d9838"
            ]
        ]
    },
    {
        "id": "573aec73.e112e4",
        "type": "switch",
        "z": "7284a1cc.fc435",
        "name": "",
        "property": "payload",
        "propertyType": "msg",
        "rules": [
            {
                "t": "eq",
                "v": "loop_on",
                "vt": "str"
            }
        ],
        "checkall": "true",
        "repair": false,
        "outputs": 1,
        "x": 2070,
        "y": 500,
        "wires": [
            [
                "85d08137.28f7c"
            ]
        ]
    },
    {
        "id": "439c36e1.9d9838",
        "type": "function",
        "z": "7284a1cc.fc435",
        "name": "binary decoding",
        "func": "//var stlinkpwr_binary_acq=msg.payload[0].payload\nvar stlinkpwr_binary_acq=msg.payload\n\nvar data=[];\nvar data_ok=-1;\nvar answer=\"\";\n\n[data_array,data_ok]=binary_decoding(stlinkpwr_binary_acq);\n\nif(data_ok==0)\n{\n for(i=4;i<Math.min(stlinkpwr_binary_acq.length-6,30);i++)    \n {\n answer+=String.fromCharCode(stlinkpwr_binary_acq[i])\n     \n }\n data_array=-1;\n}\nelse\n{\n answer=\"acq ok.\";//data_array.length+\" samples\"\n}\n\nmsg={}\nmsg.payload=answer\ndata={}\ndata.payload=data_array\n\nreturn [msg,data]\n\n\nfunction binary_decoding(acq_array)\n{\nvar samples=[];\nvar cycles=[];\nvar start_process=1;\nvar index=0;\nvar data_ok=0;\n//\"ack start\\n\"\nvar hex_header=[\"61\",\"63\",\"6b\",\"20\",\"73\",\"74\",\"61\",\"72\",\"74\",\"d\",\"a\",\"d\",\"a\"]\n\nfor (i=hex_header.length;i<(acq_array.length-1);i++)\n{\n     \nif( (acq_array[i-1]==parseInt(\"3E\", 16)) & (acq_array[i]==parseInt(\"20\", 16)) & (start_process==0))\n    {start_process=1;i=i+1;}\n\nif(start_process==1)\n  {\n    if((acq_array[i]==parseInt(\"F0\", 16)) & (acq_array[i+1]==parseInt(\"F4\", 16)) & (acq_array[i+2]==parseInt(\"FF\", 16)) & (acq_array[i+3]==parseInt(\"FF\", 16)))\n    {\n    data_ok=1;\n    i=acq_array.length;\n    }\n    else\n    {\n    stlinkpwr_sum=acq_array[i]*256+ acq_array[i+1]*1;\n    stlinkpwr_base=stlinkpwr_sum & parseInt(\"0FFF\",16);\n    stlinkpwr_exp=(stlinkpwr_sum & parseInt(\"F000\",16))/(parseInt(\"1000\",16));\n    samples[index]=stlinkpwr_base/(Math.pow(16,stlinkpwr_exp));\n    index=index+1;\n    i=i+1;\n    }\n    }\n\n}\n\nreturn [samples,data_ok]\n\n}\n ",
        "outputs": 2,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "x": 1060,
        "y": 420,
        "wires": [
            [
                "607e96e9.655ba8"
            ],
            [
                "21bc1c3a.549794"
            ]
        ]
    },
    {
        "id": "21bc1c3a.549794",
        "type": "switch",
        "z": "7284a1cc.fc435",
        "name": "",
        "property": "payload",
        "propertyType": "msg",
        "rules": [
            {
                "t": "neq",
                "v": "-1",
                "vt": "str"
            }
        ],
        "checkall": "true",
        "repair": false,
        "outputs": 1,
        "x": 1230,
        "y": 420,
        "wires": [
            [
                "3798f42b.b5eddc"
            ]
        ]
    },
    {
        "id": "ba003014.1c2f3",
        "type": "ui_chart",
        "z": "7284a1cc.fc435",
        "name": "",
        "group": "9aead2a4.e86de",
        "order": 4,
        "width": 8,
        "height": 3,
        "label": "Current(uA)/ms",
        "chartType": "line",
        "legend": "false",
        "xformat": "SSS",
        "interpolate": "linear",
        "nodata": "Rendering...",
        "dot": false,
        "ymin": "",
        "ymax": "",
        "removeOlder": 1,
        "removeOlderPoints": "",
        "removeOlderUnit": "60",
        "cutout": 0,
        "useOneColor": false,
        "useUTC": false,
        "colors": [
            "#1f77b4",
            "#aec7e8",
            "#ff7f0e",
            "#2ca02c",
            "#98df8a",
            "#d62728",
            "#ff9896",
            "#9467bd",
            "#c5b0d5"
        ],
        "outputs": 1,
        "useDifferentColor": false,
        "className": "",
        "x": 1900,
        "y": 540,
        "wires": [
            []
        ]
    },
    {
        "id": "607e96e9.655ba8",
        "type": "switch",
        "z": "7284a1cc.fc435",
        "name": "",
        "property": "payload",
        "propertyType": "msg",
        "rules": [
            {
                "t": "else"
            },
            {
                "t": "cont",
                "v": "start",
                "vt": "str"
            }
        ],
        "checkall": "true",
        "repair": false,
        "outputs": 2,
        "x": 1330,
        "y": 300,
        "wires": [
            [
                "e4f1fa0e.79f7c8"
            ],
            [
                "85d08137.28f7c",
                "82f0ba8c.888ea8"
            ]
        ]
    },
    {
        "id": "82f0ba8c.888ea8",
        "type": "function",
        "z": "7284a1cc.fc435",
        "name": "",
        "func": "msg.payload=\"<b>acq FAILED!</b>\"\nreturn msg;",
        "outputs": 1,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "x": 1520,
        "y": 280,
        "wires": [
            [
                "e4f1fa0e.79f7c8"
            ]
        ]
    },
    {
        "id": "9aead2a4.e86de",
        "type": "ui_group",
        "name": "SourceMeter (Vout=3.3V)",
        "tab": "5fd58689.008b98",
        "order": 2,
        "disp": true,
        "width": "14",
        "collapse": true
    },
    {
        "id": "fa48ed7a.a0d7c",
        "type": "ui_group",
        "name": "Configuration & Status",
        "tab": "5fd58689.008b98",
        "order": 1,
        "disp": true,
        "width": 14,
        "collapse": true
    },
    {
        "id": "642279c6.c139b8",
        "type": "serial-port",
        "serialport": "COM37",
        "serialbaud": "115200",
        "databits": "8",
        "parity": "none",
        "stopbits": "1",
        "waitfor": "",
        "dtr": "none",
        "rts": "none",
        "cts": "none",
        "dsr": "none",
        "newline": "10",
        "bin": "bin",
        "out": "interbyte",
        "addchar": "",
        "responsetimeout": "2000"
    },
    {
        "id": "5fd58689.008b98",
        "type": "ui_tab",
        "name": "STLINK-V3-PWR (SourceMeter)",
        "icon": "memory",
        "order": 1,
        "disabled": false,
        "hidden": false
    }
]

5.2. How to use GNU Octave and the STLINK-V3PWR power interface

Find below the code example that you can save and load into GNU Octave [7], the serial port must be changed to match your computer system (refer to the global_com_port variable). Instrument-control and signal packages are preinstalled global packages included in version GNU Octave 7.1.0 and placed into the GNU Octave installation folder.

close all
warning("off")
clear h
pkg load instrument-control
pkg load signal
global global_com_port;
global_com_port="COM37";
global global_acq_format
global_acq_format="bin_hexa";
global global_acq_freq
global_acq_freq=20000;
global global_acq_time
global_acq_time=0.1;
global global_voltage
global_voltage=3.3;
global global_acq_trigsrc
global_acq_trigsrc="sw";
global global_acq_average_count
global_acq_average_count=0;
global global_acq_y
global global_first_disp
global_first_disp=1;

graphics_toolkit qt


h.ax = axes ("position", [0.1 0.42 0.5 0.5]);
h.fcn = @(x) polyval([-0.1 0.5 3 0], x);

function print_to_log(string_message,h)
if(length(string_message)>5)
if(string_message(1)=="#")
current_log="";
string_message=strrep(string_message,"#","");
else
current_log=get(h.log_label,"string");
endif

set(h.log_label,"string",strcat(string_message,"\n",current_log));
endif
endfunction

function return_string=format_scientific(input_number,input_type)
 unit="";
  if (input_number<1) input_number=input_number*1000;unit="m";endif
  if (input_number<1) input_number=input_number*1000;unit="u";endif
  if (input_number<1) input_number=input_number*1000;unit="n";endif
  if (input_number<1) input_number=input_number*1000;unit="p";endif
return_string=strcat(num2str(input_number,4),unit,input_type);
endfunction

function [scale unit]=rescale_format_scientific(input_number,input_type)
 unit=""; scale=1;
  if (input_number<1) input_number=input_number*1000;scale=scale*1000;unit="m";endif
  if (input_number<1) input_number=input_number*1000;scale=scale*1000;unit="u";endif
  if (input_number<1) input_number=input_number*1000;scale=scale*1000;unit="n";endif
  if (input_number<1) input_number=input_number*1000;scale=scale*1000;unit="p";endif
endfunction

function list_available_serial_ports(h)
    [status, text]=dos("mode");
  text_array=strsplit(text,"\n");
  for i=1:length(text_array)
  if(strfind(text_array{i},"device COM")>0)
  text_array{i}=strrep(text_array{i},":","");
  text_array{i}=strrep(text_array{i},"Status for device ","");
  text_array{i}=strrep(text_array{i}," ","");
   serial_com_port=text_array{i}
   serial_com_port=strcat("\\\\.\\",serial_com_port(1:4));
s1 = serial(serial_com_port,115200,0.1);
set(s1, "parity", "N");
set(s1, "bytesize", 8);    # Change byte size (config becomes 5-N-1)
srl_write(s1, strcat("status","\n"));
pause(0.1);
[data count] = srl_read(s1,100);
srl_flush(s1);
fclose(s1) # Closes and releases serial interface object
tmp_string=strsplit(char(data),"\n");

print_to_log(strcat(serial_com_port,strrep(tmp_string{1},"ack ","")),h);

   endif
endfor
endfunction

function write_serial(serial_text)
global global_com_port
serial_com_port=strcat("\\\\.\\",global_com_port);
s1 = serial(serial_com_port,115200);
set(s1, "parity", "N");
set(s1, "bytesize", 8);    # Change byte size (config becomes 5-N-1)
srl_flush(s1);
srl_write(s1, strcat(serial_text,"\n"));
fclose(s1); # Closes and releases serial interface object
disp(strcat(serial_text,"> written"));

endfunction
function query_serial(serial_text,h)
global global_com_port;
serial_com_port=strcat("\\\\.\\",global_com_port);
s1 = serial(serial_com_port,115200,0.1);
set(s1, "parity", "N");
set(s1, "bytesize", 8);    # Change byte size (config becomes 5-N-1)
srl_write(s1, strcat(serial_text,"\n"));
pause(0.1);
[data count] = srl_read(s1,100);
srl_flush(s1);
fclose(s1) # Closes and releases serial interface object
tmp_string=strsplit(char(data),"\n");

print_to_log(strrep(tmp_string{1},"ack ",""),h);
if(strcmp(serial_text,"freq 100")) global global_acq_freq;global_acq_freq=100; endif
if(strcmp(serial_text,"freq 1k")) global global_acq_freq;global_acq_freq=1000; endif
if(strcmp(serial_text,"freq 2k")) global global_acq_freq;global_acq_freq=2000; endif
if(strcmp(serial_text,"freq 5k")) global global_acq_freq;global_acq_freq=5000; endif
if(strcmp(serial_text,"freq 10k")) global global_acq_freq;global_acq_freq=10000; endif
if(strcmp(serial_text,"freq 20k")) global global_acq_freq;global_acq_freq=20000; endif
if(strcmp(serial_text,"freq 50k")) global global_acq_freq;global_acq_freq=50000; endif
if(strcmp(serial_text,"freq 100k")) global global_acq_freq;global_acq_freq=100000; endif

if(strcmp(serial_text,"acqtime 100m")) global global_acq_time;global_acq_time=0.1; endif
if(strcmp(serial_text,"acqtime 200m")) global global_acq_time;global_acq_time=0.2; endif
if(strcmp(serial_text,"acqtime 500m")) global global_acq_time;global_acq_time=0.5; endif
if(strcmp(serial_text,"acqtime 1")) global global_acq_time;global_acq_time=1; endif
if(strcmp(serial_text,"acqtime 2")) global global_acq_time;global_acq_time=2; endif
if(strcmp(serial_text,"acqtime 5")) global global_acq_time;global_acq_time=5; endif
if(strcmp(serial_text,"acqtime 10")) global global_acq_time;global_acq_time=10; endif

if(strcmp(serial_text,"volt 1600m")) global global_voltage;global_voltage=1.6; endif
if(strcmp(serial_text,"volt 1800m")) global global_voltage;global_voltage=1.8; endif
if(strcmp(serial_text,"volt 2000m")) global global_voltage;global_voltage=2.0; endif
if(strcmp(serial_text,"volt 2200m")) global global_voltage;global_voltage=2.2; endif
if(strcmp(serial_text,"volt 2400m")) global global_voltage;global_voltage=2.4; endif
if(strcmp(serial_text,"volt 2600m")) global global_voltage;global_voltage=2.6; endif
if(strcmp(serial_text,"volt 2800m")) global global_voltage;global_voltage=2.8; endif
if(strcmp(serial_text,"volt 3000m")) global global_voltage;global_voltage=3.0; endif
if(strcmp(serial_text,"volt 3200m")) global global_voltage;global_voltage=3.2; endif
if(strcmp(serial_text,"volt 3300m")) global global_voltage;global_voltage=3.3; endif
if(strcmp(serial_text,"volt 3400m")) global global_voltage;global_voltage=3.4; endif
if(strcmp(serial_text,"volt 3600m")) global global_voltage;global_voltage=3.6; endif

endfunction

function [x y xacq_title yacq_title]=stlinkpwr_start_serial(h,run_loop,global_acq_average_count)
global global_com_port;
global global_acq_time
global global_acq_freq;
global global_acq_format;
global global_voltage;
global global_first_disp
global global_temperature;

query_serial("temp pcb",h);


acq_timeout=global_acq_time*2;
serial_com_port=strcat("\\\\.\\",global_com_port);
s1 = serial(serial_com_port,115200,acq_timeout);
set(s1, "parity", "N");
set(s1, "bytesize", 8);    # Change byte size (config becomes 5-N-1)

tick=time;
srl_write(s1, "start\n");
pause(0.5)
[data acq_size] = srl_read(s1,999999);

srl_flush(s1);
fclose(s1); # Closes and releases serial interface object

j=0;
y=[0];
acq_error=1;
if(strcmp(global_acq_format,"ascii_dec")) %%ascii mode

array_acq=strsplit(char(data),"\n");
acq_size=size(array_acq);
%array_acq{1,1} ans = ack start
%array_acq{1,2}
%array_acq{1,3}
%array_acq{1,4}ans = stlp > 5321-05
array_acq{1,4}=strrep(array_acq{1,4},"stlp > ","");
for i=4:acq_size(2)
if(strcmp(array_acq{1,i},"end\r"))
  disp("Ascii Metadata: end of acquisition")
  acq_error=0;
  break;
else
j++;
endif
y(j)=str2num(strrep(array_acq{1,i},"-","e-"));
endfor
else
start_of_acq=0;
data=uint32(data);
format long
i=2; %removing header
while(i<acq_size)
if( (data(i-1)==0x3E) && (data(i)==0x20)&& (start_of_acq==0))
 start_of_acq=1;i++;
endif
if(start_of_acq)
  if((data(i)==0xF0) && (data(i+1)==0xF4) && (data(i+2)==0xFF) && (data(i+3)==0xFF))
  acq_error=0;
  i=acq_size;
  else
  j++;
  stlinkpwr_sum= sum( [data(i) data(i+1)].*[256 1]);
  stlinkpwr_base=double(bitand(stlinkpwr_sum,0x0FFF));
  stlinkpwr_exp=double(bitand(stlinkpwr_sum,0xF000)/0x1000);
  y(j)=stlinkpwr_base/(16^(stlinkpwr_exp));
  printf( "%x%x %f\n", data(i),data(i+1),y(j))
  i++;
  endif
endif
i++;
end

endif

if(acq_error)
print_to_log("Acquisition error no meta",h)
endif

samples_nb=j;
x=0:(length(y)-1);
x=x.*(1/global_acq_freq);
y_fft=abs(fft(y-mean(y)));
y_fft=y_fft(1:length(y_fft)/2);
[xx, ix] = max(y_fft);
signal_freq=ix*(global_acq_freq/samples_nb);


print_to_log(strcat("#Acquisition completed in :",num2str(time-tick),"s"),h);
print_to_log(strcat("fs=",num2str(global_acq_freq),"Hz, acqtime=",num2str(global_acq_time),"s, samples=",num2str(samples_nb)),h);
print_to_log(strcat("rms=",format_scientific(rms(y-mean(y)),"A"),", freq=",format_scientific(signal_freq,"Hz"),", period=",format_scientific(1/signal_freq,"s")),h);
print_to_log(strcat("mean=",format_scientific(mean(y),"A"),", min=",format_scientific(min(y),"A"),", max=",format_scientific(max(y),"A")),h);
print_to_log(sprintf("Acquisition: run %d / average %d",run_loop,global_acq_average_count),h);
ref_curr=str2num(get (h.reference_current, "string"));
meas_volt=str2num(get (h.reference_voltage, "string"));
i_acc_err=100*((mean(y)/ref_curr)-1);
v_acc_err=100*((meas_volt/(global_voltage))-1);

[yscale yunit]=rescale_format_scientific(max(y));
y=y.*yscale;yacq_title=sprintf("current in %sA",yunit);
[xscale xunit]=rescale_format_scientific(max(x));
x=x.*xscale;xacq_title=sprintf("time in %ss",xunit);

endfunction

function status_stlinkv3pwr(h)
 disp("");
query_serial("status",h);
query_serial("version",h);
query_serial("volt get",h);
query_serial("pwr get",h);
endfunction

function init_stlinkv3pwr(h)
global global_acq_format;
disp("");
set(h.log_label,"string","");
query_serial(sprintf("format %s",global_acq_format),h);
query_serial("volt 3300m",h);
query_serial("freq 20k",h);
query_serial("acqtime 100m",h);
query_serial("pwr on",h);
set (h.format_radio_ctrl, "value",0);
endfunction

function update_plot (obj, init = false)

  ## gcbo holds the handle of the control
  h = guidata (obj);
  replot = false;
  recalc = false;
  switch (gcbo)
    case {h.pwron_pushbutton}      query_serial("pwr on",h);
    case {h.pwroff_pushbutton}     query_serial("pwr off",h);
    case {h.status_pushbutton}     status_stlinkv3pwr(h);
    case {h.init_pushbutton}       init_stlinkv3pwr(h);
  %%  case {h.stop_pushbutton}       query_serial("stop",h);
case {h.start_pushbutton}
  global global_acq_average_count
run_loop=1;
  while(run_loop>0)
           if( (get (h.average_radio_ctrl, "value"))==0)
           clear x_acq;clear y_acq;global_acq_average_count=0;
           [x_acq y_acq xacq_title yacq_title]=stlinkpwr_start_serial(h,run_loop,global_acq_average_count);
         else
           global global_acq_y;
           clear x_acq;clear y_acq;global_acq_average_count=global_acq_average_count+1;
           [x_acq y_acq xacq_title yacq_title]=stlinkpwr_start_serial(h,run_loop,global_acq_average_count);
           if(global_acq_average_count==1)
              global_acq_y=y_acq;
           else
              global_acq_y=(y_acq+global_acq_y)./2;
              y_acq=global_acq_y;
           endif
           endif
                   h.plot = plot (x_acq,y_acq, "b");
      set (gca, "ygrid", "on");set (gca, "xgrid", "on");
      xlabel (xacq_title);ylabel (yacq_title);
      title ("Acquisition");
      grid on
      grid minor on
         run_loop=(run_loop+1)*(get (h.loop_radio_ctrl, "value"));

        endwhile
  case {h.com_port_edit}
      global global_com_port;
      global_com_port = get (gcbo, "string")
      disp(global_com_port);
    case {h.plot_title_edit}
      user_input = get (gcbo, "string");
      query_serial(user_input,h);
  case {h.commandlist_list}
    tmp=get (h.commandlist_list, "string");
    index=get (h.commandlist_list, "value");
      query_serial(tmp{index},h);
case {h.format_radio_ctrl}
global global_acq_format;
format_sel=get (h.format_radio_ctrl, "value");
if(format_sel==0)global_acq_format="ascii_dec"; else global_acq_format="bin_hexa"; endif
query_serial(sprintf("format %s",global_acq_format),h);

  endswitch

  if (recalc || init)
  if (init)
      global global_acq_freq;
      y=zeros(1,100);
      x=0:(length(y)-1);
      x=x.*(1/global_acq_freq);
      h.plot = plot (y, "b");
      set (gca, "ygrid", "on");set (gca, "xgrid", "on");
      xlabel ("time(s)");ylabel ("Current");
      guidata (obj, h);
  endif
  endif


endfunction


## Row 1 (0.9)
%h.com_port_label = uicontrol ("style", "text",
%                                "units", "normalized",
%                                "string", "COM PORT:",
%                                "horizontalalignment", "left",
%                                "position", [0.6 0.85 0.15 0.09]);
h.pwron_pushbutton = uicontrol ("style", "pushbutton",
                                "units", "normalized",
                                "string", "Power ON",
                                "fontweight", "normal",
                                "BackgroundColor", "red",
                                "callback", @update_plot,
                                "position", [0.62 0.9 0.15 0.06]);

h.com_port_edit = uicontrol ("style", "edit",
                               "units", "normalized",
                               "string", global_com_port,
                               "callback", @update_plot,
                               "position", [0.8 0.9 0.15 0.06]);

## Row 2 (0.83)
h.pwroff_pushbutton = uicontrol ("style", "pushbutton",
                                "units", "normalized",
                                "fontweight", "normal",
                                "BackgroundColor", "green",
                                "string", "Power OFF",
                                "callback", @update_plot,
                                "position", [0.62 0.83 0.15 0.06]);

h.status_pushbutton = uicontrol ("style", "pushbutton",
                                 "units", "normalized",
                                 "string", "Status",
                                 "callback", @update_plot,
                                 "value", 0,
                                 "position", [0.8 0.83 0.15 0.06]);

## Row 3 (0.76)
 h.start_pushbutton = uicontrol ("style", "pushbutton",
                                 "units", "normalized",
                                 "fontweight", "bold",
                                 "string", "Start",
                                 "callback", @update_plot,
                                 "value", 0,
                                 "position", [0.62 0.76 0.15 0.06]);

 h.init_pushbutton = uicontrol ("style", "pushbutton",
                                 "units", "normalized",
                                 "string", "Init",
                                 "callback", @update_plot,
                                 "value", 0,
                                 "position", [0.8 0.76 0.15 0.06]);

## Row 4 (0.69)
 h.stop_pushbutton = uicontrol ("style", "pushbutton",
                                 "units", "normalized",
                                 "fontweight", "normal",
                                 "string", "Stop",
                                 "callback", @update_plot,
                                 "value", 0,
                                 "position", [0.62 0.69 0.15 0.06]);

## Row 5 (0.62)
h.plot_title_label = uicontrol ("style", "text",
                                "units", "normalized",
                                "string", "Enter cmd ->",
                                "horizontalalignment", "left",
                                "position", [0.62 0.62 0.15 0.06]);

h.reference_voltage = uicontrol ("style", "edit",
                                 "units", "normalized",
                                 "string", "3.3",
                                 "callback", @update_plot,
                               "position", [0.62 0.07 .1 0.06]);

h.controls_vreflabel = uicontrol ("style", "text",
                               "units", "normalized",
                               "string", "Vmeas(V)",
                               "horizontalalignment", "left",
                               "position", [0.73 0.06 0.35 0.08]);

 h.reference_current = uicontrol ("style", "edit",
                                 "units", "normalized",
                                 "string", "1e-3",
                                 "callback", @update_plot,
                               "position", [0.62 0.012 .1 0.06]);

h.controls_ireflabel = uicontrol ("style", "text",
                               "units", "normalized",
                               "string", "Iref(A)",
                               "horizontalalignment", "left",
                               "position", [0.73 0.00 0.35 0.08]);

h.plot_title_edit = uicontrol ("style", "edit",
                               "units", "normalized",
                               "string", "version",
                               "callback", @update_plot,
                               "position", [0.77 0.62 .2 0.06]);

## Row 6 (0.55)

h.commandlist_label = uicontrol ("style", "text",
                                 "units", "normalized",
                                 "string", "Command list:",
                                 "horizontalalignment", "left",
                                 "position", [0.62 0.54 0.35 0.08]);

h.commandlist_list = uicontrol ("style", "listbox",
                                "units", "normalized",
                                "string", {"volt 1600m",
                                           "volt 1800m",
                                           "volt 2600m",
                                           "volt 3300m",
                                           "volt 3600m",
                                           "status",
                                           "version",
                                           "pwr get",
                                           "temp",
                                           "volt get",
                                           "acqtime 1",
                                           "acqtime 500m",
                                           "freq 100k",
                                           "freq 50k",
                                           "freq 20k",
                                           "freq 10k",
                                           "apiver"},
                                "callback", @update_plot,
                                "position", [0.62 0.3 0.35 0.26]);
## Row 7 (0.2)
     ## Controls
h.controls_label = uicontrol ("style", "text",
                               "units", "normalized",
                               "string", "Controls:",
                               "horizontalalignment", "left",
                               "position", [0.62 0.22 0.35 0.08]);
## Row 8 (0.15)
h.average_radio_ctrl = uicontrol ("style", "checkbox",
                                    "units", "normalized",
                                    "string", "Average",
                                    "callback", @update_plot,
                                    "position", [0.62 0.19 0.15 0.04]);

h.null_radio_ctrl = uicontrol ("style", "checkbox",
                                   "units", "normalized",
                                   "string", "Null",
                                   "callback", @update_plot,
                                   "value", 0,
                                   "position", [0.77 0.19 0.15 0.04]);

h.loop_radio_ctrl = uicontrol ("style", "checkbox",
                                   "units", "normalized",
                                   "string", "Loop",
                                   "callback", @update_plot,
                                   "value", 0,
                                   "position", [0.87 0.19 0.15 0.04]);

h.format_radio_ctrl = uicontrol ("style", "checkbox",
                                   "units", "normalized",
                                   "string", "F:Ascii/Bin",
                                   "callback", @update_plot,
                                   "value", 0,
                                   "position", [0.62 0.14 0.15 0.04]);

h.trigger_radio_ctrl = uicontrol ("style", "checkbox",
                                   "units", "normalized",
                                   "string", "T:SW/GPIO",
                                   "callback", @update_plot,
                                   "value", 0,
                                   "position", [0.77 0.14 0.15 0.04]);

## Log
h.log_label = uicontrol ("style", "text",
                                "units", "normalized",
                                "string", "Log:",
                                "horizontalalignment", "left",
                                "position", [0.05 0.05 0.5 0.3]);


## markerstyle


set (gcf, "color", get(0, "defaultuicontrolbackgroundcolor"))
guidata (gcf, h)
update_plot (gcf, true);

6. References