院長のメモ帖
2016年7月29日 金曜日
AC電力位相制御の基礎数式
(追記) この記事には重大な数式に誤りがあり、結論が間違っています。参考にしてはいけません!
こちらを 参照してください。
電動燻製マシーンを作るにあたっての、基礎研究シリーズ、AC電力位相制御についての覚書です。
DCでヒーター出力を精密コントロールするならPWM制御を選べばマイコンのPWM端子とパワーMOSFETを使えばいいだけなので簡単ですが、ACの場合、位相制御かインバーター制御ということになりますが、どちらもそれなりの回路が要求されます。今回は位相制御を選択し、試作機は出来上がりました。その試作機については別に記事にしますが、今回は位相制御のソフトウェアの基礎となる計算式についての考察です。
AC位相制御を簡単に説明すると、トライアック(サイリスタ)を使って交流波の半波の前方部分の出力を0Vにすることで、平均電圧を100V以下の任意の電圧に落とす、という感じですね。位相制御について知りたい方はWekipediaを参照してください。この記事では、位相制御の概要は理解していることを前提に、任意の「出力電力」を得るために必要な「電力をOnにしている時間」を求める式を考察します。
今回の制御機器はヒーター(ニクロム線)ですので温度にかかわらず抵抗値Rはほぼ一定です。そこで、
Q(熱量) = k(定数) * W(電力)
= k * A(電力) * V(電圧)
= (k / R) * V 2 (式1)
となりますので、ヒーターの出力熱量は電力Wに比例、電圧Vの二乗に比例します。
また、位相制御で半波当たりのOn時間の割合をtとすると平均電圧Vは、
V = k2(定数) * (cos(0) - cos(t*π) )
= k2 * (1 - cos(t*π))
となり、t=1 (常にAC ON、すなわち最大出力時) の時のVが1になるように正規化すると K2 = 1/2となるので
V = ( 1 - cos(t*π)) /2 (式2)
になります。
t,Vに合わせて、電力Wも0-1に正規化すると式1は、
W = V 2
となりますので、式2を代入し、さらにθ = t * π (式3) とすると
W= {( 1 - cosθ ) /2}2
= cosθ 2 - 2cosθ +1
をcosθで整理すると、
cosθ 2 - 2cosθ + 1 -W = 0 (式4)
と、二次方程式が導けますので、その解は
cosθ = (2 +/- SQRT( 4 - 4*(1-W) ) / 2
= 1 +/- SQRT(W)/2
また、今回、cosθは、0-1間しかとりませんが、加算する側の解は1を超えますので、式4の有効解は
cosθ = 1 - SQRT(W) / 2 式4'
この式を cosX = YのときacosY = X の定義で変形すると
θ = acos(1 - SQRT(W) /2)
さらにθの定義、式3を代入して
t = acos(1 - SQRT(W) /2) / π 式5
これで、この式5に出力したい電力Wを代入すれば、それに必要なパルスOn時間tをマイコンで計算できるようになりました。
いやー、幾何学なんて何十年ぶりに計算したんでこの式を導出するのに丸一日かかっちゃいました。
こちらを 参照してください。
電動燻製マシーンを作るにあたっての、基礎研究シリーズ、AC電力位相制御についての覚書です。
DCでヒーター出力を精密コントロールするならPWM制御を選べばマイコンのPWM端子とパワーMOSFETを使えばいいだけなので簡単ですが、ACの場合、位相制御かインバーター制御ということになりますが、どちらもそれなりの回路が要求されます。今回は位相制御を選択し、試作機は出来上がりました。その試作機については別に記事にしますが、今回は位相制御のソフトウェアの基礎となる計算式についての考察です。
AC位相制御を簡単に説明すると、トライアック(サイリスタ)を使って交流波の半波の前方部分の出力を0Vにすることで、平均電圧を100V以下の任意の電圧に落とす、という感じですね。位相制御について知りたい方はWekipediaを参照してください。この記事では、位相制御の概要は理解していることを前提に、任意の「出力電力」を得るために必要な「電力をOnにしている時間」を求める式を考察します。
今回の制御機器はヒーター(ニクロム線)ですので温度にかかわらず抵抗値Rはほぼ一定です。そこで、
Q(熱量) = k(定数) * W(電力)
= k * A(電力) * V(電圧)
= (k / R) * V 2 (式1)
となりますので、ヒーターの出力熱量は電力Wに比例、電圧Vの二乗に比例します。
また、位相制御で半波当たりのOn時間の割合をtとすると平均電圧Vは、
V = k2(定数) * (cos(0) - cos(t*π) )
= k2 * (1 - cos(t*π))
となり、t=1 (常にAC ON、すなわち最大出力時) の時のVが1になるように正規化すると K2 = 1/2となるので
V = ( 1 - cos(t*π)) /2 (式2)
になります。
t,Vに合わせて、電力Wも0-1に正規化すると式1は、
W = V 2
となりますので、式2を代入し、さらにθ = t * π (式3) とすると
W= {( 1 - cosθ ) /2}2
= cosθ 2 - 2cosθ +1
をcosθで整理すると、
cosθ 2 - 2cosθ + 1 -W = 0 (式4)
と、二次方程式が導けますので、その解は
cosθ = (2 +/- SQRT( 4 - 4*(1-W) ) / 2
= 1 +/- SQRT(W)/2
また、今回、cosθは、0-1間しかとりませんが、加算する側の解は1を超えますので、式4の有効解は
cosθ = 1 - SQRT(W) / 2 式4'
この式を cosX = YのときacosY = X の定義で変形すると
θ = acos(1 - SQRT(W) /2)
さらにθの定義、式3を代入して
t = acos(1 - SQRT(W) /2) / π 式5
これで、この式5に出力したい電力Wを代入すれば、それに必要なパルスOn時間tをマイコンで計算できるようになりました。
いやー、幾何学なんて何十年ぶりに計算したんでこの式を導出するのに丸一日かかっちゃいました。
2016年6月18日 土曜日
C#プログラマへのC/C++の罠 その2継承修飾子?
最近はだいぶC++にも慣れ、変なエラーが出ることも少なくなりましたが、今日は久しぶりにやらかしました。
class Parent
{
virtual void Method1();
}
class Child : Parent
{
void Medhod1();
}
いわゆる、継承クラスを作ったわけですが、C++でもC#でもこの構文はだいたい同じですね。
C#では、常に修飾子overrideが子クラスのメソッドに必要ですが、C++の場合は抽象メソッドの実装時にだけ必要なのが違いますね。
まあ、そこも3分ぐらい手が止まりましたが、上記のC++コードにはもっと恐るべき罠が隠されていました。
C++プログラマーの方は、もう何が罠かお分かりかと思いますが、C#プログラマーにはその存在すら知られていない、継承修飾子というものが欠けているのです!
上記のChild定義ではこの継承修飾子を省略していますので、コンパイラはそれを補って
class Child : private Parent
{
void Medhod1();
}
と解釈します。
するとどういうことが起こるかというと、親クラスの全メンバーのアクセス修飾子をprivateとして継承してしまいます。
となると、このChildクラスは親クラスからpublicメソッドを継承しても、外部からは呼び出せないprivateメソッドに変換してしまうので、外から見ると実質何も継承していないように見え、継承を前提としたコードはすべてエラー化してしまいます。
ですから、上記のコードは
class Child : public Parent
{
void Medhod1();
}
とpublic継承修飾子を書かなければならなかったのです。
いやー、継承修飾子にたどり着くまで、C++の継承解説ホームページを4つぐらい参照しましたよ。
このページにたどり着いて疑問が解消しました。継承修飾子について詳しく知りたい方は参照してください。
使わない機能なので解説してないんでしょうが、あるからには解説しておかないと、言語解説ページとしては失格ですね(<=他人に罪をなすりつけるな)。
以前、C++プログラマーの友人と話をしていて、彼はC->C++->C#の順に習得したので、C++からC#には非常にすんなり入れたといってました。
僕は、C->C#->C++の順なんですが、どうもこの道順には、いっぱいブービートラップが潜んでいるようです。
class Parent
{
virtual void Method1();
}
class Child : Parent
{
void Medhod1();
}
いわゆる、継承クラスを作ったわけですが、C++でもC#でもこの構文はだいたい同じですね。
C#では、常に修飾子overrideが子クラスのメソッドに必要ですが、C++の場合は抽象メソッドの実装時にだけ必要なのが違いますね。
まあ、そこも3分ぐらい手が止まりましたが、上記のC++コードにはもっと恐るべき罠が隠されていました。
C++プログラマーの方は、もう何が罠かお分かりかと思いますが、C#プログラマーにはその存在すら知られていない、継承修飾子というものが欠けているのです!
上記のChild定義ではこの継承修飾子を省略していますので、コンパイラはそれを補って
class Child : private Parent
{
void Medhod1();
}
と解釈します。
するとどういうことが起こるかというと、親クラスの全メンバーのアクセス修飾子をprivateとして継承してしまいます。
となると、このChildクラスは親クラスからpublicメソッドを継承しても、外部からは呼び出せないprivateメソッドに変換してしまうので、外から見ると実質何も継承していないように見え、継承を前提としたコードはすべてエラー化してしまいます。
ですから、上記のコードは
class Child : public Parent
{
void Medhod1();
}
とpublic継承修飾子を書かなければならなかったのです。
いやー、継承修飾子にたどり着くまで、C++の継承解説ホームページを4つぐらい参照しましたよ。
このページにたどり着いて疑問が解消しました。継承修飾子について詳しく知りたい方は参照してください。
使わない機能なので解説してないんでしょうが、あるからには解説しておかないと、言語解説ページとしては失格ですね(<=他人に罪をなすりつけるな)。
以前、C++プログラマーの友人と話をしていて、彼はC->C++->C#の順に習得したので、C++からC#には非常にすんなり入れたといってました。
僕は、C->C#->C++の順なんですが、どうもこの道順には、いっぱいブービートラップが潜んでいるようです。
2016年6月 6日 月曜日
Arduino互換機の値段って...
ここのところ引き続き、Arduinoで電子工作にはまっていますが、今回は、Arduino互換機の値段について。
何を隠そう、私は今までArduinoを買ったことがありません。いや、本家のArduinoのことです。
実は私の所有するArduinoはすべていわゆる互換機というやつです。それもほとんどがNano互換機です。
というのもAmazonで検索すると、とても信じられないような値段でArduino Nano互換機が売られているのです。
もうこれなんか、価格破壊なんて言うのもばからしい 値段差ですよ!?
私は平均500円ぐらいで、すでに10個以上のNANOを手に入れています。大半は中国からの発送なので時間がかかりますが、国内発送で600円台なんでざらにありますので、迅速にほしい場合は、こちらから頼んでいます。
え?なんでそんなに買ったかって?実は電源の逆刺しやらなんやらで累計6台のNANOと一台のMEGA2560を破壊しておりまして...現在、未使用のNANO在庫は2台。そろそろ追加で購入するかな。
何を隠そう、私は今までArduinoを買ったことがありません。いや、本家のArduinoのことです。
実は私の所有するArduinoはすべていわゆる互換機というやつです。それもほとんどがNano互換機です。
というのもAmazonで検索すると、とても信じられないような値段でArduino Nano互換機が売られているのです。
もうこれなんか、価格破壊なんて言うのもばからしい 値段差ですよ!?
私は平均500円ぐらいで、すでに10個以上のNANOを手に入れています。大半は中国からの発送なので時間がかかりますが、国内発送で600円台なんでざらにありますので、迅速にほしい場合は、こちらから頼んでいます。
え?なんでそんなに買ったかって?実は電源の逆刺しやらなんやらで累計6台のNANOと一台のMEGA2560を破壊しておりまして...現在、未使用のNANO在庫は2台。そろそろ追加で購入するかな。
2016年5月19日 木曜日
Arduino開発はVisualStudioとVisualMicroで決まり
最近、狂犬病ワクチンやフィラリア、病院のすぐ横に交差点が新設されたりなんかしたおかげで、ずいぶん忙しくなってますが、時間を見つけてはArduino開発にいそしんでおります。
Arduinoは、標準でフリーの開発環境Arduino IDEを提供していますが、よくできているとはいえしょせん非商用IDE。Visual Studioの洗練度、機能性には及ぶべきもありません。
なんといっても私はVisual Basicの時代からずっとMicrosoftの開発環境におせわになっており、良くも悪くもVisual Studioに染まっています。
一時期Android開発をしようかと思ってEclipseやAndroidStudioなんかも試用してみましたが、全然開発できませんでした...
しかし、Arduino開発には、Visual MicroというVisual Studio用の拡張モジュールが存在しており、開発過程のほぼすべてをVisual Studio上でこなすことができます。
これは、革命的にマイコン開発を効率化してくれます。しかも、フリー版が存在するので無料です。
開発環境をセットアップするのも非常に簡単です。
まず、Arduino IDEをインストール、セットアップします。Visual MicroそのものにはArduino用SDKとか入っておらず、Arduino IDEを参照する形をとっています。
逆に言えば、Arduino IDEで対応するハードウェアやライブラリは、すべてVisual Microから参照できるのでほぼ100%の互換性があります。
つづいて、Visual Studioがなければこれをインストール。そしてVisual Studioの「ツール」-「拡張機能と更新」からVisual Microを検索してインストールするだけです。
私はArduino開発用のソリューションを一つ作って、ここで複数のプロジェクトを立ち上げ開発しています。
ここには当然.NETのC#プロジェクトとかも入れることができますので、たとえばPCとArduinoを連携させるようなプログラムもワンストップで構築できます。
H8のときは、日立のIDEを使ってましてそれなりによくできたIDEだとは思ったのですが、やっぱり慣れる手間もかかりますし、しばらく開発してなくて戻ってきたときに流儀を忘れていてコツをつかみなおすのに時間を取られたりして、肝心の開発が全然進まなかったりしてましたが、これからはそのような心配とも無縁になります。
そしてなにより、Team Foundation Onlineを使えるのがうれしいです。
もう、WindowsからArduino開発するなら、Visual Microで決まりですね!
Arduinoは、標準でフリーの開発環境Arduino IDEを提供していますが、よくできているとはいえしょせん非商用IDE。Visual Studioの洗練度、機能性には及ぶべきもありません。
なんといっても私はVisual Basicの時代からずっとMicrosoftの開発環境におせわになっており、良くも悪くもVisual Studioに染まっています。
一時期Android開発をしようかと思ってEclipseやAndroidStudioなんかも試用してみましたが、全然開発できませんでした...
しかし、Arduino開発には、Visual MicroというVisual Studio用の拡張モジュールが存在しており、開発過程のほぼすべてをVisual Studio上でこなすことができます。
これは、革命的にマイコン開発を効率化してくれます。しかも、フリー版が存在するので無料です。
開発環境をセットアップするのも非常に簡単です。
まず、Arduino IDEをインストール、セットアップします。Visual MicroそのものにはArduino用SDKとか入っておらず、Arduino IDEを参照する形をとっています。
逆に言えば、Arduino IDEで対応するハードウェアやライブラリは、すべてVisual Microから参照できるのでほぼ100%の互換性があります。
つづいて、Visual Studioがなければこれをインストール。そしてVisual Studioの「ツール」-「拡張機能と更新」からVisual Microを検索してインストールするだけです。
私はArduino開発用のソリューションを一つ作って、ここで複数のプロジェクトを立ち上げ開発しています。
ここには当然.NETのC#プロジェクトとかも入れることができますので、たとえばPCとArduinoを連携させるようなプログラムもワンストップで構築できます。
H8のときは、日立のIDEを使ってましてそれなりによくできたIDEだとは思ったのですが、やっぱり慣れる手間もかかりますし、しばらく開発してなくて戻ってきたときに流儀を忘れていてコツをつかみなおすのに時間を取られたりして、肝心の開発が全然進まなかったりしてましたが、これからはそのような心配とも無縁になります。
そしてなにより、Team Foundation Onlineを使えるのがうれしいです。
もう、WindowsからArduino開発するなら、Visual Microで決まりですね!
2016年5月15日 日曜日
C#プログラマへのC/C++の罠
ずいぶん、前回の記事から時間が開いてしまいましたが、除湿器の方は一応の完成をしていて、運用状態に持ち込めています。
この件についても製作記事をまとめたいところですが、今回はちょっと違う切り口で...
Arduinoの開発はVisual StudioにVisual Microを組み込んでC/C++で開発していますが、C#との違いになれるまでずいぶんあほな間違いを犯しました。
数年前にH8Tinyで開発したときにある程度C++をマスターしたつもりでしたがもうすっかり忘れてました。
CもMS-DOSの時代はポインターを使ったプログラムもばりばり書いてたはずですが、やっぱり結構忘れています...
そう、プログラミング言語も慣れが重要です。どっぷりC#に浸かりきってしまい初心者なバグを連発しています。
まず、最初にやらかしたのはinclude文、というかヘッダファイルの書き方。CPPとhの使い分けが全然思い出せませんでした。
変数の宣言の先頭にexternをつけて、headに記載し、どこか一か所のCPPで実体を定義するという、C時代なら当たり前にやっていたところからつまづきました。
あらためて、1か所で定義すればOKなC#のありがたみを感じました。
それから、アクセス修飾子にinternalがない!
これは、C#にはあるモジュールの概念がないからどうしようもないのですが、internal classを作れないと、外からはいじらせたくないけど関連するクラス間のデーター共有のためのローカルクラスが作れない...
まあ、気にせずにグローバルに定義するとか、名前空間をうまく利用すればいいのでしょうが...
それからforeach構文に相当する、for( : )構文。こんなの昔なかったけど、CPP2011から使えるようになったんですね。とてもありがたいです。
でも、なんでこんな構文なんだろう。JavaやC#にあわせて素直にforeachにすればいいと思うんですが、キーワードを極力増やさないためなんでしょうか。
逆にC#にはなくて、便利だと思った機能の筆頭に関数内のstatic変数。
C#だとclass内のprivateフィールドで対応するしかないですが、特定の関数でしか使わない変数をクラス全体で共有しなくちゃならないのは、スコープがでかすぎます。
他にもいろいろ躓いたり頷いたりしてますが、順調にarduino開発にのめりこんでいます。
前述の除湿器のほかにも、検査キット用タイマー(キッチンタイマーみたいなものですが、あらかじめ院内で使う検査キットの時間をプリセットしてある)も作って、フィラリア検査の効率化に寄与しております。
この件についても製作記事をまとめたいところですが、今回はちょっと違う切り口で...
Arduinoの開発はVisual StudioにVisual Microを組み込んでC/C++で開発していますが、C#との違いになれるまでずいぶんあほな間違いを犯しました。
数年前にH8Tinyで開発したときにある程度C++をマスターしたつもりでしたがもうすっかり忘れてました。
CもMS-DOSの時代はポインターを使ったプログラムもばりばり書いてたはずですが、やっぱり結構忘れています...
そう、プログラミング言語も慣れが重要です。どっぷりC#に浸かりきってしまい初心者なバグを連発しています。
まず、最初にやらかしたのはinclude文、というかヘッダファイルの書き方。CPPとhの使い分けが全然思い出せませんでした。
変数の宣言の先頭にexternをつけて、headに記載し、どこか一か所のCPPで実体を定義するという、C時代なら当たり前にやっていたところからつまづきました。
あらためて、1か所で定義すればOKなC#のありがたみを感じました。
それから、アクセス修飾子にinternalがない!
これは、C#にはあるモジュールの概念がないからどうしようもないのですが、internal classを作れないと、外からはいじらせたくないけど関連するクラス間のデーター共有のためのローカルクラスが作れない...
まあ、気にせずにグローバルに定義するとか、名前空間をうまく利用すればいいのでしょうが...
それからforeach構文に相当する、for( : )構文。こんなの昔なかったけど、CPP2011から使えるようになったんですね。とてもありがたいです。
でも、なんでこんな構文なんだろう。JavaやC#にあわせて素直にforeachにすればいいと思うんですが、キーワードを極力増やさないためなんでしょうか。
逆にC#にはなくて、便利だと思った機能の筆頭に関数内のstatic変数。
C#だとclass内のprivateフィールドで対応するしかないですが、特定の関数でしか使わない変数をクラス全体で共有しなくちゃならないのは、スコープがでかすぎます。
他にもいろいろ躓いたり頷いたりしてますが、順調にarduino開発にのめりこんでいます。
前述の除湿器のほかにも、検査キット用タイマー(キッチンタイマーみたいなものですが、あらかじめ院内で使う検査キットの時間をプリセットしてある)も作って、フィラリア検査の効率化に寄与しております。