ここから本文です
S.A.の狂気の科学実験室
Mad Science Technology

webサーバー立ち上げ

 以前からTwitterで騒いでいたウェブページができました。

気温等を表示するだけです。こんなことやってるからInformation of Temperatureとか言われるんですね。ちなみに1時間おきに計測してグラフを更新しているだけです。今後の予定として
・現在の気温等を数値で表示
・過去ログのダウンロード
・測定風景の掲載
・デザインを改善(ここ重要)
をするつもりです。いかんせんhtml, cssやjavascriptにほとんど触れたことがないので意外と大変そうです・・・。とくにデザインがダサい(大事なことなので(ry)ので何とかしたものです。現状は最近話題のjavascriptは使用していませんので安心です。(あっても安全だが) データがcsvなので数値表示でjavascript使うと思います。
 サーバー自体はレンタルとかではなくラズパイを家に置いてあります。正直レンタルのほうが楽なんですが、サーバー管理をちょっとしてみたいと思ったのと、センサのデータをすぐにとってこれる方がいいのでラズパイでやりました。「ドメインって何?」っていうぐらいの無知さでもググればなんとかなるものです。おかげでこの辺の話が2%ぐらい分かるようになりました。

 測定は現状, ビニールコップにアルミ箔を巻くとかいう夏休みの工作にも劣る代物です。ちゃんとしたものを作るのは結構面倒だしお金もかかるのでまたいづれの機会に・・・。研究室の3Dプリンタとかが使えれば楽そうですが。
イメージ 1
なお、日光の遮断が十分ではないようで、日が差すと途端に気温が上がります。
 センサは言わずと知れたBME280です。よくBME280といいつつBMP280(こちらは湿度が測れない)だとかいうパチモンもありますがAmazonで\800くらいのを買ってみたところ大丈夫でした。ただ本当にBoschのものかはわかりません。現状は気象庁データと比べてそんなにおかしなデータではないので大丈夫そうです。ちなみに、なにを血迷ったかgithubのBME280用のコードは一切使わずデータシートを片手に車輪の再発明をしました。まあ浮動小数演算を使わず書いたので一応のアドバンテージはありますが。

 今日のところはこの辺で。最近はひそかに進めているコイルガンシミュレータに僅かな進展と致命的問題が生じたり。あとYahooBlogは終了するそうなので近々livedoorあたりに移行しようかと考えています。ではまた ノシ

VVVFインバータ完成

 突然ですが、VVVFインバータが完成しました。
イメージ 8
PFCでバス電圧を出力、ハーフブリッジ基板3枚で三相インバータを構成しています。ハイサイドはすべてフローティング電源でゲート電圧を供給、ローサイドはただのDCDCコンバータで3つともに供給しています。制御はSTM32F103C8T6(BluePill)、インターフェースはATmega88VでI2Cで通信しています。文章では限界があるので詳しいことは下図にて。
イメージ 10

 今回は今までのテスラコイル等とは異なり、高周波でもなければさほど大電力でもないので素子を壊すことはありませんでした。また、プリント基板で数Aクラスの電流回路を作ったのは初めてだったんですが、ユニバーサル基板で作っていたものよりもはるかに浮遊インダクタンスを減らせたようです。表裏に全く同じ銅箔形状を作ってビアを打つという方法でパターンを設計しましたが正解だったようです。
イメージ 7
テスラコイル製作でゲート周りは極限まで配線を短くすべきと身をもって知ったのでその通りに極限まで近づけて、ケミコンもつけておきました。おかげで波形はかなりきれいでした。負バイアスもかけられるように設計したので-5Vをかけておきましたが波形を見る限り誤点弧の心配はなさそうなのでスイッチングの高速化ぐらいしか意味はなさそうです。MOSFETが2SK2698というもので大容量のIGBTほど帰還容量なども大きくないせいでしょうか。ちなみに、デッドタイム軽減用にダイオードでON時とOFF時でゲート抵抗が変わるようにしましたがあまり効果はなかったようです。1Ωと10Ωでは差が小さすぎましたね。多分ON時は100Ωぐらいにしないと意味がなさそうです。結局デッドタイムはデータシートを参考に200nsとしています。

 スナバについてもテスラコイルの時の教訓を基に一括Cスナバのみでやってみましたがバス電圧供給の配線が長すぎたようでリンギングが半端なかったです。
イメージ 6
[GS間電圧(黄色) DS間電圧(青色) 9パルスモード時]
バス電圧70Vで140Vピークぐらいのサージが発生しました。これでは250V入力では500V耐圧のMOSFETは死んでしまいそうなので急遽各MOSFETのDS間に0.047uFのCを挿入して解決しました。一応つけれるようにパターンを作っておいたのが功をなしました。その結果は以下の通り。
イメージ 1
[GS間電圧(黄色) DS間電圧(青色) 非同期モード時]
当初はデッドタイムが悪いのかと思って調整しましたが全く変化がありませんでした。というわけでスイッチング速度を犠牲にする手に出たというわけです。なお、このサージは15パルスモードや9パルスモードなどの出力パルス幅が非常に小さい時のみしかもともと発生していません。
 最終的なスイッチングの特性は以下のようになりました。
イメージ 2
[GS間電圧(黄色) DS間電圧(青色) ターンオン]
イメージ 3
[GS間電圧(黄色) DS間電圧(青色) ターンオフ]
応答は500nsといったところでしょうか。一括Cスナバのみの時は200nsぐらいだったのでちょっと悲しいですが壊れたら元も子もないので・・・。あと、何気にフライホイールダイオード代わりにTVSを入れてますが、これはリカバリ特性がいいからでサージ対策のつもりはないです。これに頼ると効率が悪化しそうで使いたくなかったわけです。

 PFCについては最大500W出力で250Vという感じで設計しました。使っているMOSFETがTK20A60Uというものでいかにも電力に耐えられなさそうでしたが、意外と損失が少なかったようで、問題なく動きました。なお、周波数が低いうちに3パルスモードとかに入ると電流制限で電圧が170Vぐらいまで落ちます。制御ICはBD7691というものを使いました。NJM2375は使い物になりませんでしたがこちらはあっさり予定通り動いてくれました。
イメージ 11
FETは裏面にヒートシンクと一緒にくっついてます。回路図は以下の通り。
イメージ 4
補助巻き線がいらないという売り文句がありますがこれのためだけにACアダプタを余分に搭載するのも嫌なので補助巻き線でICに電源を供給しています。他はデータシート丸パクリです。

 ハイサイドのゲートにはフローティング電源が必要ですが、マルチ出力のRCCとかはさっぱりわからないので結局ただただトランスの巻き比で電圧を決めるという前時代的な方法を取りました。以下実物と回路図です。
イメージ 9
イメージ 5
トランスを普通に交流駆動してやればマルチ出力など簡単です。DC19Vはなぜあるかというと、制御回路用にノーパソのACアダプタを搭載していたからです。ちなみに正負電源を3ポート出力し、さらには結合係数を上げるために半分ずつ巻いたため、トランスを作るのがかなり大変でした。誰か簡単にマルチ出力得られるコンバータ作ってくださいm(__)m

 制御側のほうが骨が折れました。というのもSTMをArduino以外でがっつり開発するのはこれが初めてだったので分からないことばかりでしたので。しかしペリフェラルといい処理能力といい、ATmega88とかしか使ってこなかった身としては性能に驚愕しました。同期モードが実装できてからは割と順調にいきました。非同期モードは面倒ではあるものの、仕組みは単純なのでsinの計算ができたらすぐできました。ただ、HALの不具合やクソ仕様には苦労しましたが・・・。次回からはシンプルにレジスタをたたこうと思います。

一応完成はしたもののまだまだ問題があります。まず、I2Cの通信が途切れやすいです。どうやらHALのライブラリはACKが返ってこなかった場合、無限ループに陥るようです。クソ仕様じゃねぇか というわけでここはレジスタをたたいて自分で実装しなければなりません。また、もともとはUSB CDCとしてPCから制御できるようにするのも目標だったのでそれが実装できてないのが残念です。HALを使った最大の理由はUSBの物理層を理解せずにUSBデバイスを実装したかったからという。ここに関してはそのうち気が向いたらやります。

 だいぶ長い記事になってしまいましたが読んでくれた方に感謝。ご指摘ご質問はここのコメント欄かTwitterの方でお願いします。たぶんTwitterの方で見てくださったかとは思いますが、一応動作の様子のツイートを貼っておきます。

 VVVFの理論が①で固まったので、STM32F103C8T6用のプログラムを書いていく。いわゆるBluePillである。今回はCubeMXでペリフェラルの設定をして、自動生成されたコードをもとに、SW4STM32で開発する。せっかくなのでHALを活用していく。

 とりあえず、TIM1のCH1~3でネガティブ出力も使って、6出力を得る。当然PWMモードを使う。カウンタはセンタアラインモード3である。この辺は①の通りである。カウンタのモードとかのことは使用するチップによって違うので詳しいことは省略する。
 比較レジスタの値はDMAで自動的にセットされるように設定しておく。こうするとかなり効率よく任意パルス数の三相交流PWM出力が得られる。というのも、U相DMAにセットしたメモリアドレスを適当にオフセットしたアドレスをVW相にセットすればいいからである。パルス数を変更するときはメモリの呼び出しバイト数とアドレスのオフセットを変えるだけでよい。もちろん適切な数値への書き換えは必要だが。
 しかし、STM32F1xx系のDMAではアドレスの途中から初めてループする([0]~[5]まであるときに2, 3, 4, 5, 0, 1とループさせる)ことはできない。動作中にDMAを停止してもよければできるが、パルス変更時に出力が途切れられても困るので・・・。そこで、配列を長くとってやる。本来6だったところを6+(6*2/3)=10のようにする。こうすることでW相が[4]から読み出してもバッファオーバーランを防げる。伸ばした場所には[0]~[4]の値を代入すればいい。
イメージ 1
【各相の先頭アドレスは、太い矢印が示す場所である。なお、同じ色のセルには同じ値が入っている。】
ちなみに配列長が6(10)というのは3パルスモードの時で、9パルスモードなら18(30)、15パルスモードなら30(50)である。コードを載せたいところだが、結局この辺りはHALでは自由に設定できる関数がなく、レジスタ直叩きなのでやめておく。そもそも、最大27パルスまで可能にしようと思えば配列長は90になり、ある割り込みのうちに処理が終わるようにするにはそれ相応に処理速度が必要なので、HALでスマートに、なんてのは発想が間違ってる気がしないでもない。
 ここまでこればもう簡単である。後は割り込みとグローバル変数によるフラグの活用で変更を同期させる等のこまかいところである。正直インバータを強力なIGBTとかで作ると思うので、同期をとらなくても問題ないと思う。
 あるときの電圧、周波数をどのように決めるかは人それぞれなので割愛するが、とりあえずはVf制御でもしておけばいいと思う。

 これはVVVFインバータを作ろうとした過程で私が考えたものであり、あっている保証は全くない。むしろ詳しい方はどんどん指摘していただければ幸いです。

 VVVFインバータを作るというからには三相インバータを作るわけだが、ここではゲート波形をどのように生成するか、もう少しいうとゲートドライバにどのような信号を入力するかを考える。
 三相インバータはシングルレベル出力であれば6個のスイッチング素子(IGBT, MOSFET)があるので、信号も6種類ある。アナログ回路でこれらを生成するのはおそらく非常にめんどくさいうえ、特性の変化に悩まされるだろうから、マイコンを使う。つまり、この記事はそのプログラムをどう考えるかという内容である。

 まず、インバータが出力すべきものは、UVW相のsin波である。といっても、各アームは0~(バス電圧)までの電圧しか出力できないので、バイアスがかかることになるが、各相の線間電圧はバイアス分は消えるので問題ない。出力できる線間電圧は-(バス電圧)~(バス電圧)となる。ここで、どの相もHi-Zにする必要は基本的にないので、ローサイドへの信号はハイサイドへの信号の反転(※1)となる。また、VW相はU相に対して位相の遅れがあるだけである。この時点で、非同期制御ならアップダウンカウンタでsinテーブルの値を基に比較レジスタを設定してPWMを出力するだけと分かる。カウンタ周波数が出力の周波数に対して十分高ければこれでいい。今回使おうと考えているSTM32F103系マイコンは誘導機の数十Hzに対して十分なスピードがあり、カウンタに4つの比較レジスタがあるため簡単にできる。なお、この手の制御では位相のずれをなくすためアップダウンカウンタを使う。以後は単にカウンタと表記する。
※1: 実際にはデッドタイムが必要なので、マイコンのカウンタにデッドタイム生成機能があればそれでもいいし、なければシュミットトリガNOTとRCD回路等の非対称の遅延を発生する回路が必要。

 同期制御の場合は、出力する周波数の倍数の周波数にカウンタを設定する必要がある。これ自体はMCUに計算させてカウントのトップ値を設定するだけである。実際にはできるだけ高い分解能を保つため、プリスケーラの設定も周波数の変化とともにすべきである。式にすると
イメージ 3
イメージ 4
となる。設定すべきカウンタ周波数とカウンタのビット数、プリスケーラの設定可能な分周比からカウンタのトップ値とプリスケーラの分周比を決める。アルゴリズムは
・ビット数上の最大値にトップ値を設定した場合の分周比を計算
・それよりも小さく、設定可能な最大の分周比を選択
・選択した分周比からトップ値を計算
となる。なお、トップ値が変わるときは比較レジスタも併せて変えなければならない。カウンタのレジスタはプリロードされてトップやボトムの時に実際の値が変更されるので、非同期で計算するのはいいが、
・周波数の変更はU相の位相が0[rad]の時
・電圧の変更は各相、位相が0[rad]の時
・電圧と周波数の両方を同時に変更しない
とすれば不連続な出力にならないのでいいかもしれない。電圧の変更に関しては上記の方法だと変更後1周期は電圧が不平衡になるのでU相0[rad]ですべて変更するほうがいいかもしれないが・・・(わからん)。これらを実装するなら
・計算結果をバッファ
・変更されたしるしのフラグを立てる
・割り込み処理でフラグを確認
・フラグが立っているなら値を変更
みたいな感じになると思う。

 ここで、三相インバータのパルス数の話をする。パルス数とは出力の半周期をPWMのパルス何個でsinに近似するかという数で、結論から言うと3*(奇数)か、1が望ましい。それ以外でも出力できるが、パルス幅が左右非対称になり、パルス幅を制御しづらくなる。これは図を見ればよくわかる
(パルス数)=3
イメージ 1
(パルス数)=4
イメージ 2
振幅: 1.0
出力: UV間(下のグラフ)
横軸: U相の位相[rad]
というわけである。とりあえずは3パルスモードについて考える。
 最初の疑問は「比較レジスタの値はどう決めるか」である。3パルスでは「カウンタ周波数は出力周波数に対して十分高い」という前提は無理がある。このため、比較レジスタはその区間のsinの平均値を設定することになる。こうすることで電圧的にsinと等価な出力が得られるはずである。ちなみに、非線形関数fでは「f(xの平均値)=f(x)の平均値」とはならないので、カウンタ周期の中央の時刻におけるsinでは誤差がある。実際、3パルスでは位相π/6~π/2の平均値が必要だが、この平均値は3*sqrt(3)/(2*π)≃0.827で、sin(π/3)≃0.866である。なお、振幅最大でもduty比は1にはならない。これは、矩形波は基本波の振幅が4/π倍になることからも予想できる。
 次は、「値をいつ変更するか」である。奇数パルスでは対称的な波形を得るにはトップ、ボトムの両方で値の変更が必要である。つまり、それらのタイミングで割り込みで比較レジスタを設定すれば、その値をもとにしたPWM出力が得られる。ただし、ある割り込み処理内でレジスタを書き換えても、それが反映されるのは次に割り込みが入る瞬間になると考えられる。なので1ステップ先の値に書き換える必要がある。
 これらをまとめて図にすると、こんな感じになる。
イメージ 5
各場合1~6の設定すべき比較レジスタ値は以下のようになる。
イメージ 6
ちなみに
イメージ 7
である。
この平均値のテーブルを保存しておけばそれを読み出して振幅をかけるだけで比較レジスタ値が決定できる。また、カウンタ周波数は出力周波数の3倍と決まる。VW相については、V相ならステップ3から、W相ならステップ5から始めればよい。

 こんな具合で、9パルス、15パルスなどの場合も考えたいところだが、実はもうほとんど完成している。9パルスの場合はsin波の平均値を計算する範囲を2π/9ずつにすればいい。カウンタ周波数は出力周波数の9倍・・・とまあ規則性は単純である。なお、sin波は0~π/2までの値で0~2πまで生成できるため、平均値も範囲は限定できる。また、最初の平均値は必ず0なので、実は3パルスモードなら1個の値で、9パルスなら4個で事足りる。このあたりはMCUのメモリ、処理能力等から考えてどうするか決めればよい。個人的には全部記憶しておいて呼び出し処理を簡単にしたほうがいい気がする。
 ところで、1パルスモードだとこの理論は破綻する。平均値が常に0になるからである。そもそも、1パルスモードでは振幅を制御できない。1パルスモードというのはいわゆる120°通電であり、各相の出力はduty比を50%に保たなければ波形の対称性がなくなり、真っ当な交流出力ではなくなってしまうからである。制御できないといっても、回転数が上がればそのうちこのモードを使うだろうから、一応矩形波の生成方法を考える。考えるといっても簡単で、上の図で、r*a_s=1とすればよい。要するに1パルスモードとはduty比100%の3パルスモードである。なお、1パルスならカウンタ1周期で出力も1周期にすることもできるが、高々120Hzとかの誘導機用の三相インバータでは必要はない気がする。ただし、MCUのタイマーは比較レジスタがカウント値の下限値、上限値でも非常に短いパルスが発生することがある。これを回避する意味では1周期で出力する価値はある。

 かなり長文になってしまったが、ここまで読んでくれた方に感謝。

PFC回路を作る(製作編)

 NJM2375でPFC回路を作りました。自分でもやりたい方は設計編から読むことをお勧めします。↓
設計編: https://blogs.yahoo.co.jp/sa00000000001/16238039.html


さて、設計編で上げた数式をもとに以下のようなパラメータになりました。300Wまで安定して出力するようにと、Pin=500[W]ぐらいとなるようにシャント抵抗を決めています。出力電圧は200Vです
イメージ 1
こんな感じです。ちなみに最初は二次コイル側の巻き数を増やしてAC50Vでテストしましたがうまく機能しませんでした。0電流検出がうまく働かなかったようです。AC100V入力でうまくいきました。ちなみに回路図にはありませんがヒューズを挟んでます。

2018/10/23 追記
無負荷では一応動くようですが、VFBピンに電流が流れる、エラーアンプ出力VOL(EA)が0.6Vとかになる、等の理由により製作を断念しました。誰かが解決してくれることを願って、これらの記事を公開しておきます。

[ すべて表示 ]

本文はここまでですこのページの先頭へ
みんなの更新記事