ArduinoとオシロスコープをExcelで制御して測定する(2) シャッタースピードの自動測定

##1. はじめに
[ArduinoとオシロスコープをExcelで制御して測定](https://qiita.com/pbjpkas/items/7da7ff99e7226fa84bcb)できるようになりました。次のステップとして、Excelは表計算ソフトという話があるので自動で測定を繰返しながらExcelらしく表計算で最大値、最小値、平均値などを得られるようにします。

ちょうど手元に機械式のカメラがあるので題材としてシャッタースピードの測定をします(筆者はカメラの設計は専門外のため測定方法の妥当性は不問とさせてください)。なお、自動といいつつ機材の都合で手作業の部分が残っていますがこれは治具で操作を自動化すれば解決可能でありスルーしていただきたく思います。

- システム全景
![システム全景](https://qiita-image-store.s3.amazonaws.com/0/221758/ce5bd87c-cdd2-b925-c941-f2436356d57c.jpeg)

- シャッターボタン自動押下の様子
![シャッターボタン自動押下](https://qiita-image-store.s3.amazonaws.com/0/221758/b1132341-3166-27c3-ef23-ac7ab7fd345e.gif)
  - ソレノイドの通電時間：200ms
  - M5Stackの液晶を白で全画面描画し明るさMaxで点灯したものを光源として使用

##2. シャッタースピード自動測定システム
###2.1 シャッタースピードの測定手順

1. カメラのレンズ側に光源を、フィルム側に光センサを配置する。
- シャッターを切って光源の光を光センサに入射し、光センサで光電変換された電圧をオシロスコープで測定する。

###2.2 自動化ポイント
以下を自動化します。

1. シャッターボタンの押下
- オシロスコープの測定結果の取得

###2.3 システムの構成要素
以下にシステムの構成要素を挙げます。上の2つは[Part1](https://qiita.com/pbjpkas/items/7da7ff99e7226fa84bcb)をご覧ください。

- SCPIコマンド対応オシロスコープ
- UARTで制御できるマイコン
- 測定対象ハードウェア(CANON FTb-N)
- 測定対象ハードウェアを操作する治具
- 光センサ(aitendo FD393-4P)
- 光源
- 測定器やマイコンを制御するExcelマクロ

####2.3.1 測定対象ハードウェア(CANON FTb-N)
測定対象のハードウェアとして[キヤノン](http://www.canon.jp)の[FTb-N](https://www.google.co.jp/search?hl=ja&as_q=canon+FTb-N)を使用します。これは1971年に[F-1](https://www.google.co.jp/search?hl=ja&as_q=canon+F-1)と一緒に発売を開始した[FTb](https://www.google.co.jp/search?hl=ja&as_q=canon+FTb)の改良機種です。

2軸式の布幕横走行[フォーカルプレーンシャッター](https://www.google.co.jp/search?hl=ja&as_q=フォーカルプレーンシャッター)を搭載しシャッタースピードはB(バルブ)、1秒、1/2秒、1/4秒、1/8秒、1/15秒、1/30秒、1/60秒、1/125秒、1/250秒、1/500秒、1/1000秒を備えます。シャッターのチャージはフィルム巻き上げ操作で行います。

####2.3.2 測定対象ハードウェアを操作する治具
カメラのシャッターを動かすには、1)シャッターをチャージする、2)シャッターボタンを押下する、の2つの操作が必要です。また、シャッタースピードの設定もあります。

今回はシャッターボタンの押下を治具で自動化します。シャッタースピードはあらかじめ設定しシャッターのチャージは手作業で行うこととします。F-1だとワインダーかモードラ(モータードライブ)でフィルム巻き上げ操作を自動化できるのですが…

#####2.3.2.1 シャッターボタンの押下
シャッターボタンの直上に配置したプッシュ型[ソレノイド](https://www.google.co.jp/search?hl=ja&as_q=ソレノイド)でシャッターボタンを押下します。

![シャッターボタン押下治具](https://qiita-image-store.s3.amazonaws.com/0/221758/85009091-4a3d-c4ed-e37b-b4dc07b90782.jpeg)

シャッターボタンの押下ストロークは2～3mm程度ですが必要な力の大きさがよくわからず(1kgf≒10Nくらい？)、また、ソレノイドを使うのは初めてでパワー不足で買い直すのもなんだかなあと思い[タカハ機工](http://www.takaha.co.jp)の[CB12500045](http://www.takaha.co.jp/SHOP/CB12500045.html)を購入しました。実際にテストベンチを組んで動かしたところもう一回り小さくても良いように思います。

CB12500045はDC12Vで動作させるとストローク3mmにおける吸引力が15N(≒1.5kgf)程度となります(※1)。DC12Vの場合は通電率25%で使用することになりますが一瞬だけONしてシャッターボタンを押下したあと少なくとも数秒以上OFFが続きますので特に問題はありません。

ベース板に[タミヤ](http://www.tamiya.com/japan/index.html)の[透明ユニバーサルプレートL](https://www.google.com/search?q=透明ユニバーサルプレートL)を、ソレノイドの支持に[透明ロングユニバーサルアームセット](https://www.google.com/search?q=透明ロングユニバーサルアームセット)を使用しました。高さの微調整はワッシャーで行いソレノイドのねじ穴はΦ4mmのため穴を広げる加工をしています。

参考：
 [ソレノイドの技術解説(タカハ機工)](http://www.takaha.co.jp/technological/)
 [【ソレノイド・入門編】なるほど納得！カタログ（吸引グラフ）の見方！](https://ameblo.jp/solcon/entry-11977796391.html)
 [CB1250シリーズの仕様](http://www.takaha.co.jp/catalog/CB1250.pdf)
※1：CB12500045は抵抗値が4.5ΩでDC12Vを給電すると電流は2.7A、消費電力は32Wとなります。仕様書の吸引力‐ストローク特性図における30Wの特性からストローク3mmにおける吸引力を約15Nと読み取っています。

#####2.3.2.2 ソレノイド駆動回路
Arduino LeonardoのI/O出力では電圧、電流ともソレノイドを駆動するには足りないため駆動回路を組みます。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/221758/fbcb94a5-99a4-71f9-ce53-08fe8197a027.png)
R1のArduino Leonardo側はDigital Pin#12に接続しています。現物合わせでひとまずR1=10kΩ、R2=510kΩとしています。詳細は付録をご覧ください。

この回路はシステムの実現性の確認を目的とした実験室レベルのものです。保護回路などは特に入っていませんので適宜[安全設計](https://www.google.co.jp/search?hl=ja&as_q=安全設計)を行ってください。以下に一例を示します。

- ヒューズの挿入。タカハ機工とは別のメーカーですが[新電元メカトロニクス](http://smt.shindengen.co.jp)の[免責事項](https://www.shindengen.co.jp/smt/disclaimer/index.html)では以下のようにヒューズの挿入が求められています。
> ソレノイドは、 入力ラインにヒューズが内蔵されていません。ソレノイド故障時には発煙・発火の危険がありますので、入力ラインに必ずヒューズを挿入して使用してください。

- 連続通電の回避。タカハ機工の[カタログの見方](http://www.takaha.co.jp/technological/catalog.html#a_02)によると通電率25%の場合は一度の通電時間は最長で2分が目安となっています。

この回路の使用に起因する一切の事象について筆者は責任を負いません。

#####2.3.2.3 Arduino Leonardo
手持ちのArduino Leonardoに以下のコマンドを実装していますのでそれを使用します。

- "port 3 high"というコマンドを受信すると digitalWrite(12, HIGH)を実行する。
- "port 3 low"というコマンドを受信すると digitalWrite(12, LOW)を実行する。

"port 3 high"でソレノイドへの給電を開始したあと"port 3 low"コマンドを受信するまで給電が続きます。

####2.3.3 光センサ(aitendo FD393-4P)
光センサとして[aitendo](http://www.aitendo.com)のフォトダイオードモジュール[FD393-4P](http://www.aitendo.com/product/11591)を使用します。

![FD393-4P](https://qiita-image-store.s3.amazonaws.com/0/221758/9742a29c-8250-7576-6b92-e7516eb9fb67.jpeg)

####2.3.4 光源
iPhone 6Sのライトをカメラのレンズ側に配置しました。構築したテストベンチを以下に掲載します。

![治具後景](https://qiita-image-store.s3.amazonaws.com/0/221758/9762965f-6180-fb74-6a6f-089d79319ba1.jpeg)


##3. 測定器やマイコンを制御するExcelマクロ
[Part1](https://qiita.com/pbjpkas/items/7da7ff99e7226fa84bcb)のマクロに以下の変更を加えました。

- SYSコマンドの引数であるWAITMSとMSGBOXを独立したコマンドに変更
- LOOPコマンド、TABLEコマンドを追加
- 10行目～19行目は1回だけ実行するコマンドを記述する
- 20行目以降はLOOPコマンドで指定された回数繰返す
- 複数回行う操作を「測定テーブル」として表形式で記述し、TABLEコマンドで表のカラムを指定する
  - 測定テーブルはF10セルより右側および下側に記述する
  - F～H、I～Kのように3カラム(制御対象機器、送信データ、受信データ)でワンセット

###3.1 仕様(のような何か)
![Excel](https://qiita-image-store.s3.amazonaws.com/0/221758/4f0f408d-cf21-88f0-7039-2101cfe38b69.png)

####3.1.1 書式

- DSO(Digital Storage Oscilloscope)のVISA ADDRESSをC6セルへ記述する
- TB(Target Board、ここではArduino Leonardo)のVISA ADDRESSをC7セルへ記述する
- 1行につき一つのコマンドを10行目以降に記述する
  - A列：制御対象機器
      1. DSO
      - TB
      - WAITMS
      - MSGBOX
      - LOOP
      - TABLE
      - SYS(SYStem、Excel VBAのウェイト調整やメッセージボックス表示)
      - //(コメント)
  - B列：送信データ(A列がDSO、TBの場合)、コマンド引数(A列がDSO、TB以外の場合)
  - C列：受信データ
      - 受信データが数値の場合はExcelの書式設定で小数点以下の桁数を適宜設定のこと
- DSOのコマンドはSCPIコマンドそのもの
  - SCPIコマンドに"?"が含まれる場合はReadString()でデータを受信しC列へ出力する
  - 例
      - :TIM:SCAL 0.01 (時間軸スケールを0.01秒に設定)
      - :MEAS:FREQ? CHAN1 (CH1の信号の周波数を測定)
      - :MEAS:ITEM? NWID
          - オシロスコープのMeasure機能で測定した値はSCPIコマンドの":MEAS:ITEM?"で取得する
          - -Wid(-Width)は":MEAS:ITEM? NWID"で取得する
- TBのコマンドは2.3.2.3参照
- WAITMSコマンドの引数はミリ秒単位の時間(最小単位：100ms)
- MSGBOXコマンドの引数はメッセージボックスに表示する文字列
- LOOPコマンドの引数は繰り返し回数
  - LOOPコマンドが実行されない場合は1が指定されたものとする
- TABLEコマンドの引数は測定テーブルの「制御対象機器」のカラム
- SYSコマンドの引数は以下の2種類
  - wait1000ms (1000msの待ち)
  - msgbox (メッセージボックスをポップアップする)

####3.1.2 動作

- テスト開始ボタンの押下をもってコマンド実行を開始する
- 実行中のコマンドのセルをSelectする
- A列が空白の行をもってコマンド実行を終了する

###3.2 プログラム
```vb
Option Explicit

Private Declare Sub Sleep Lib "KERNEL32.dll" (ByVal dwMilliseconds As Long)

Const COL_PARSER_CMD = 1     'A列：パーサ用コマンドカラム
Const COL_PARSER_TXD = 2     'B列：パーサ用送信データカラム
Const COL_PARSER_RXD = 3     'C列：パーサ用受信データカラム

Const LINE_PARSER_START = 10 'パーサ用コマンド開始行
Const LINE_PARSER_LOOP = 20  'パーサ用ループ処理開始行

Const LINE_TABLE_START = 10  '測定テーブル用コマンド開始行

Const VISA_ADDR_DSO = "C6"   'DSO : Digital Storage Oscilloscope
Const VISA_ADDR_TB = "C7"    'TB  : Target Board

'「テスト開始」ボタン押下で呼出すマクロ
Sub Parser()
    Dim i As Long
    Dim loopNum As Long
    Dim loopNumMax As Long
    loopNumMax = 1           'いったん1で設定(LOOPコマンドで上書き可)
    
    Dim strCmd As String
    Dim strTxd As String
    
    loopNum = 0
    Do While loopNum < loopNumMax
        
        i = LINE_PARSER_START
        Do While ActiveSheet.Cells(i, COL_PARSER_CMD) <> ""
        
            If loopNum >= 1 And i < LINE_PARSER_LOOP Then
                '処理をスキップする
            
            Else
                ActiveSheet.Cells(i, COL_PARSER_CMD).Select
                
                strCmd = ActiveSheet.Cells(i, COL_PARSER_CMD)
                strTxd = ActiveSheet.Cells(i, COL_PARSER_TXD)
                
                If InStr(strCmd, "//") > 0 Then
                    '何もしない
                ElseIf strCmd = "DSO" Then
                    Call ControlDSO(i, strTxd, COL_PARSER_RXD)
                
                ElseIf strCmd = "TB" Then
                    Call ControlTB(i, strTxd, COL_PARSER_RXD)
                
                ElseIf strCmd = "SYS" Then
                    Call SysControl(strTxd)
                
                ElseIf strCmd = "WAITMS" Then
                    Call SysWaitMs(strTxd)
                
                ElseIf strCmd = "MSGBOX" Then
                    MsgBox (strTxd)
                
                ElseIf strCmd = "LOOP" Then
                    If IsNumeric(strTxd) = True Then
                        loopNumMax = CInt(strTxd)
                    Else
                        MsgBox ("unknown value")
                    End If
                
                ElseIf strCmd = "TABLE" Then
                    Call SysTable(loopNum, strTxd)
                
                Else
                    MsgBox ("unknown command")
                
                End If
          
            End If
            
            i = i + 1
        Loop
        
        loopNum = loopNum + 1
    Loop

End Sub

Function SysTable(loopNum As Long, colTable As String)
    Dim i As Long
    Dim column As Long
    Dim strCmd As String
    Dim strTxd As String
    
    i = loopNum + LINE_TABLE_START
    
    column = Range(colTable + "1").column
    ActiveSheet.Cells(i, column).Select
    
    strCmd = ActiveSheet.Cells(i, column)
    strTxd = ActiveSheet.Cells(i, column + 1)
    
    If strCmd = "DSO" Then
        Call ControlDSO(i, strTxd, column + 2)
    
    ElseIf strCmd = "TB" Then
        Call ControlTB(i, strTxd, column + 2)
    
    End If
        
    i = i + 1

End Function

Function ControlDSO(line As Long, strTxd As String, colRxd As Long)
    Dim visaAddr As String
    visaAddr = ActiveSheet.Range(VISA_ADDR_DSO)
    
    Dim RM As New VisaComLib.ResourceManager
    Dim DSO As New VisaComLib.FormattedIO488
    
    Set DSO.IO = RM.Open(visaAddr)
    DSO.WriteString strTxd
    
    If InStr(strTxd, "?") > 0 Then
        ActiveSheet.Cells(line, colRxd) = Replace(DSO.ReadString(), vbLf, "")
    End If
    
    DSO.IO.Close
    Set DSO = Nothing
    Set RM = Nothing
End Function

Function ControlTB(line As Long, strTxd As String, colRxd As Long)
    Dim i As Long
    Dim j As Long
    Dim strVal As String
    Dim strArray() As String
'    Dim dbgStr As String
    
    Dim visaAddr As String
    visaAddr = ActiveSheet.Range(VISA_ADDR_TB)
    
    Dim RM As New VisaComLib.ResourceManager
    Dim TB As New VisaComLib.FormattedIO488  'TB : Target Board
    
    Set TB.IO = RM.Open(visaAddr)
    Dim sfc As VisaComLib.ISerial            'RS232C通信設定
    Set sfc = TB.IO
    sfc.BaudRate = 9600
    sfc.DataBits = 8
    sfc.Parity = ASRL_PAR_NONE
    sfc.StopBits = ASRL_STOP_ONE
    sfc.FlowControl = ASRL_FLOW_NONE
    
    TB.IO.TerminationCharacter = 10
    TB.IO.TerminationCharacterEnabled = True
    
    TB.WriteString strTxd
    
    strVal = ""
    For i = 1 To 3                           'Write→ReadのあいだにSleepを入れる
        Sleep (10)
        DoEvents
        
        strVal = strVal + TB.ReadString()
        ReDim strArray(1 To Len(strVal))
        
        For j = 1 To UBound(strArray)        '制御文字を削除する
            strArray(j) = Mid(strVal, j, 1)
            If Asc(strArray(j)) <= 31 Or 127 <= Asc(strArray(j)) Then
'                dbgStr = CStr(i) + "," + CStr(j) + "," + CStr(Asc(strArray(j)))
'                MsgBox (dbgStr)
                strArray(j) = ""
            End If
        Next j
        strVal = Join(strArray, "")
        
        If i <= 2 Then
            strVal = strVal + "/"
        End If
        
        If strVal <> "" Then
            ActiveSheet.Cells(line, colRxd).value = strVal
            'Exit For
        End If
    Next
    
    TB.IO.Close
    Set TB = Nothing
    Set RM = Nothing
End Function

Function SysWaitMs(waitMs As String)
    Dim i As Long
    Dim loopNum As Long
    
    If IsNumeric(waitMs) = True Then
        loopNum = CInt(waitMs) / 100
        For i = 1 To loopNum
            Sleep (100)
            DoEvents
        Next
    Else
        MsgBox ("unknown value")
    End If
    
End Function

Function SysControl(strTxd As String)
    Dim i As Long
    
    If strTxd = "wait1000ms" Then
        For i = 1 To 10
            Sleep (100)
            DoEvents
        Next
    
    ElseIf strTxd = "msgbox" Then
        MsgBox ("wait...")
        
    End If
    
End Function
```

##4. 自動測定の実行と結果
###4.1 自動測定の流れ
3.1のスクリーンショットを例に説明します。

1. テストベンチを構築します。
- [ミラーアップ](https://www.google.co.jp/search?hl=ja&as_q=ミラーアップ)およびシャッタースピード設定を行います。
- 光センサの感度を調整します。
- オシロスコープの諸設定(時間軸スケールおよび電圧軸スケールの設定、トリガモードの設定、Measure機能の有効化)を行います。
- Excelで上記プログラムを実行すると「フィルム巻いた?」というメッセージボックスが表示されるので、フィルム巻き上げ操作を行ってシャッターをチャージします。
- メッセージボックスのOKボタンを押すとTABLEコマンドがF10セルのコマンドを実行し、ArduinoのDigital Pin#12がHighレベルになってソレノイドが通電しシャッターボタンを押下します。
- 100ms経過後、TABLEコマンドがI10セルのコマンドを実行し、ArduinoのDigital Pin#12がLowレベルになってソレノイドが電源断しシャッターボタン押下が止まります。
- 1000ms経過後、TABLEコマンドがL10セルのコマンドを実行し、オシロスコープの測定結果を取得します。
- 測定をLOOPコマンドで指定された回数繰返します。最大値(MAX)、最小値(MIN)、平均値(AVERAGE)、中央値(MEDIAN)、標準偏差(STDEV.P)を計算するようにセルに数式を入れているのでオシロスコープから測定結果を取得するたびに自動で計算されます。

###4.2 自動測定の結果
1/60秒(≒16.7ms)の設定で10回測定した結果を以下に示します。
![シャッタースピード10回測定結果](https://qiita-image-store.s3.amazonaws.com/0/221758/103ba879-34ae-1096-1227-75bc0e69f84d.png)


##5. おわりに

- [メカトロ](https://www.google.co.jp/search?hl=ja&as_q=メカトロ)治具の製作とExcel VBAの改修を行い、ArduinoとオシロスコープをExcelで制御しシャッタースピードを自動で繰返し測定してExcelらしく表計算まで完結できました(シャッターのチャージが手作業なのはスルーでお願いします)。Excelですので表だけでなく[散布図](https://www.google.co.jp/search?hl=ja&as_q=散布図)や[箱ひげ図](https://www.google.co.jp/search?hl=ja&as_q=箱ひげ図)などで結果を整理するのもありでしょう。Excelで測定を自動化するのは合理的と思いました。

- Excelの表計算は最大値、最小値、平均値、中央値、標準偏差の計算にとどめていますが、最大値が1回でも基準を超えたらNG、平均値が基準の±XX%を超えたらNGといった判定基準を設けてGo/No-Go判定しても良いと思います。

- コマンドの実行結果がOK以外で返ってきたら測定を中断するようなアレンジもありでしょう。

- ソレノイドの通電時間100msは実際に動作させてみたところもっと短くて良さそうです(WAITMSの引数を100msより短くするにはSysWaitMs()の改修が発生します)。


##X. 付録：駆動回路の検討
###X.1 はじめに
"[Arduino ソレノイド](https://www.google.co.jp/search?hl=ja&as_q=Arduino+ソレノイド)" でググったところ[パワーMOSFET](https://www.google.com/search?q=パワーMOSFET)で制御する製作例がいくつか見つかったものの筆者はパワーMOSFETを使用した回路は設計したことがなく、これも何かの機会と思って試しました。設計は以下の流れで行いました。

1. ググって資料を集める
- 見様見真似で作ってみる
- オシロスコープで波形を見ながら回路定数を検討する

###X.2 参考資料
1. [FETの選び方・使い方ガイド | マルツオンライン](https://www.marutsu.co.jp/pc/static/large_order/fet_1-1)
- [MOS FETによるスイッチングの基礎 | マルツオンライン](https://www.marutsu.co.jp/pc/static/large_order/fet_3)
- [MOSFETゲート駆動回路](https://toshiba.semicon-storage.com/info/docget.jsp?did=59459)
- [パワーMOSFET最大定格](https://toshiba.semicon-storage.com/info/docget.jsp?did=13408)
- [安全に使用するための選定方法](https://www.rohm.co.jp/electronics-basics/transistors/tr_what6)
- [電子回路・電子工作 雑談の部屋 nMOSとpMOS-FETの使い分け，選び方について](http://e3office.webspace.ne.jp/bbs/e3office_topic_pr_13.html)
- [MOS-FETの許容損失とは？](https://okwave.jp/qa/q2477404.html)
- [リレーコイルのサージ保護について](https://ac-blog.panasonic.co.jp/%E3%83%AA%E3%83%AC-%E3%82%B3%E3%82%A4%E3%83%AB%E3%81%AE%E3%82%B5-%E3%82%B8%E4%BF%9D%E8%AD%B7%E3%81%AB%E3%81%A4%E3%81%84%E3%81%A6)
- [2SK2232(データシートおよび各種アプリケーションノート)](https://toshiba.semicon-storage.com/jp/product/mosfet/detail.2SK2232.html)
- [EKI04047(データシート)](https://www.semicon.sanken-ele.co.jp/ctrl/product/detail/EKI04047/)
- [ノイズ問題を複雑にする要因 | 村田製作所](https://www.murata.com/ja-jp/products/emc/emifil/knowhow/basic/chapter03-p1)
- [オヤイデ電気取り扱い品目一覧表](http://www.oyaide.com/application/files/1115/0287/2184/2017.pdf)

###X.3 要件
- Arduino LeonardoのDigital OutでCB12500045の給電をON/OFFできること
  - 電圧：5V
  - 電流：20mA(最大)
- ソレノイドへの給電を遮断したときに発生する逆起電力から駆動回路を保護できること

###X.4 回路
2.3.2.2の回路図を再掲します。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/221758/fbcb94a5-99a4-71f9-ce53-08fe8197a027.png)

####X.4.1 動作確認用LEDおよびサージ保護ダイオード
動作確認用にLEDを設け2mA流すこととしました。駆動回路の電源電圧を12V、LEDの電圧降下を1.8V、LEDに流す電流を2mAとすると、電流制限の抵抗Rは
R = (12V-1.8V)/2mA
  = 5100Ω
となります。

次に、ソレノイドは電気的にはコイルであり電源遮断時に逆起電力が発生します。逆起電力をソレノイド自身で吸収させるため以下の条件を満たすダイオードを接続することとし[10A10](https://www.google.co.jp/search?hl=ja&as_q=ダイオード+10A10)(逆耐電圧VRRM:1000V、順電流IF:10A)を選定しました。

- 逆耐電圧：電源電圧(12V)の10倍以上
- 順方向電流：3A以上

逆起電力は-0.9V程度、逆起電力の継続期間は100ms程度となりました。

![ソレノイドの端子間電圧(10A10接続時)](https://qiita-image-store.s3.amazonaws.com/0/221758/2f867b66-e79a-1e95-b1d5-932c82ba88b6.jpeg)
Fig. X.1 ソレノイドの端子間電圧(10A10接続時)


####X.4.2 MOSFETの選定
5Vでゲートを駆動できること、ドレイン・ソース間電圧VDSSが12Vの3倍以上あること、ドレイン電流IDが3Aの3倍以上あることを目安に2SK2232とEKI04047を候補とし、1)オン抵抗が小さい、2)Qgが小さい、3)許容損失が大きい、という点でEKI04047を選定しました。以下に仕様を抜粋します。

絶対最大定格(Ta=25℃)

|項目|記号|2SK2232|EKI04047|単位
|----|----|----|----|----
|ドレイン・ソース間電圧|VDSS|60|40|V
|ドレイン電流|ID|25|80|A
|許容損失(Tc=25℃)|PD|35|90|W
|チャネル温度|Tch|150|150|℃

熱的特性

|項目|記号|2SK2232|EKI04047|単位
|----|----|----|----|----
|チャネル・ケース間熱抵抗|Rth(ch-c)|3.57|1.4|℃/W
|チャネル・外気間熱抵抗|Rth(ch-a)|62.5|62.5|℃/W

電気的特性

|項目|記号|2SK2232|EKI04047|単位
|----|----|----|----|----
|ゲート駆動電圧(※)||4|4.5|V
|ゲートしきい値電圧|Vth|0.8(最小)、2.0(最大)|1.0(最小)、2.0(標準)、2.5(最大)|V
|ドレイン・ソース間オン抵抗|RDS(ON)|57(標準)、80(最大)(ID=12A、VGS=4V)|5.4(標準)、7.0(最大)(ID=21.4A、VGS=4.5V)|mΩ
|ゲート入力電荷量|Qg|38(VGS=10V)|16.0(VGS=4.5V)|nC

※ゲート駆動電圧：仕様書に謳われている駆動電圧

#####X.4.2.1 オン抵抗RDS(ON)
オン抵抗RDS(ON)はFET自身が消費する電力に効いてきます。ドレイン電流IDが3AのときのFETの消費電力Pと放熱器なしの場合の温度上昇を以下に計算します。

P = ID x ID x RDS(ON)

|項目|2SK2232|EKI04047|単位
|----|----|----|----
|ドレイン電流ID|3|3|A
|オン抵抗RDS(ON)(最大)|80|7.0|mΩ
|FETの消費電力|0.72|0.063|W
|チャネル・外気間熱抵抗|62.5|62.5|℃/W
|チャネルの温度上昇|45|3.9|℃

放熱器なしのときの熱抵抗はどちらも62.5℃/Wです。2SK2232が0.72W消費するとチャネル温度は45℃上昇し、Ta=25℃の場合は70℃になります。同様にEKI04047のチャネル温度は4℃上昇しTa=25℃の場合は29℃になります。

#####X.4.2.2 ゲート入力電荷量Qg
ゲート入力電荷量Qgは充電電流Igと充電時間tとの間に以下の関係があります。
    Qg = Ig x t  (Igが一定の場合)
Qgが小さいと充電電流を小さく、あるいは充電時間を短くできます。

#####X.4.2.3 許容損失PD
ここは初めよくわからなかった項目です。ソレノイドが消費する電力が32Wなのでこれより大きい必要があると思ったのですがドレイン電流を3Aとすると定常オン状態のMOSFET自身の消費電力は2SK2232は0.72W、EKI04047は0.063WでどちらもPDと比べると十分小さいです。

参考資料の6.でリンクしたページの"[51] ロードスイッチ設計のツボ(14)"というトピックがヒントになりました。MOSFETを定常オフ状態と定常オン状態の2つの状態をとるスイッチではなくゲート電圧によってドレイン・ソース間抵抗RDSが変化する可変抵抗と考えオフ～オンの過渡状態の消費電力を検討します。
![FET等価回路](https://qiita-image-store.s3.amazonaws.com/0/221758/d875a7d6-d7e1-ce91-9f8d-e335033f9e97.png)
Fig. X.2 MOSFETの等価回路

以下の回路において電源電圧V=12V、負荷抵抗RL=4.5Ωとした場合のRLの消費電力PRLおよびRDSの消費電力PRDSを計算します。RLの端子間電圧をVRL、RDSの端子間電圧をVRDSとします。

![損失計算回路](https://qiita-image-store.s3.amazonaws.com/0/221758/83051bdf-7bf0-1829-c02f-2d5dc1ed053e.png)
Fig. X.3 損失計算回路

計算は以下の4つの公式を組合わせます。

|計算式| |
|----|----
|V = R x I|オームの法則
|P = V x I = I x I x R|電力の計算
|VRL = V x RL/(RL+RDS)|抵抗による分圧
|VRDS = V x RDS/(RL+RDS)|抵抗による分圧

以下に計算結果をプロットしたものを示します。RL=RDS=4.5ΩとなったときにPRDSが最大となり、その値はPRLの最大値の1/4である8Wとなります。2SK2232、EKI04047のどちらを選定しても絶対最大定格の半分以下に収まることが分かりました。

![損失計算結果](https://qiita-image-store.s3.amazonaws.com/0/221758/1fbdb869-3890-11ae-ea83-d497c3f45c83.png)
Fig. X.4 損失計算結果

####X.4.3 ゲート抵抗R1、ゲート・ソース間抵抗R2
最初はゲート抵抗R1はなくArduino LeonardoのDigital Outとゲートは直結、ゲート・ソース間抵抗R2は1kΩで実装したのですがオシロスコープで波形を観察したところオン→オフ遷移時に盛大に振動していることがわかり回路を見直しました。R1、R2の組合わせを数パターン試し過渡応答の様子(オーバーシュートやアンダーシュートの状態、遷移時間)から実験的にひとまずR1=10kΩ、R2=510kΩとしています。この値は今後変更する可能性があります。

#####X.4.3.1 ゲート抵抗R1
ゲートに充電を開始するとゲート電圧は0Vから上昇します。Arduino LeonardoのDigital Outから見るとポートをHighレベルにして5Vを出力した瞬間に0Vに短絡することになります。Digital Outのピン一つ当たりの絶対最大定格は40mAなので最大でもその半分の20mAを超えないように電流を制限するためにゲートに抵抗R1を入れます。この抵抗は電流制限だけでなくオンオフの遷移時の振動を抑える[ダンピング抵抗](https://www.google.com/search?q=ダンピング抵抗)の役割も兼ねています。

ゲートへ流れる電流を20mA以下に制限するには以下の計算よりR1 ≧ 250Ωとすれば良いです。
R1 = 5V / 0.020A
= 250Ω

#####X.4.3.2 ゲート・ソース間抵抗R2
ゲートをマイコンと接続していない、あるいは接続してあってもマイコンのGPIOがOutputに設定されていない(Inputになっている、[Hi-Z](https://www.google.co.jp/search?hl=ja&as_q=デジタル回路+Hi-Z)になっている)ときに誤動作しないようVGSを0Vに固定するためゲートとソースを抵抗R2で接続します。

R2はR1とR2で分圧した電圧が駆動電圧(2SK2232なら4V、EKI04047なら4.5V)を超える必要があります。Digital Outの電圧が5V、駆動電圧が4.5V、R1が250Ωのとき、R2は少なくとも2250Ωより大きい必要があります。

#####X.4.3.3 過渡応答
以下にR1、R2の組合わせを6パターン試した時の過渡応答を示します。ゲートと抵抗を介して接続しているArduino LeonardoのDigital OutをHighにして5Vにすることを「オン」、Lowに設定して0Vにすることを「オフ」と呼ぶこととします。画像はR1=4.7kΩ、R2=100kΩのもので、ch1：Arduino LeonardoのDigital Outの電圧、ch2:ゲート電圧VGS、ch3：ドレイン電圧VDS、ch4：DC12Vの電源電圧です。

![ArduinoExcelVol2_R1R2_transition1.jpg](https://qiita-image-store.s3.amazonaws.com/0/221758/fc94af1d-7740-f518-a9d7-cae81f962249.jpeg)
Fig. X.5 オフ→オン

![ArduinoExcelVol2_R1R2_transition2V2.jpg](https://qiita-image-store.s3.amazonaws.com/0/221758/362fb940-6c72-02f0-f214-b72839ae4ae1.jpeg)
Fig. X.6 オン→オフ

![ArduinoExcelVol2_R1R2_transition3V2.jpg](https://qiita-image-store.s3.amazonaws.com/0/221758/50ef5a56-a1ec-8033-57db-e8a4f47d5272.jpeg)
Fig. X.7 ソレノイドの端子間電圧

![ArduinoExcelVol2_R1R2_transition_summaryV2.png](https://qiita-image-store.s3.amazonaws.com/0/221758/6b7fc522-1613-9c92-d555-6c9e44cc8d6f.png)

######X.4.3.3.1 構成#1 R1=0Ω、R2=1kΩ
- Arduino LeonardoのDigital Outの電圧とゲート電圧は等しいためch1は省略しています。
- オフ→オン時にDigital Outの電圧(ゲート電圧)が上昇した後いったん降下し、再度上昇しています。
- オン→オフ時に電源電圧、ドレイン電圧、Digital Outの電圧(ゲート電圧)のいずれもが振動しています。
- オン→オフ時にドレイン電圧が26.5Vまで上昇しています。EKI04047のドレイン・ソース間電圧の絶対最大定格は40Vなので26.5Vは67%に相当します。電源電圧も22.40Vまで振れているためこのまま使うのは落ち着かないです。

![R1=0Ω, R2=1kΩ, オフ→オン](https://qiita-image-store.s3.amazonaws.com/0/221758/c136865f-3ad4-013d-5593-0ec8c83147ac.png)
Fig. X.8 R1=0Ω, R2=1kΩ, オフ→オン

![R1=0Ω, R2=1kΩ, オン→オフ](https://qiita-image-store.s3.amazonaws.com/0/221758/5e6beb0b-d5da-7e67-d02b-668f5fb55563.png)
Fig. X.9 R1=0Ω, R2=1kΩ, オン→オフ

![R1=0Ω, R2=1kΩ, ソレノイドの端子間電圧](https://qiita-image-store.s3.amazonaws.com/0/221758/66208e36-c938-8b79-3372-65cc48097eb1.png)
Fig. X.10 R1=0, R2=1k, ソレノイドの端子間電圧

######X.4.3.3.2 構成#2 R1=470Ω、R2=100kΩ
- オン→オフ時の電源電圧、ドレイン電圧、ゲート電圧の振動が構成#1よりも収まっています。

![R1=470Ω, R2=100kΩ, オフ→オン](https://qiita-image-store.s3.amazonaws.com/0/221758/499754ce-55d9-9b34-b0b6-d529a9225c41.png)
Fig. X.11 R1=470Ω, R2=100kΩ, オフ→オン

![R1=470Ω, R2=100kΩ, オン→オフ](https://qiita-image-store.s3.amazonaws.com/0/221758/70581cde-e290-ea69-24ae-0af8cdddf17b.png)
Fig. X.12 R1=470Ω, R2=100kΩ, オン→オフ

![R1=470Ω, R2=100kΩ, ソレノイドの端子間電圧](https://qiita-image-store.s3.amazonaws.com/0/221758/b21f2a0f-5de2-5f14-b4ee-a2a77c957332.png)
Fig. X.13 R1=470Ω, R2=100kΩ, ソレノイドの端子間電圧

######X.4.3.3.3 構成#3 R1=1kΩ、R2=100kΩ
- オン→オフ時に電源電圧、ドレイン電圧にオーバーシュートがありますが振動はほぼがなくなりました。

![R1=1kΩ, R2=100kΩ, オフ→オン](https://qiita-image-store.s3.amazonaws.com/0/221758/59305ca3-50d4-d136-12cd-0cdbacf2274d.png)
Fig. X.14 R1=1kΩ, R2=100kΩ, オフ→オン

![R1=1kΩ, R2=100kΩ, オン→オフ](https://qiita-image-store.s3.amazonaws.com/0/221758/6173c0b9-b59f-8f88-1f4d-65599b6f3490.png)
Fig. X.15 R1=1kΩ, R2=100kΩ, オン→オフ

![R1=1kΩ, R2=100kΩ, ソレノイドの端子間電圧](https://qiita-image-store.s3.amazonaws.com/0/221758/20249ce8-32d8-b4f4-8ff1-66fe6fb82828.png)
Fig. X.16 R1=1kΩ, R2=100kΩ, ソレノイドの端子間電圧

######X.4.3.3.4 構成#4 R1=4.7kΩ、R2=100kΩ
- 波形はFig. X.5 ～ Fig. X.7をご参照ください。
- オン→オフ時の電源電圧、ドレイン電圧のオーバーシュート、ソレノイドの逆起電力のアンダーシュートは小さくなったものの残っています。

######X.4.3.3.5 構成#5 R1=10kΩ、R2=510kΩ
- オン→オフ時の電源電圧、ドレイン電圧のオーバーシュート、ソレノイドの逆起電力のアンダーシュートがほとんどなくなりました。

![R1=10kΩ, R2=510kΩ, オフ→オン](https://qiita-image-store.s3.amazonaws.com/0/221758/d1c76070-f3c7-e68e-1485-fd7546dd3220.png)
Fig. X.17 R1=10kΩ, R2=510kΩ, オフ→オン

![R1=10kΩ, R2=510kΩ, オン→オフ](https://qiita-image-store.s3.amazonaws.com/0/221758/33a0365f-7ae0-2854-358b-e9f68d3cb03d.png)
Fig. X.18 R1=10kΩ, R2=510kΩ, オン→オフ

![R1=10kΩ, R2=510kΩ, ソレノイドの端子間電圧](https://qiita-image-store.s3.amazonaws.com/0/221758/42b43350-77f2-876d-d5d2-c392ab822b1e.png)
Fig. X.19 R1=10kΩ, R2=510kΩ, ソレノイドの端子間電圧

######X.4.3.3.6 構成#6 R1=20kΩ、R2=510kΩ
- オン→オフ時の電源電圧、ドレイン電圧のオーバーシュート、ソレノイドの逆起電力のアンダーシュートがほぼほぼないのは構成#5と同様ですが遷移時間がほぼ倍に伸びています。

![R1=20kΩ, R2=510kΩ, オフ→オン](https://qiita-image-store.s3.amazonaws.com/0/221758/8b86e53b-b1c3-b211-8454-c5d612773c9e.png)
Fig. X.20 R1=20kΩ, R2=510kΩ, オフ→オン

![R1=20kΩ, R2=510kΩ, オン→オフ](https://qiita-image-store.s3.amazonaws.com/0/221758/9d2ec3c1-8bb8-97bd-c4dc-22912103470a.png)
Fig. X.21 R1=20kΩ, R2=510kΩ, オン→オフ

![R1=20kΩ, R2=510kΩ, ソレノイドの端子間電圧](https://qiita-image-store.s3.amazonaws.com/0/221758/af293b5a-d707-34c1-2d6e-4d1667fa43c4.png)
Fig. X.22 R1=20kΩ, R2=510kΩ, ソレノイドの端子間電圧


####X.5 実装
実装した回路を示します。連続通電は想定しておらず、あくまでも実験用です。

![実装](https://qiita-image-store.s3.amazonaws.com/0/221758/9c74274b-da0e-931b-3626-120ded61376d.jpeg)
Fig. X.17 実装写真

- 抵抗を載せ替えるたびにはんだ付けするのは過酷なため改修の際にR1とR2をピンソケットで抜差しできるようにしました。もともとピンソケットを使うことは想定しておらず空きスペースに配置した関係で抵抗を立てています。

- 10A10は足が太くて基板に挿せなかったためΦ0.8mmのスズメッキ線で足を延長しはんだ付けしています。
  - スズメッキ線はメーカーが保証する許容電流は特にないようですが参考資料の12でリンクした資料によるとΦ0.8mmの標準的なビニル電線(単線)の1芯の許容電流は9A、一方で同じΦ0.8mmでもスズメッキ線が属するマグネットワイヤーは安全電流として1.26Aが示されています。
  - Φ0.8mmのマグネットワイヤーの抵抗は参考値として36Ω/kmが示されており、使用する線材の長さを0.1mとすると線材の抵抗は3.6mΩになります。線材に流す電流を3Aとすると線材の消費する電力はP = I x I x Rより32.4mW、線材による電圧降下はV = R x Iより10.8mVとなります。

- ターミナルブロックは手持ちの都合で[TB401-1-3-E](http://akizukidenshi.com/catalog/g/gP-01405/)を使用しましたがこれは許容電流が2Aのため10Aまで許容される[TB411-2-2-E-1](http://akizukidenshi.com/catalog/g/gP-06309/)などに換装予定です。


####X.6 おわりに
- ソレノイドは初めて&パワーMOSFETも初めて&アンペアオーダーの電流をパワーMOSFETで制御するのも初めてと初めてずくめの回路設計の素人でもインターネットの情報を集めて＆実験を繰返し、実験室レベルとはいえ動くものができました。

- アプリケーションノートは専門家向けに書かれていて難しかったですが量産レベルの設計を行うには定常状態や過渡状態だけでなく熱や安全性など検討、評価すべき事柄が多岐にわたることが分かりました。

- 無鉛はんだがなかなか溶けず＆溶けても流れる前に固まってしまい部品点数が少ないわりに実装、リワークが大変でした。
  - はんだごてを450℃に設定しても無鉛はんだがなかなか溶けない(EKI04047は放熱器を背負っているようなものだし…)
  - はんだ吸い取り線でなかなか吸えない
  - 回路の見直しで1kΩの抵抗を外したらパターンが剥がれたorz、、、など