2023年1月13日金曜日

自動計測への目覚め ~電源効率を電子負荷と電源装置だけで測る~

おはようございました。

先日重い腰を上げてやっと効率とロードレギュレーションの半自動測定化の話をした際に、

『ELS-304買った時点でできたよね?』

とうっかり気づいてしまった件について、放置もよくないので一応

電源装置PCR500Mと電子負荷装置ELS-304でも測定できるように実装する

ことにしました。


やるにあたって肝心な事をメーカーにも確認しております。

『PCR500Mの表示は最小単位が0.1だけど分解能はどうよ?』


という話です。メーカー的には

『確度としては0.1単位になるが、内部で持っている数値は実数(小数点以下5桁)で返され、分解能は、電圧が1mV、電流が1mA、電力が1mW』

とのこと、今出てる後継機(PCR500MA)も変わらないそうです。

こういうまともな質問なら個人相手でも構ってくれるのが菊水電子工業の良いところ

ぜひ今後もよろしくお願いします。


そんな訳で、我々みたいに

『正確な値じゃなくて大雑把な参考値が欲しいなら自己責任な!!』

という輩共にとっては十分有用な様子。

さて、そんな訳で早速実装してみました。


そして、転んでもただでは起きない私、前回少々心残りだった

『25%以下の負荷領域をもうちょっと精度良く測れないものか?』

『ガチ本番はAC電圧・周波数振って測るよね?』

(本業なら温度・入力条件を振って虐め倒して変な挙動が出ないか?確認する)

という課題に対し、

前者は25%以下の負荷領域は倍の密度(半分の幅)で測る、

後者はExcelのシート上に値を入れて参照するようにする、

という手で逃げることにしました。

100点取って5分そこそこなので200点取ってもいいんだけど、この先何があるか分からないのでとりあえず実装してみようと思った次第。

(過去の実績から私が今“半分暇つぶし感覚”でやってる自宅作業は、ちょっと後にやらされる仕事であることが殆ど)


さて、ここで注意点があります。

PCR500Mのデータにはゴミが混じってるよ?という話、

こいつの吐き出す数値には垂直タブ+CRの羅列が入った後、+○.○○○○○E+○○というように、余計な制御コードを桁合わせの材料としてぶっ込んできやがります。

コイツは面倒くせぇ~!

と思ったので、素直に+の位置から後ろの文字列を強引に数値化して取り出します。

後はExcelさんがヨロシクやってくれるだろう…なんて淡い期待をしておきます。

そんな訳で実装した結果、こんな感じに仕上がりました。


' 効率測定自動化用マクロ

' PCR500M - WT200 - DUT - WT200 - PLZ152WA or ELS-304 の組み合わせ

' 効率を100%負荷から0%負荷まで1%毎に計測してゆく


Dim RunFlag As Boolean      ' 動作中はTrueとなるフラグ


' スタートボタンクリック時のプログラム

Sub btnStart_Click()

    

    Dim Rdata       As String               ' 受信データ文字列

    Dim Counter     As Long                 ' データカウンタ

    Dim WT_ReadErrorFlag As Boolean         ' WT200の計測ミス時のフラグ

    Counter = 0

    

    ' 2重起動の防止

    If RunFlag Then Exit Sub

    RunFlag = True                          ' 動作中フラグをセット

    

    ' GPIB 初期設定

    Dim RM As New VisaComLib.ResourceManager                            ' リソースマネージャーの定義

    

    ' PIA4801初期設定

    If Range("E4").Value = True Then

        Dim PIA4810 As New VisaComLib.FormattedIO488                        ' 測定器の定義

        Set PIA4810.IO = RM.Open("GPIB0::" & Range("C4") & "::INSTR")       ' GPIBアドレスの設定

        PIA4810.WriteString "NODE1"                                         ' NODE1 を選択

        PIA4810.WriteString "CH1"                                           ' CH1 を選択

        PIA4810.WriteString "VSET0"                                         ' 出力は0V

    End If

            

    ' ELS-304 初期設定

    If Range("E7").Value = True Then

        Dim ELS304 As New VisaComLib.FormattedIO488                     ' 測定器の定義

        Set ELS304.IO = RM.Open("GPIB0::" & Range("C7") & "::INSTR")    ' GPIBアドレスの設定

        ELS304.WriteString "MF1"                                        ' フリーラン測定

        ELS304.WriteString "HZ1"                                        ' 設定周波数は60Hz

        ELS304.WriteString "RC0"                                        ' 電流の設定レンジは自動

        

        ELS304.WriteString "RV1"                                        ' 電圧の設定レンジは30V

'       ELS304.WriteString "RV2"                                        ' 電圧の設定レンジは4V

        

        ELS304.WriteString "CC0"                                        ' 初期設定は定電流モードで0A


'       ELS304.WriteString "CX" & Range("G7")                           ' 外部制御で+10V時の最大電流値設定

        

    End If

    

    

    

    ' WT200 電源側 初期設定

    If Range("E3").Value = True Then

        Dim WT200_IN As New VisaComLib.FormattedIO488                   ' 測定器の定義

        Set WT200_IN.IO = RM.Open("ASRL" & Range("C3") & "::INSTR")     ' COMポートアドレスの設定

        WT200_IN.WriteString "DL0"                                      ' ターミネータをCR+LFに設定

        WT200_IN.WriteString "DS1"                                      ' 表示は5桁に設定

        WT200_IN.WriteString "H0"                                       ' 出力にヘッダをつけない

        WT200_IN.WriteString "FL1"                                      ' 周波数判定用のフィルタはONに設定

        WT200_IN.WriteString "AA1"                                      ' 電流をオートレンジに設定

        WT200_IN.WriteString "AV1"                                      ' 電圧をオートレンジに設定

        WT200_IN.WriteString "AC1"                                      ' 平均化回数を8回に設定

        WT200_IN.WriteString "AG1"                                      ' 平均化を有効に設定

        WT200_IN.WriteString "AT0"                                      ' 平均化を指数化平均演算に設定

        WT200_IN.WriteString "DA1"                                      ' ディスプレイAを電圧に設定

        WT200_IN.WriteString "DB2"                                      ' ディスプレイBを電流に設定

        WT200_IN.WriteString "DC3"                                      ' ディスプレイCを電力に設定

        WT200_IN.WriteString "HD0"                                      ' 出力データはサンプルレートで更新

        WT200_IN.WriteString "MN0"                                      ' 出力データはRMS=実効値に設定

        WT200_IN.WriteString "OFD0"                                     ' 通信出力は通常測定用初期設定

    

    '   14個出力可能な個別設定は使用しない

    '   WT200_IN.WriteString "OF1,1,1"                     ' 1個目の出力は電圧

    '   WT200_IN.WriteString "OF2,2,1"                     ' 2個目の出力は電流

    '   WT200_IN.WriteString "OF3,3,1"                     ' 3個目の出力は有効電力

    '   WT200_IN.WriteString "OF4,0,1"                     ' 4個目の出力は無し

    '   WT200_IN.WriteString "OF5,0,1"                     ' 5個目の出力は無し

    '   WT200_IN.WriteString "OF6,0,1"                     ' 6個目の出力は無し

    '   WT200_IN.WriteString "OF7,0,1"                     ' 7個目の出力は無し

    '   WT200_IN.WriteString "OF8,0,1"                     ' 8個目の出力は無し

    '   WT200_IN.WriteString "OF9,0,1"                     ' 9個目の出力は無し

    '   WT200_IN.WriteString "OF10,0,1"                    ' 10個目の出力は無し

    '   WT200_IN.WriteString "OF11,0,1"                    ' 11個目の出力は無し

    '   WT200_IN.WriteString "OF12,0,1"                    ' 12個目の出力は無し

    '   WT200_IN.WriteString "OF13,0,1"                    ' 13個目の出力は無し

    '   WT200_IN.WriteString "OF14,0,1"                    ' 14個目の出力は無し

    End If

    

    

    ' WT200 電子負荷側 初期設定

    If Range("E6").Value = True Then

        Dim WT200_OUT As New VisaComLib.FormattedIO488                  ' 測定器の定義

        Set WT200_OUT.IO = RM.Open("ASRL" & Range("C6") & "::INSTR")    ' COMポートアドレスの設定

        WT200_OUT.WriteString "DL0"                                     ' ターミネータをCR+LFに設定

        WT200_OUT.WriteString "DS1"                                     ' 表示は5桁に設定

        WT200_OUT.WriteString "H0"                                      ' 出力にヘッダをつけない

        WT200_OUT.WriteString "FL1"                                     ' 周波数判定用のフィルタはONに設定

        WT200_OUT.WriteString "AA1"                                     ' 電流をオートレンジに設定

        WT200_OUT.WriteString "AV1"                                     ' 電圧をオートレンジに設定

        WT200_OUT.WriteString "AC1"                                     ' 平均化回数を8回に設定

        WT200_OUT.WriteString "AG1"                                     ' 平均化を有効に設定

        WT200_OUT.WriteString "AT0"                                     ' 平均化を指数化平均演算に設定

        WT200_OUT.WriteString "DA1"                                     ' ディスプレイAを電圧に設定

        WT200_OUT.WriteString "DB2"                                     ' ディスプレイBを電流に設定

        WT200_OUT.WriteString "DC3"                                     ' ディスプレイCを電力に設定

        WT200_OUT.WriteString "HD0"                                     ' 出力データはサンプルレートで更新

        WT200_OUT.WriteString "MN0"                                     ' 出力データはRMS=実効値に設定

        WT200_OUT.WriteString "OFD0"                                    ' 通信出力は通常測定用初期設定

    

    '   14個出力可能な個別設定は使用しない

    '   WT200_OUT.WriteString "OF1,1,1"                     ' 1個目の出力は電圧

    '   WT200_OUT.WriteString "OF2,2,1"                     ' 2個目の出力は電流

    '   WT200_OUT.WriteString "OF3,3,1"                     ' 3個目の出力は有効電力

    '   WT200_OUT.WriteString "OF4,0,1"                     ' 4個目の出力は無し

    '   WT200_OUT.WriteString "OF5,0,1"                     ' 5個目の出力は無し

    '   WT200_OUT.WriteString "OF6,0,1"                     ' 6個目の出力は無し

    '   WT200_OUT.WriteString "OF7,0,1"                     ' 7個目の出力は無し

    '   WT200_OUT.WriteString "OF8,0,1"                     ' 8個目の出力は無し

    '   WT200_OUT.WriteString "OF9,0,1"                     ' 9個目の出力は無し

    '   WT200_OUT.WriteString "OF10,0,1"                    ' 10個目の出力は無し

    '   WT200_OUT.WriteString "OF11,0,1"                    ' 11個目の出力は無し

    '   WT200_OUT.WriteString "OF12,0,1"                    ' 12個目の出力は無し

    '   WT200_OUT.WriteString "OF13,0,1"                    ' 13個目の出力は無し

    '   WT200_OUT.WriteString "OF14,0,1"                    ' 14個目の出力は無し

    End If

    

    If Range("E5").Value = True Then

        ' PCR500M 初期設定

        Dim PCR500M As New VisaComLib.FormattedIO488                    ' 測定器の定義

        Set PCR500M.IO = RM.Open("ASRL" & Range("C5") & "::INSTR")      ' COMポートアドレス設定

        PCR500M.WriteString "OUTP:COUP AC"                              ' カップリングAC設定

        PCR500M.WriteString "CURR 2.5"                                  ' AC2.5Aでリミットをかける

        PCR500M.WriteString "FREQ " & Round(Range("G6"), 1)             ' 周波数は G6 の値

        PCR500M.WriteString "VOLT " & Round(Range("G5"), 1)             ' AC電圧は G5 の値

        PCR500M.WriteString "VOLT:OFFS 0"                               ' DC電圧は0V

        PCR500M.WriteString "VOLT:RANG:AUTO"                            ' 電圧レンジは自動に設定

        PCR500M.WriteString "OUTP 1"                                    ' 出力ON

        Application.Wait [NOW()] + 500 / 86400000                       ' 出力安定までの待ち時間 500ms(コマンド応答は330ms)

    End If

            

    If Range("E7").Value = True Then

        ELS304.WriteString "CC" & Round(Range("G7"), 2)                 ' 指定された最大負荷での起動

        ELS304.WriteString "SW1"                                        ' 負荷ON

            ' いきなり最大負荷なので、最初は電力計のオートレンジを安定させる

        Application.Wait [NOW()] + 3000 / 86400000                       ' 出力安定までの待ち時間 3000ms

    End If

            

    ' 取得データのタイトルを書く

    ' 入力のデータ

    Range("A9") = "取得回数"            ' Aは取得回数を記載

    Range("B9") = "時間"                ' Bは時間を記載

    

    If Range("E3").Value = True Then

        Range("C9") = "入力電圧"        ' Cは電圧を記載

        Range("D9") = "入力電流"        ' Dは電流を記載

        Range("E9") = "入力電力"        ' Eは電力を記載

        Range("F9") = "入力周波数"      ' Fは周波数を記載

    End If

    

    ' 出力のデータ

    If Range("E6").Value = True Then

        Range("H9") = "出力電圧"        ' Hは電圧を記載

        Range("I9") = "出力電流"        ' Iは電流を記載

        Range("J9") = "出力電力"        ' Jは電を記載

        Range("K9") = "出力周波数"      ' Kは電流を記載

    End If

        

    If Range("E5").Value = True Then

        ' PCR500Mの状態

        Range("M9") = "PCR500M電圧"     ' Mは電圧を記載

        Range("N9") = "PCR500M電流"     ' Nは電流を記載

        Range("O9") = "PCR500M電力"     ' Oは電力を記載

        Range("P9") = "PCR500M力率"     ' Pは力率を記載

    End If

    

    If Range("E7").Value = True Then

        ' ELS-304のデータ

        Range("R9") = "ELS-304電圧"     ' Rは電圧を記載

        Range("S9") = "ELS-304電流"     ' Sは電流を記載

        Range("T9") = "ELS-304電力"     ' Tは電力を記載

    End If

    

        


    If Range("E4").Value = True Then

    ' いきなり最大負荷なので、最初は電力計のオートレンジを安定させる

        PIA4810.WriteString "VSET10"                                                        ' 10V出力

        Application.Wait [NOW()] + 3000 / 86400000                                          ' 数値安定までの待ち時間 3000ms

    End If

    

    

    For Counter = 0 To Range("G2")

        DoEvents

        If Counter <= (Range("G2") / 1.25 * 0.75) Then

            ' 25%以上負荷の領域は最大間隔での測定

            If Range("E4").Value = True Then

                ' (10-カウンタの値×10÷(測定点数÷1.25))V出力

                PIA4810.WriteString "VSET" & Round((10 - Counter * 10 / (Range("G2") / 1.25)), 2)

            End If

            If Range("E7").Value = True Then

                ELS304.WriteString "CC" & Round((Range("G7") * (1 - Counter / (Range("G2") / 1.25))), 2)

            End If

        Else

            ' 25%未満負荷の領域は最大間隔の半分の間隔での測定

            If Range("E4").Value = True Then

                '(10-カウンタの値×10÷(測定点数÷1.25))V出力

                PIA4810.WriteString "VSET" & Round((10 - Counter * 10 / (Range("G2") / 1.25) + (Counter - (Range("G2") / 1.25 * 0.75)) / 2 * 10 / (Range("G2") / 1.25)), 2)

            End If

            If Range("E7").Value = True Then

                ELS304.WriteString "CC" & Round((Range("G7") * ((1 - Counter / (Range("G2") / 1.25)) + (Counter - (Range("G2") / 1.25 * 0.75)) / 2 / (Range("G2") / 1.25))), 2)

            End If

        

        End If

            



        Application.Wait [NOW()] + 7000 / 86400000                                      ' 出力安定までの待ち時間 7000ms

        Range("A10").Offset(Counter, 0) = Counter                                       ' 取得回数の書き出し

        

        ' WT200入力側からのデータ読み出し

        If Range("E3").Value = True Then

            WT_ReadErrorFlag = False

            Do

                DoEvents

                If WT_ReadErrorFlag = True Then

                    Application.Wait [NOW()] + 1000 / 86400000              ' 読み込みエラーで戻ってきた場合は待ち時間 1000ms 待って再取得

                    WT_ReadErrorFlag = False

                End If

                WT200_IN.WriteString "OD"                                   ' WT200入力側測定値の問い合わせ

                

                Rdata = WT200_IN.ReadString                                 ' 電圧データの取得

                If Rdata Like "*999999.E+3*" Then                           ' Like演算子で数値エラーがが含まれているか判定する

                    WT_ReadErrorFlag = True                                 ' エラー有ならフラグを立てる

                End If

                Range("C10").Offset(Counter, 0) = Val(Rdata)                ' 電圧データの書き込み

                

                Rdata = WT200_IN.ReadString                                 ' 電流データの取得

                If Rdata Like "*999999.E+3*" Then                           ' Like演算子で数値エラーがが含まれているか判定する

                    WT_ReadErrorFlag = True                                 ' エラー有ならフラグを立てる

                End If

                Range("D10").Offset(Counter, 0) = Val(Rdata)                ' 電流データの書き込み

                

                Rdata = WT200_IN.ReadString                                 ' 電力データの取得

                If Rdata Like "*999999.E+3*" Then                           ' Like演算子で数値エラーがが含まれているか判定する

                    WT_ReadErrorFlag = True                                 ' エラー有ならフラグを立てる

                End If

                Range("E10").Offset(Counter, 0) = Val(Rdata)                ' 電力データの書き込み

                

                Rdata = WT200_IN.ReadString                                 ' 周波数データの取得

                Range("F10").Offset(Counter, 0) = Left(Rdata, 11)           ' 周波数データの書き込み

                Rdata = WT200_IN.ReadString                                 ' データ"END"の取得

                Range("G10").Offset(Counter, 0) = Rdata


            Loop While WT_ReadErrorFlag = True                              ' エラーがあったら読み込みやり直し

        End If

        

        ' WT200出力側からのデータ読み出し

        If Range("E6").Value = True Then

            WT_ReadErrorFlag = False

            Do

                DoEvents

                If WT_ReadErrorFlag = True Then

                    Application.Wait [NOW()] + 1000 / 86400000              ' 読み込みエラーで戻ってきた場合は待ち時間 1000ms 待って再取得

                    WT_ReadErrorFlag = False

                End If

                WT200_OUT.WriteString "OD"                                  ' WT200出力側測定値の問い合わせ

                

                Rdata = WT200_OUT.ReadString                                ' 電圧データの取得

                If Rdata Like "*999999.E+3*" Then                           ' Like演算子で数値エラーがが含まれているか判定する

                    WT_ReadErrorFlag = True                                 ' エラー有ならフラグを立てる

                End If

                Range("H10").Offset(Counter, 0) = Val(Rdata)                ' 電圧データの書き込み

                

                Rdata = WT200_OUT.ReadString                                ' 電流データの取得

                If Rdata Like "*999999.E+3*" Then                           ' Like演算子で数値エラーがが含まれているか判定する

                    WT_ReadErrorFlag = True                                 ' エラー有ならフラグを立てる

                End If

                Range("I10").Offset(Counter, 0) = Val(Rdata)                ' 電流データの書き込み

                

                Rdata = WT200_OUT.ReadString                                ' 電力データの取得

                If Rdata Like "*999999.E+3*" Then                           ' Like演算子で数値エラーがが含まれているか判定する

                    WT_ReadErrorFlag = True                                 ' エラー有ならフラグを立てる

                End If

                Range("J10").Offset(Counter, 0) = Val(Rdata)                ' 電力データの書き込み

                

                Rdata = WT200_OUT.ReadString                                ' 周波数データの取得

                Range("K10").Offset(Counter, 0) = Left(Rdata, 11)           ' 周波数データの書き込み

                Rdata = WT200_OUT.ReadString                                ' データ"END"の取得

                Range("L10").Offset(Counter, 0) = Rdata


            Loop While WT_ReadErrorFlag = True                              ' エラーがあったら読み込みやり直し

        End If

            

        

        Range("B10").Offset(Counter, 0) = Format(Now, "hh:mm:ss")           ' 採取時間の書き出し

                

        If Range("E5").Value = True Then

            ' ここにPCR500Mからの計測データ取得

            ' PCR500Mのデータには垂直タブとCRの制御コード羅列が混じるので、"+"以降を取得

            PCR500M.WriteString "MEAS:VOLT:AC?"                                     ' AC電圧の問い合わせ

            Rdata = PCR500M.ReadString

            Range("M10").Offset(Counter, 0) = Val(Mid(Rdata, InStr(Rdata, "+")))    ' 電圧データの書き込み

            PCR500M.WriteString "MEAS:CURR:AC?"                                     ' AC電流の問い合わせ

            Rdata = PCR500M.ReadString

            Range("N10").Offset(Counter, 0) = Val(Mid(Rdata, InStr(Rdata, "+")))    ' 電流データの書き込み

            PCR500M.WriteString "MEAS:POW:AC?"                                      ' AC電力の問い合わせ

            Rdata = PCR500M.ReadString

            Range("O10").Offset(Counter, 0) = Val(Mid(Rdata, InStr(Rdata, "+")))    ' 電力データの書き込み

            PCR500M.WriteString "MEAS:POW:AC:PFAC? "                                ' AC力率の問い合わせ

            Rdata = PCR500M.ReadString

            Range("P10").Offset(Counter, 0) = Val(Mid(Rdata, InStr(Rdata, "+")))    ' 力率データの書き込み

        End If

        

            ' ELS-304 のデータ採取

        If Range("E7").Value = True Then

            ELS304.WriteString "MV0"                                        ' 電圧の問い合わせ

            Rdata = ELS304.ReadString

            Range("R10").Offset(Counter, 0) = Val(Rdata)                    ' 電圧データの書き込み

            ELS304.WriteString "MC0"                                        ' 電流の問い合わせ

            Rdata = ELS304.ReadString

            Range("S10").Offset(Counter, 0) = Val(Rdata)                    ' 電流データの書き込み

            ELS304.WriteString "MW"                                         ' 電力の問い合わせ

            Rdata = ELS304.ReadString

            Range("T10").Offset(Counter, 0) = Val(Rdata)                    ' 電力データの書き込み

        End If

    

    Next

    

    If Range("E7").Value = True Then

        ELS304.WriteString "SW0"                                            ' ELS-304の負荷OFF

    End If

    

    If Range("E5").Value = True Then

        PCR500M.WriteString "OUTP 0"                                        ' PCR500M 出力OFF

        PCR500M.WriteString "SYST:LOC"                                      ' ローカルに戻す

    End If

    

    If Range("E4").Value = True Then

        PIA4810.WriteString "VSET 0"                                        ' 電子負荷の出力最小状態

    End If



    ' 終了処理

    If Range("E5").Value = True Then

        PCR500M.IO.Close

        Set PCR500M = Nothing

    End If

    

    If Range("E4").Value = True Then

        PIA4810.IO.Close

        Set PIA4810 = Nothing

    End If

    

    If Range("E3").Value = True Then

        WT200_IN.IO.Close

        Set WT200_IN = Nothing

    End If

    

    If Range("E6").Value = True Then

        WT200_OUT.IO.Close

        Set WT200_OUT = Nothing

    End If

    

    If Range("E7").Value = True Then

        ELS304.IO.Close

        Set ELS304 = Nothing

    End If

    

    Set RM = Nothing

    

    RunFlag = False         ' フラグのリセット

    MsgBox "終了しました"

End Sub


' ストップボタンクリックイベント

Sub btnStop_Click()

    RunFlag = False

    ' 終了処理

    If Range("E5").Value = True Then

        PCR500M.WriteString "OUTP 0"                                    ' PCR500M 出力OFF

        PCR500M.WriteString "SYST:LOC"                                  ' ローカルに戻す

        PCR500M.IO.Close

        Set PCR500M = Nothing

    End If

    

    If Range("E3").Value = True Then

        WT200_IN.IO.Close

        Set WT200_IN = Nothing

    End If

    

    If Range("E6").Value = True Then

        WT200_OUT.IO.Close

        Set WT200_OUT = Nothing

    End If

    

    If Range("E7").Value = True Then

        ELS304.WriteString "SW0"                                        ' ELS-304の負荷OFF

        ELS304.IO.Close

        Set ELS304 = Nothing

    End If

    

    

    If Range("E4").Value = True Then

        PIA4810.WriteString "VSET 0"                                        ' 電子負荷の出力最小状態

        PIA4810.IO.Close

        Set PIA4810 = Nothing

    End If

    

    

    Set RM = Nothing

End Sub



' クリアボタンクリックイベント

Sub btnClear_Click()

    If RunFlag Then

        If MsgBox("停止してデータをクリアしてよろしいですか?", vbExclamation + vbOKCancel) = vbOK Then

            Range("A9:Z65536").ClearContents

            RunFlag = False

        End If

        Exit Sub

    End If

    

    If MsgBox("データをクリアします", vbInformation + vbOKCancel) = vbOK Then

        Range("A9:Z65536").ClearContents

    End If

End Sub


'----ここまで

ソースがかなりごちゃごちゃしてきたので、この手の

『何も考えずにノリと勢い作ってみたけど、不満だったから後から拡張』

は、そろそろお腹一杯というところです。

逆に言えば私の限界点として、

“これぐらいの程度ならば設計なんて考えずに手だけ動かしてたらバグなしで余裕で書ける”

“御託は良いからサッサと手を動かせ!”

という事なのでしょう。

ではこの構成で電源装置と電子負荷から読み取った値をグラフ化してみます。




さて、やはりというか、

電子負荷装置で測ると電圧低下の影響がいくらか目についてしまう

のと、測定結果が荒い側面が表に出ています。

まぁ、ぶっちゃけこんなもんです。

あと気づいたのはELS-304は癖の強い機種ですが、外から制御する分には申し分ない動きをしてくれるので非常にありがたい…と思った次第。あれは間違っても手で操作するものではない…。


なんにせよこれで大体の電源の効率やロードレギュレーションの測定がチョロくなったので、久しぶりに快適な電源技術調査という名の

m9(^Д^)プギャー

生活を楽しむことができます。


過去作った製品とかの資料も測定点数が荒くてこれで測りなおしたいのだけど、一般経路じゃ手に入れられんので残念…。

つうか、もう製品として使っていないだろうし気にしなくてもいいか…。


ってか、これやりだしたら電圧の高いPFC周りの測定やトランス・インバータ周りもやりたくなってくるな…

次は高圧の電子負荷装置か交流負荷装置か?

こうやってフラグをしっかり立てておくことにします。

PFCやトランス・インバータなんかの案件も考えている方は投げ銭(現物支給も可)もついでに考えながら私にご相談ください。(ぉぃ

ではでは、今日はココまで。
またの機会に会える事を楽しみにしています。

2023年1月11日水曜日

自動計測への目覚め ~電源効率の自動測定化から始める~

 おはようございました。

私は技術士という立場上、

『やっちゃいけないことは正々堂々と言っておくべき立場』

なこともあって、敢えて職場の空気読まずに問題発言をバンバン発言します。

他人から見たらきっと、

言っても聞かない(その会社の風土では正しくても世間からすればダメなことは煩い)

見てほしくないものだけは見つけてくれるくせに、自分の仕事はしょうもないミスがたまにある(致命傷になりそうなもの以外は大体鈍感)

その癖問題がありそうな所だけは何故か嗅ぎ付けて割り込んでくる(致命傷には敏感)

そんな、嗅覚以外は大体残念なこともあって、どこの職場でも大体干されている今日この頃、いかがお過ごしでしょうか?

目の前に転がってきた仕事だけはさっさと片付けてしまうので、現場でガチンコしている職人さん意外には大体ウケが悪いという、ガッカリ状態でございます。

こんな状態になると『あいつに話したら粗捜しされる!』となるようで、基本放置プレイが始まります。

そういう干されているというか思えないような状態にあっては、私みたいな“生産的な仕事がないと生きてられない人間”にとっては地獄でしかなく、“何もせずとも金が落ちてくる(給与が支払われる)状況ほど怖いものはない”という恐怖に駆られます。

私自身も過去、優秀な後輩に依存して腐っていたことがあるのですが、そこから戻るためにかかる精神的苦痛って、半端ないんですよ。

はっきり言って、継続的に自律の努力をして、腐らないほうが楽です。

しかしこれがまた結構大変です。

金もかかるわ、情報は常に複数ソースを参照する必要があるわ、世間の多数派は大体残念側なので延々と孤独と戦わねばなりません。

だからこそ、世の中は自分で考えない側に堕ちた人間は、そのほとんどがまともな人間に戻れない訳で、これこそが失われた30年の根本たる原因でしょう。

多くの日本人は自律することを辞めたので今の惨状があるわけです。


さて、そんな訳で真面目に仕事をするので窓際族になってしまったという訳の分からない状況になってしまった私、ここぞ!とばかりに今までやった仕事の中で超絶面倒くさかった作業を半自動化しようと思い始めました。


中でも簡単に片づけられそうなものはないか?と探し始めたところ、偶々中古で校正後間もない電力計、横河電機のWT200(RS-232C付)が転がっていました。

これは何かできそう!と早速落札し、先日まで何かに使える…と遊びで購入した菊水電子工業のPIA4810+OP02-PIA(GPIBからアナログ出力を出せる玩具)と組み合わせて、効率とロードレギュレーションの測定の半自動化をしようと思い立ちました。


さて、最初は私がすでに購入して持っている、ソコソコ良さ気な電源PCR-500Mを使って、

PCR-500M(GPIBで測定データ取り出し)→DUT→電力計(WT200)→PLZ-152WA(+PIA-48140で制御)

みたいな形か、

電源→電力計(WT200)→DUT→ELS-304(GPIBで測定データ取り出し)

で攻めようか?と考えていたのですが、何やら電力計は2台目が出ていることに気づき、素直に

電源→電力計①→DUT→電力計②→PLZ-152WA(+PIA-48140で制御)

という形で進めることにしました。

うちのPCR-500Mの問題かもしれないのですが、RS-232Cで通信してると計測データのヘッダにゴミデータが出たり、うまく通信できないことがある模様。

WT200は結構古い機種なので、クレストファクターの問題があるにせよ、素直にシンプルな構成にしようと思います。


さて、PIA4810のセットアップから始めます。

この機種は純正のコンフィグレーションソフトが必要です。ノード番号と接続する機種を指定せねばそのまま使えないという、なんか微妙に面倒くさい代物だったりします。

中古品は付属CDがない!あっても年月立ったらCDは読み取れなくなる。

しかもダウンロード欄にもこれらのソフトの情報は出てきません。

しかし!計測機ドライバの欄のIVI-COM多重環境計測機ドライバというソフトの中に、必要なソフトがすべて同梱されています。


…分かりにくい…


さて、本体のコントロールボードスロットにOP02-PIAが刺さっていたので、それを利用します。

それぞれのノードに適当な機種を選択します。1つのボードにつき2ch実装されており、コマンド“VOUT”、“IOUT”で出力を決定できます。この時の指定値は選択した機種の最大出力の値に縮尺されるようです。

なので、換算の面倒くさがりな私は10V100Aの機種PAK10-100Aにしました。

それぞれの出力について注意点があるようで、IOUTについては0レベルの出力が困難で、若干出力が出る模様。また最大値も10Vを若干超える値が出ます。

そのため、それなりに精度よく操作したいならば、VOUTの出力一択です。ご注意下さい。

…分かりにくい…

…そのうえ汎用性に乏しい…

菊水電子は多少雑に使っても壊れない&直感で簡単に使える安心感はあるものの、こういう本筋とは違うちょっとしたところが残念仕様なので、注意が必要です。

…PLZシリーズの電流モニタ出力が周波数特性酷いとか、意外と知られていない…



次に電力計WT200の接続です。最大ボーレートが9600bpsなのですが、この速度で通信をしていると、データがうまく出力されないときがあり、たまに通信エラーが出ます。素直に4800bpsで進めましょう。

こういう罠を平気でぶっ込んでくる辺り、さすがは横河電機といったところ…


そしてこれらをExcelのVBAで実装してゆきます。RS-232Cが2ch以上あるので、いつものEasy-Commを使うのはちょっと面倒です。そのため、素直にVISA COMでの実装をしてゆきます。

今時の業界標準はコレなので、合わせてみようと持った次第。


そんな訳でこんな感じで実装してみました。汚いExcel VBAソースですがご容赦を…

Option Explicit


' 効率測定自動化用マクロ

' PCR500M - WT200 - DUT - WT200 - PLZ152WA or ELS-304(負荷量はアナログ制御) の組み合わせ

' 効率を100%負荷から0%負荷まで1%毎に計測してゆく


Dim RunFlag As Boolean      ' 動作中はTrueとなるフラグ


' スタートボタンクリック時のプログラム

Sub btnStart_Click()

    

    Dim Rdata       As String               ' 受信データ文字列

    Dim Counter     As Long                 ' データカウンタ

    Dim WT_ReadErrorFlag As Boolean         ' WT200の計測ミス時のフラグ

    Counter = 0

    

    ' 2重起動の防止

    If RunFlag Then Exit Sub

    RunFlag = True                          ' 動作中フラグをセット

    

    ' GPIB 初期設定

    Dim RM As New VisaComLib.ResourceManager        ' リソースマネージャーの定義

    

    ' PIA4801初期設定

    Dim PIA4810 As New VisaComLib.FormattedIO488                    ' 測定器の定義

    Set PIA4810.IO = RM.Open("GPIB0::" & Range("C4") & "::INSTR")   ' GPIBアドレスの設定

    PIA4810.WriteString "NODE1"                                     ' NODE1 を選択

    PIA4810.WriteString "CH1"                                       ' CH1 を選択

    PIA4810.WriteString "VSET0"                                     ' 出力は0V

    

    ' WT200 電源側 初期設定

    If Range("E3").Value = True Then

        Dim WT200_IN As New VisaComLib.FormattedIO488      ' 測定器の定義

        Set WT200_IN.IO = RM.Open("ASRL" & Range("C3") & "::INSTR")      ' COMポートアドレスの設定

        WT200_IN.WriteString "DL0"                         ' ターミネータをCR+LFに設定

        WT200_IN.WriteString "DS1"                         ' 表示は5桁に設定

        WT200_IN.WriteString "H0"                          ' 出力にヘッダをつけない

        WT200_IN.WriteString "FL1"                         ' 周波数判定用のフィルタはONに設定

        WT200_IN.WriteString "AA1"                         ' 電流をオートレンジに設定

        WT200_IN.WriteString "AV1"                         ' 電圧をオートレンジに設定

        WT200_IN.WriteString "AC1"                         ' 平均化回数を8回に設定

        WT200_IN.WriteString "AG1"                         ' 平均化を有効に設定

        WT200_IN.WriteString "AT0"                         ' 平均化を指数化平均演算に設定

        WT200_IN.WriteString "DA1"                         ' ディスプレイAを電圧に設定

        WT200_IN.WriteString "DB2"                         ' ディスプレイBを電流に設定

        WT200_IN.WriteString "DC3"                         ' ディスプレイCを電力に設定

        WT200_IN.WriteString "HD0"                         ' 出力データはサンプルレートで更新

        WT200_IN.WriteString "MN0"                         ' 出力データはRMS=実効値に設定

        WT200_IN.WriteString "OFD0"                        ' 通信出力は通常測定用初期設定

    End If

    

    

    ' WT200 電子負荷側 初期設定

    If Range("E6").Value = True Then

        Dim WT200_OUT As New VisaComLib.FormattedIO488      ' 測定器の定義

        Set WT200_OUT.IO = RM.Open("ASRL" & Range("C6") & "::INSTR")      ' COMポートアドレスの設定

        WT200_OUT.WriteString "DL0"                         ' ターミネータをCR+LFに設定

        WT200_OUT.WriteString "DS1"                         ' 表示は5桁に設定

        WT200_OUT.WriteString "H0"                          ' 出力にヘッダをつけない

        WT200_OUT.WriteString "FL1"                         ' 周波数判定用のフィルタはONに設定

        WT200_OUT.WriteString "AA1"                         ' 電流をオートレンジに設定

        WT200_OUT.WriteString "AV1"                         ' 電圧をオートレンジに設定

        WT200_OUT.WriteString "AC1"                         ' 平均化回数を8回に設定

        WT200_OUT.WriteString "AG1"                         ' 平均化を有効に設定

        WT200_OUT.WriteString "AT0"                         ' 平均化を指数化平均演算に設定

        WT200_OUT.WriteString "DA1"                         ' ディスプレイAを電圧に設定

        WT200_OUT.WriteString "DB2"                         ' ディスプレイBを電流に設定

        WT200_OUT.WriteString "DC3"                         ' ディスプレイCを電力に設定

        WT200_OUT.WriteString "HD0"                         ' 出力データはサンプルレートで更新

        WT200_OUT.WriteString "MN0"                         ' 出力データはRMS=実効値に設定

        WT200_OUT.WriteString "OFD0"                        ' 通信出力は通常測定用初期設定

    End If

    

    If Range("E5").Value = True Then

        ' PCR500M 初期設定

        Dim PCR500M As New VisaComLib.FormattedIO488    ' 測定器の定義

        Set PCR500M.IO = RM.Open("ASRL" & Range("C5") & "::INSTR")      ' COMポートアドレス設定

        PCR500M.WriteString "OUTP:COUP AC"                              ' カップリングAC設定

        PCR500M.WriteString "CURR 2.5"                                  ' AC2.5Aでリミットをかける

        PCR500M.WriteString "FREQ 60"                                   ' 周波数は60Hz

        PCR500M.WriteString "VOLT 100"                                  ' AC電圧は100V

        PCR500M.WriteString "VOLT:OFFS 0"                               ' DC電圧は0V

        PCR500M.WriteString "VOLT:RANG:AUTO"                            ' 電圧レンジは自動に設定

        PCR500M.WriteString "OUTP 1"                                    ' 出力ON

        Application.Wait [NOW()] + 500 / 86400000                       ' 出力安定までの待ち時間 500ms

    End If

            

    If Range("E7").Value = True Then

        ELS304.WriteString "SW1"                                        ' 負荷ON

        Application.Wait [NOW()] + 500 / 86400000                       ' 出力安定までの待ち時間 500ms

    End If

            

    ' 取得データのタイトルを書く

    ' 入力のデータ

    Range("A9") = "取得回数"        ' Aは取得回数を記載

    Range("B9") = "時間"            ' Bは時間を記載

    

    If Range("E3").Value = True Then

        Range("C9") = "入力電圧"        ' Cは電圧を記載

        Range("D9") = "入力電流"        ' Dは電流を記載

        Range("E9") = "入力電力"        ' Eは電流を記載

        Range("F9") = "入力周波数"      ' Fは電流を記載

    End If

    

    ' 出力のデータ

    If Range("E6").Value = True Then

        Range("H9") = "出力電圧"        ' Hは電圧を記載

        Range("I9") = "出力電流"        ' Iは電流を記載

        Range("J9") = "出力電力"        ' Jは電流を記載

        Range("K9") = "出力周波数"      ' Kは電流を記載

    End If

        

    ' いきなり最大負荷なので、最初は電力計のオートレンジを安定させる

    PIA4810.WriteString "VSET10"                                '10V出力

    Application.Wait [NOW()] + 3000 / 86400000                  ' 数値安定までの待ち時間 3000ms

    

    For Counter = 0 To Range("G2")

        DoEvents

        PIA4810.WriteString "VSET" & Round((10 - Counter * 10 / Range("G2")), 1) '(10-カウンタの値×10÷測定点数)V出力

        Application.Wait [NOW()] + 7000 / 86400000                   ' 出力安定までの待ち時間 7000ms

        Range("A10").Offset(Counter, 0) = Counter                    ' 取得回数の書き出し

        

        ' WT200入力側からのデータ読み出し

        If Range("E3").Value = True Then

            WT_ReadErrorFlag = False

            Do

                DoEvents

                If WT_ReadErrorFlag = True Then

                    Application.Wait [NOW()] + 1000 / 86400000              ' 読み込みエラーで戻ってきた場合は待ち時間 1000ms 待って再取得

                    WT_ReadErrorFlag = False

                End If

                WT200_IN.WriteString "OD"                                   ' WT200入力側測定値の問い合わせ

                

                Rdata = WT200_IN.ReadString                                 ' 電圧データの取得

                If Rdata Like "*999999.E+3*" Then                           ' Like演算子で数値エラーがが含まれているか判定する

                    WT_ReadErrorFlag = True                                 ' エラー有ならフラグを立てる

                End If

                Range("C10").Offset(Counter, 0) = Val(Rdata)                ' 電圧データの書き込み

                

                Rdata = WT200_IN.ReadString                                 ' 電流データの取得

                If Rdata Like "*999999.E+3*" Then                           ' Like演算子で数値エラーがが含まれているか判定する

                    WT_ReadErrorFlag = True                                 ' エラー有ならフラグを立てる

                End If

                Range("D10").Offset(Counter, 0) = Val(Rdata)                ' 電流データの書き込み

                

                Rdata = WT200_IN.ReadString                                 ' 電力データの取得

                If Rdata Like "*999999.E+3*" Then                           ' Like演算子で数値エラーがが含まれているか判定する

                    WT_ReadErrorFlag = True                                 ' エラー有ならフラグを立てる

                End If

                Range("E10").Offset(Counter, 0) = Val(Rdata)                ' 電力データの書き込み

                

                Rdata = WT200_IN.ReadString                                 ' 周波数データの取得

                Range("F10").Offset(Counter, 0) = Left(Rdata, 11)           ' 周波数データの書き込み

                Rdata = WT200_IN.ReadString                                 ' データ"END"の取得

                Range("G10").Offset(Counter, 0) = Rdata


            Loop While WT_ReadErrorFlag = True                              ' エラーがあったら読み込みやり直し

        End If

        

        ' WT200出力側からのデータ読み出し

        If Range("E6").Value = True Then

            WT_ReadErrorFlag = False

            Do

                DoEvents

                If WT_ReadErrorFlag = True Then

                    Application.Wait [NOW()] + 1000 / 86400000              ' 読み込みエラーで戻ってきた場合は待ち時間 1000ms 待って再取得

                    WT_ReadErrorFlag = False

                End If

                WT200_OUT.WriteString "OD"                                  ' WT200出力側測定値の問い合わせ

                

                Rdata = WT200_OUT.ReadString                                ' 電圧データの取得

                If Rdata Like "*999999.E+3*" Then                           ' Like演算子で数値エラーがが含まれているか判定する

                    WT_ReadErrorFlag = True                                 ' エラー有ならフラグを立てる

                End If

                Range("H10").Offset(Counter, 0) = Val(Rdata)                ' 電圧データの書き込み

                

                Rdata = WT200_OUT.ReadString                                ' 電流データの取得

                If Rdata Like "*999999.E+3*" Then                           ' Like演算子で数値エラーがが含まれているか判定する

                    WT_ReadErrorFlag = True                                 ' エラー有ならフラグを立てる

                End If

                Range("I10").Offset(Counter, 0) = Val(Rdata)                ' 電流データの書き込み

                

                Rdata = WT200_OUT.ReadString                                ' 電力データの取得

                If Rdata Like "*999999.E+3*" Then                           ' Like演算子で数値エラーがが含まれているか判定する

                    WT_ReadErrorFlag = True                                 ' エラー有ならフラグを立てる

                End If

                Range("J10").Offset(Counter, 0) = Val(Rdata)                ' 電力データの書き込み

                

                Rdata = WT200_OUT.ReadString                                ' 周波数データの取得

                Range("K10").Offset(Counter, 0) = Left(Rdata, 11)           ' 周波数データの書き込み

                Rdata = WT200_OUT.ReadString                                ' データ"END"の取得

                Range("L10").Offset(Counter, 0) = Rdata


            Loop While WT_ReadErrorFlag = True                              ' エラーがあったら読み込みやり直し

        End If

            

        

        Range("B10").Offset(Counter, 0) = Format(Now, "hh:mm:ss")   ' 採取時間の書き出し

    

    Next

    

    If Range("E5").Value = True Then

        PCR500M.WriteString "OUTP 0"                                    ' PCR500M 出力OFF

        PCR500M.WriteString "SYST:LOC"                                  ' ローカルに戻す

    End If

    

    PIA4810.WriteString "VSET 0"                                        ' 電子負荷の出力最小状態


    ' 終了処理

    If Range("E5").Value = True Then

        PCR500M.IO.Close

        Set PCR500M = Nothing

    End If

    PIA4810.IO.Close

    

    If Range("E3").Value = True Then

        WT200_IN.IO.Close

        Set WT200_IN = Nothing

    End If

    

    If Range("E6").Value = True Then

        WT200_OUT.IO.Close

        Set WT200_OUT = Nothing

    End If

    

    Set PIA4810 = Nothing

    

    Set RM = Nothing

    

    RunFlag = False         ' フラグのリセット

    MsgBox "終了しました"

End Sub


' ストップボタンクリックイベント

Sub btnStop_Click()

    RunFlag = False

    ' 終了処理

    If Range("E5").Value = True Then

        PCR500M.WriteString "OUTP 0"                                    ' PCR500M 出力OFF

        PCR500M.WriteString "SYST:LOC"                                  ' ローカルに戻す

        PCR500M.IO.Close

        Set PCR500M = Nothing

    End If

    

    If Range("E3").Value = True Then

        WT200_IN.IO.Close

        Set WT200_IN = Nothing

    End If

    

    If Range("E6").Value = True Then

        WT200_OUT.IO.Close

        Set WT200_OUT = Nothing

    End If

        

    PIA4810.WriteString "VSET 0"                                        ' 電子負荷の出力最小状態

    PIA4810.IO.Close

    Set PIA4810 = Nothing

    

    Set RM = Nothing

End Sub



' クリアボタンクリックイベント

Sub btnClear_Click()

    If RunFlag Then

        If MsgBox("停止してデータをクリアしてよろしいですか?", vbExclamation + vbOKCancel) = vbOK Then

            Range("A9:Z65536").ClearContents

            RunFlag = False

        End If

        Exit Sub

    End If

    

    If MsgBox("データをクリアします", vbInformation + vbOKCancel) = vbOK Then

        Range("A9:Z65536").ClearContents

    End If

End Sub


'----ここまで


そして適当なAC-DCコンバータの特性を測ってみます。

ちょうど秋月電子の5V2AのACアダプタ(GF12-US0520)があったので、こいつを生贄に捧げます。

そして測定した結果がこれ…。


今までの手作業では、無負荷から軽負荷の立ち上がり部分は数%刻み、中間は10%刻みぐらいで測定していました。

しかも計器のデジタル表示を目測で使用していて、手書きのメモ用紙に羅列を書き込み、後でExcelの表にする、そしてグラフ化して…という1系統1回の計測で大体合計1~3時間かかっていました。

しかも超絶面倒くさいので、やるというハードルもかなり高いです。

やる気になるまでにモチベーションをガッツリ上げてハイになる必要があるのです。

正直な話、電源インピーダンスやPSRRの測定よりもやりたくない測定でした。


しかし、この半自動化をすることによって、これでソコソコ正確な値を1%刻みぐらいでもガッツリ計測できるようになりました。しかも測定器の準備から30分ソコソコで1系統、2系統目からは15分弱で測定可能です。

しかもボタンを押したら後はコーヒータイム(緊急停止の心づもりだけしてれば良い)

※測定器のウォームアップは加味しない


今回電子負荷はPLZ-152WAやELS-304をアナログで使用しているので、最初に最大負荷電流を設定しておいて、10V出力でその負荷電流に設定してしまいます。

あとはPIA-4810を使って外部制御で1%刻みぐらいまでなら余裕をもって目標値への制御が効くので、綺麗に測定ができます。

何なら軽負荷の時はもっと細かくとってもいいかもしれません。


また、負荷を変化させた時の待ち時間を削ればもっと短くできそうですが、とりあえず安全圏の値1000msとしました。

※2023/01/15:WT200の平均化処理の都合で、待ち時間を7秒に増やしました。

仕事でもないし、大量に測定するわけでもありません。

世間の電源で癖の強い奴にあっては、安定するまで結構時間がかかるものもあります。

そんな訳で、毎回待ち時間を設定するのもどうか?と思うし、ここから削っても高々知れたもんです。とりあえずは外に待ち時間のパラメータを出さずに進めようと思います。


(と言いながら、実際は会社での仕事をこれでやる羽目になるんだろうけども…)


さて、これを見た方は気づいたかもしれません。

『少し前に電子負荷ELS-304を買ったときに、PCR-500Mと組み合わせて測定できたんじゃないの?』

と…。

『うん!それ、PIA-4810とWT200買って、VBA組んでいる後半で気づいた!』

…左遷にパワハラに、何分心に余裕がなかったんですよ…

ということで許してもらおう…。


さて、そんな訳で、

『こいつの効率や特性はどうなってんの?』

とか、現物持ってて知りたい方はご連絡ください。

勿論PC用のATX電源なんかの特性も測れます。

気が向いたらお手伝い(内職)できるかもしれません。

気が向いたら、私にご相談ください。


ではでは、今日はココまで。
またの機会に会える事を楽しみにしています。