(また番外編)てっぱくに行ってきました
ESP8266でBトレ(第8回 ハードウェア編その8 プリント基板の作成 後編)
番外編からつづきます
お祈りしてから基板に通電したところ無事ALIVEランプが点灯しました。I2CとワンショットマルチまではOKのようです。 数秒後にルーターのランプが点滅しはじめ、パケットが流れ出したことが確認できました。USBシリアルもOKです。WiFi経由でコマンドを送り、シリアルのバス切り替えも動作確認できました。 機能的には今までのおさらいなのでどうということはありませんが、自分でパターンを引いた基板が動作するのを見たらちょっと感激しました。おじさんの歴史の中では、中学校の授業で作ったお風呂ブザーが動いて以来の快挙です。
つづいて動力基板も組み立ててみました。
たくさん見える8ピンのICソケットはモータードライバ用です。下がフィーダー用の6個で、右上はポイントマシン用の4個です。ポイントマシン用はあと2個分、電源ラインのみ配線してあります(右上の4個の下)。ユニバーサル基板状の部分に信号点灯用のIOエクスパンダでも配置しようかなと思ってI2CのラインとALIVE信号を上の基板から引いてきています。
合体っ
追加で取り寄せた長いピンヘッダで2枚の基板を連結します。基板の固定も兼ねるため、主なものは上下左右に振り分けましたが、あとからあちこちに信号線を追加したため、慎重に差し込む必要があります。 動力基板のうえにロジック基板を重ねるようにしました。DCジャックが両方の基板にありますが、ジャンパピンの選択により、ロジック基板側は、動力基板からの給電でも動きます、ただし、12V給電の場合は降圧コンバータを使う必要がありそうです。今回は6V給電の予定なのでシリースレギュレータで降圧しています。
動作テストのようすはこちら
というわけで、ひとまず成功ししました。 ポイントマシンもとりあえず動いてます(なぜ「とりあえず」なのかは後に) 位相同期はまだ調整が必要なので今回は未チェックです。
今回の反省点
自作部品の穴のサイズが小さかった。これはコンポーネントを自作した際に元にした部品のビアが小さかった(標準サイズだった)ためのようです。
部品同士の間隔がぎりぎりだった。これはCADソフトでコンポーネントをデザインするときに、部品が占有する領域を設定しなかったためにチェック漏れしたためでした。
上下の基板を連結するピンが多すぎた、また一か所のピン数が少ないところは、機械的強度が保てない。ピンは機能の基板への割り振り方を工夫すれば減らせるかもしれません。また、総ピン数が同じでも、なるべく少ない個所にまとめ、一か所あたりのピン数を多くなるようにすべきですね。
動力用の電源ラインが細め。最大1Aだと思って線を引いてしまいましたが、1Aのドライバが6個あるので、供給側に余裕があれば最大6Aまで流れることが考えられます。そこまでは考慮しなくてもいいとは思いますがそれにしても電源ラインが細めでした。
今回みつかった問題点と対策
6V単一電源にしたらポイント用の電圧が不足する
Bトレ(カトーの現行の動力ユニット)は6Vで十分な速度が出るため、6V給電で考えていました。12V給電だと低Duty域を主に使うことになるので、位相同期が必要なケースが多くなりますが、位相同期は同時に2ch以上はおこなえないので、使用頻度を上げたくないという理由もあります。また、 ロジック部は3.3Vなので、12Vからの降圧する場合はシリースレギュレータではなくDCコンバータを使いたくなりますがちょっともったいないです。というわけで、6Vレギュレータをつないだところ、なんと、ポイントマシンが動かないじゃないですか!ポイントマシンに12Vが必要なことをすっかり忘れてました。
ゾーンコントローラごとにACアダプタが2個必要というのも気が利かないので、ポイントマシン用の12V電源は昇圧コンバータを使って生成するとにしました(ダイオードの型番が古いのは気にしないでください)。下のような回路を空きスペースに組み込むことにします(なので信号はおあずけです)。
入力電圧は6~12V位の範囲で変わるので、ダイオード(1S1588)で基準電圧を作って、コンデンサの端子電圧と比較してNE555の発振をOn/Off制御しています。コンパレータにヒステリシスを持たせて間欠動作するようにしました。上の回路の定数で動かしてみたところ、約16VでOff、その後時間とともに電圧が低下して約12VでOnになります。電車のコンプレッサーみたいでしょ。
昇圧回路(右)と次の説明のポイントマシンドライバです
ポイント切替はBD6231Fではムリ!(だけど...)
BD6231Fは絶対定格が1Aですが、12V給電でポイントを切り替えるときの電流をオシロで確認したら瞬間的に2A弱流れています(ポイントマシンに直列に0.47オームをいれてその両端の電圧を図りました(下の写真)。1マスが500mVなので約1Aです)。
今回の企みを始めたころ、ブレッドボードにちょこちょこっと組んで動かしてみただけで進めてしまいましたが、ちゃんと確認しないといけませんね。しょうがないので、バラのFETでHブリッジを組んでみました。
容量は余裕ですがサイズ的に収まりません。BD6231F用のDIPソケットにピン互換で一つ作ってみましたが、4ピンソケットなのに7ピン分の長さを使います。また、制御部がないのでFとRをH-Hにしたら電源を短絡します(たぶんボードごと落ちます)。
時間ができたら表面実装の練習を兼ねて、もう少し小さいパーツで基板を作ろうかとも思いますが(そんな時間があったらいっそ全体をCPLD化したいですが)、売り物ではないので当面はBD6231Fに頑張ってもらうことにします。 そろそろソフトに行きたいですね...
ペースが遅いにゃ
ESP8266でBトレ(番外編 プリント基板できました)
昨日プリント基板ができあがってきました、うれしいので写真を載せます。間違ってないといいんですが...
ネコポス×2通で届きました、パッケージをあけたところです。
2種×うらおもて
電源ラインだけ導通を確認したあと、部品を合わせていきます。
あ、穴が小さい...
部品の足をけずって対応します
ここも...
間隔が狭すぎてきちきち...
DIPパッケージのバリを削って押し込みます(プラモデルかい)
#なぜか抵抗が長い、抵抗どうしの間隔も狭い
どこで間違えた?
標準のピンヘッダでは高さがぎりぎり...
ピンヘッダの台座にあて木をして万力などではさめばずらせそうですが、ここはおとなしく長ピンヘッダを注文しました。
さっそく組み立て、通電して臭いをかぎます。
くんくん...
焦げた臭いもしませんでしたのでいったん電源をはずし、ESP8266(ESP-WROOM-02)を取り付けて再度通電します。
つづく...
ESP8266でBトレ(第7回 ハードウェア編その7 プリント基板の作成 前編)
こんにちは、またずいぶん時間がたってしまいました、冬眠してたわけではないんですが...
起きてるにゃ
前回まででとりあえず回路が固まりましたので、今回は量産(といっても数個ですが)のためにプリント基板(PCB)を作ります。おじさんにとって初めての経験ですし、これを書いている時点ではまだ出来上がってきていませんので、ちゃんと動くものができるかどうかわかりません。本当は作図した回路図をもとに一台作って確認しようと思っていたのですが、前回までの試作基板のはんだ付けでめげてしまい回路図を印刷してチェックするだけですませてしまいましたので、その点でも心配です。失敗したら笑ってやってください(とても失敗しそうな気がします...)。
なお、プリント基板作成や発注の方法に関しては、すでにネット上にいい記事がたくさんあり、おじさんもそれらを参考にさせていただきました。ですので、実用的な情報をお探しの場合はそちらをご参照いただきたく、本稿は主に「シロウトのドタバタを追体験して楽しむ」という用途にお使いください。
プリント基板を作る
プリント基板を作るといっても、自分で基板を露光したり、フレキシブルテープとインレタで銅箔にマスキングしたりするわけではなく、CADで図面を描いて発注するだけです。しかもパターンを考えたり描いたりする必要すらなく、回路図さえ用意すればCADが自動的にパターンに変換してくれます(実際には手作業も必要ですが)。趣味のレベルでそんなことができるなんてスゴいと思いますが、画面上だけですんでしまうのは少し味気ない気もしますね。
プリント基板設計ソフト
ホビーユースで利用できるプリント基板用CADソフトは複数ありますが、おじさんはDesignSparkPCBを使うことにしました。この分野ではEAGLEがメジャーなようですが、EAGLEはフリー版は作成できるサイズの制限があったり、作ったものを配る場合は、たとえ実費頒布でも有償版のライセンスが必要だったりするようです。 DesignSparkPCBにはそのような制約はなく、ダウンロードして試したところ、使い勝手も普通のDrawソフトとあまり変わらず違和感なく操作できたため、これを利用させていただくことにしました。
プリント基板作成サービス
国内ではP板.comやUniCraftなどが有名なようですが、時間がかかってもいいので気軽に試したいということで、FusionPCBという海外のサービスを使います。ここはスイッチサイエンス経由でも注文できます。最初は直接頼んで早い便で送ってもらおうとしたのですが、なぜか決済の画面が動かなかったので、スイッチサイエンスさんへ注文しました。今回頼んだものは10cm×10cm×10枚を2種類ですが、FusionPCBでUPSでの発送を選んだ場合とほぼ同額でした。直接頼んでUPSで送ってもらうよりスイッチサイエンスさん経由のほうがやや時間がかかりそうですが、万一の場合に相談できる(かな?)という安心感を考えるとコストパフォーマンスの差は納得できる範囲です。英語が得意な方や、急いでいる方、チャレンジャー(というほどでもないか)な方は、FusionPCBへ直接オーダーしてもいいと思います。(FusionPCBだと、複数種類注文した場合にまとめて発送してもらえるので、送料的にもオトクです。)
作成の手順
(これ以降はDesiginSparkPCBを使ってFusionPCB(スイッチサイエンス)に製造依頼した場合の例を書きます(これしか知らないので))
プリント基板の作成は、 ①回路図を作図する>②デザインルールを設定する>③プリント基板の図面に変換する>④発注する というような流れになります。 最初から回路図をCADでひく人の場合は①はすでにすんでいるはずですが、手描きアナログ人間なおじさんの場合はここから始めます。②は何かというと、基板を受注する側が決めたルール(「こういう設計になってないと製造できませんよ」というルール)です。内容は、例えば、隣り合う配線の最小間隔とか、基板のヘリから配線までの最小幅といったようなものです。配線をCADソフトに考えさせる前にソフトにこのルールを教えてやる必要があります、受注会社のページに載ってます。FusionPCBでは、EAGLE用にはデザインルールの設定ファイルがダウンロードできるのでこれを読み込ませればいいようですが、DesignSparkPCB用はありませんでしたので、ルールを見て設定画面から入力してやる必要があります。また、基板サイズは、所定の範囲内で自由に決められますが、注文枚数によってオトクなサイズがありますので、最初からそれも考慮したほうがよさそうです。FusionPCBでは10cm×10cm×10枚と10cm×15cm×10枚では金額が倍以上違います。③はソフトが自動的にやってくれます。全自動でもできますし、主要な部品や配線の配置だけ手動で決めて、あとはソフトにまかせるとか全部手動でといった使いかたもできます。④はファイルをまとめてアップロードしてオーダーフォームに入力してカードやPaypalで支払いをおこないます。ファイルはレイヤごとに出力されたものをZip圧縮しますが、レイヤごとにファイル名のつけ方にルールがありますのでそれに従います。
気づいた点など
まだ注文しただけで、出来上がりを確認していないので、現時点まででDesignSparkPCBを使ってみて気づいたり感じたりした点を書きます。 (ですので、今後書き足したり修正したりするかもしれません)
チュートリアルをやってみる
まずはとっかかりのために、DesiginSparkPCBのホームページにあるチュートリアルビデオを見てそのとおりやってみました。これだけでおおまかなイメージがつかめるのでおすすめです。また、サイト内に機能の説明がたくさんありますので、探せばたいていのことは載っています。ただし、サイト内では探しにくいのでGoogleからググる(表現がヘン?)必要がありました。
ない部品は探してみる。ちょっと探してなければさっさと作る。
部品ライブラリがついてきますし、オンラインでも検索できますが、それでも使いたい部品が無い場合があります(というか無いことのほうが多いくらい)。 その場合、次のような方法が考えられます。
- DesignSparkPCB用の部品をネットで探す。親切な方が公開されている場合があります。おじさんは74HCのゲートはこちらの方が公開されているものを使わせていただきました。
- EAGLE用があれば、それを変換して使う EAGLEのほうがメジャーなので、それ用の部品ならある場合があります(ESP-WROOM-02もEAGLE用はこちらの方が公開されています)。DesignSpark用への変換はここの説明をどうぞ。
- 自分で作る やってみたら結構簡単でしたので、これがおすすめです↓。
部品の作り方
(DesignSparkPCBのブログにありますので、ここではさらっと)
部品は回路図用の図と、基板用の図にわかれていて、これを組み合わせてコンポーネントとして定義します。基板用の図はよほど特殊な部品(ESP-WROOM-02本体とか)でない限りライブラリにあります。 回路図用の図は自分で描くか回路記号ライブラリからコピーします。基板用の部品も自分で描くか基板用部品図のライブラリからコピーします。同一形状で定数や型番が違う部品を複数種類作る場合は一個作ればOKです。
コンポーネントにする 回路図用の図と基板用の図を組み合わせて定数などを設定したものをコンポーネントといいます。実際に使用するにはコンポーネントにする必要があります。自分でコンポーネントを作るには、まずコンポーネントを新規作成して、それに回路図用と基板用の図を追加します。その後、回路図の端点と基板用部品の端子を関連付て定数を記述します。
回路的には同一で複数の形状がある部品(たとえばロジックICのDIP版とSOP版とか、立てた抵抗と寝かせた抵抗とか)の場合は、一つのコンポーネント内に複数の基板用の形状を定義できます(Edit>Packagesで開いたダイアログでAddします)。配置時には既定値として指定した形状のものが配置されますが、配置した部品のプロパティダイアログから変更できます。
必要なコンポーネントはできるだけ事前に準備しておく
ピンヘッダやDCジャックなどのコネクタ類も含め、使う部品は事前に用意しておくほうが気分よく作業を進められます。また、使いたい部品がいろいろなライブラリに散在していると配置のときに探すのが大変(ライブラリを複数有効にしておくと動作が遅くなる)なので、プロジェクトのライブラリを用意して、そこに使う部品をコピーして集めておくといいと思います。 部品は、Ctrl+Lでライブラリが開きますのでそこで編集すればいいのですが、回路図や基板の設計中にコンポーネントを編集する場合は基板や回路図上で対象部品を右クリックしてコンテキストメニューからEditComponentinLibralyを選びます。
回路図上で離れた配線を同じネットに属させてつながっていることにする機能について
回路図上で離れた位置にある配線に同一ネット名を付けて図上はつながなくてもつながっていることにする機能があり機能ブロックごとに回路図を分けて書くことができるので便利ですが、間違えてつなぐと切り離すのが大変です(間違えてつないでしまった部分のネットを全部消す以外の方法をみつけられませんでした)。また、ネット名を表示させておいかないとつながっていることがわかりませんので、うっかりほかのネットにつないでしまうと困ったことになります。このダイアログが出たときはYesを押す前によくよく注意する必要があります。 どこかにつなげてまったかもというときはView>HilightNet>Browse...で、Net名を選んでハイライトされた配線を探しましょう。 (本当は一つ一つのネットにそのネットの意味をあらわす名前をつけておくのが正しい使い方なのかもしれません。) また、回路の一部をコピペするとコピペ元と先のネットがつながった状態になってしまいます。使い方がわかってないだけのような気もしますが、安全のために繰り返しがある場合なども未配線の部品をコピペするようにしました。
単位や用語について
ググったり、ググって見つけた情報を正しく理解するために、基板界?の用語について知っておいたほうがいいです。mil(thou)、ネット、ルート、ビア、パッド、スルーホール、シルク...くらい覚えておけばよさげかも。
グリッドを切り替える
グリッドにスナップする感じで配線や部品などのオブジェクトは配置されますので、場面ごとにグリッドのStepSizeを調節するといいです。 たとえば部品の配置の時は大きめにしておいて、配線のときは小さめにするとかします。
配線を折り曲げるとき
すでに引いてある配線を折り曲げるときはその配線をダブルクリックしますが、自分が思っている側じゃない線分がマウスカーソルにくっついてくることがあり、離せないのでイラっとします(納豆のパックのビニールみたいです)。分割した線分のうち、それぞれの側のコーナーから遠いほうがマウスにくっついてくるようですので、それを意識してダブルクリックする点を選ぶといいです(折り曲げる点は自由に移動できます)。
主要な配線は手でひくほうがよさげ
自動配置ロジックは配線の意味的なものまでは考慮してくれませんので、そこにこだわる場合は手配線したほうがいいかもしれません。 今回は、練習を兼ねて動力用の基板は全部手配線でやってみました。
ルートの作成、やり直し
ネットをルートに変換する場合は、一つのネットの一部のみをルートにできますが、戻す場合は全部戻ってしまいます。たとえばグランドの一部をやり直したい場合など困ります。こんなときは、変更したいルートを選択して削除してから、回路図と同期(Tools>Foward Design Changes...)させることにより、ルート前の状態に戻せます。 パターンを手でひくとき、引き出したい場所にネットの分岐がない場合があります。そんなときはネットにとらわれずにつなぎたい部分同士をパターンでつないでから、回路図と同期させれば、つないだ部分に対応するネットが消えてつじつまが合います。
部分的に線の太さを変えたい
例えば電源ラインの場合、ロジックピンのプルアップか、電源供給線かによって線の太さを変えたかったりします。自動でやると同じ太さになってしまいますが、事前に線のクラスを定義しておくと、そのクラスに応じた太さになります。それでも分岐位置の都合などで、思い通りにならない場合は、パターン上で線を直接選んで太さを変更することもできます。
回路図との同期
パターンを作っている最中に回路の一部を直したり付け足したりした場合、前述の同期機能を実行することで、それがパターンに反映されます。未配置の部品やネットとして基板の外に現れます。
部品のシルク
部品のシルクは部品外形の定義で描きますが、デザインルール上、シルクの上や近傍にはパッドが置けないので、あまり凝ったシルクにしないほうがよさげです。また部品名と部品番号はひと固まりになっていて個々に動かせないのがちょっと不便です。今回は部品番号だけ自動で配置して、型番は裏面シルクに手動で書きました。
データ出力
FusionPCB用のガーバーやドリルデータの出力はこのページを参考にしました。 出力したファイルを所定の名づけルールに従ってリネームして圧縮したあとfusionPCBのサイトにアップロードすると出来上がりイメージが確認できます。(スイッチサイエンスのアップロードページだと、寸法が正しく解釈されずイメージを確認できません。) 基板サイズはメーカーが決めている価格ごとのサイズぴったりではなく微妙に小さくしておくとよいようです(たぶんそうだろうと思って若干小さめにしたのですが、それでもFusionPCBのサイトにアップしたらワンサイズ大きく評価されたので、さらに削る必要がありました。)
こまめにセーブ
DesignRuleCheckを走らせるときなど、ときどき固まるので、まめにセーブすることが大切です。
どのくらいで慣れたか
平日夜に1~2時間くらいずつ10日~12日ほどと、休日を2日半ほど費やしてようやく手描きの回路図の入力と基板2枚のレイアウトができました。 若い方ならもっと短時間で慣れるでしょう。使い方が少しわかってくるとパズルみたいで結構楽しいです。動作が確認できたらデータもアップします。
動力部とロジック部の2枚に分けたロジック部のほうです。
できた?
まだできてません。先週金曜日の夜に発注と支払いを済ませて火曜日の昼にチェックを開始した旨のメールがスイッチサイエンスさんから届いたところです。来週火曜日以降は春節のお休みなので、このペースだと届くのはちょっと先になりそうです。
1/30(土)追記:
本日昼にスイッチサイエンスさんから、製造を開始したとのメールが届きました。とりあえずデザインルール的にはOKだったようです。
2/2(火)追記:
本日昼に製造完了のメールが来ました、結構早いですね。
2/9(火)追記:
本日夕方にスイッチサイエンスさんから発送完了のメールがありました。クロネコさんからもメールがあって明日到着予定だそうです!
ESP8266でBトレ(第6回 ハードウェア編その6 位相同期 後編)
年末はドタバタしていて、気がついたら年が変わってしまいました、みなさまあけましておめでとうございます。息切れしないようにボチボチ進めていきたいと思いますので今年もよろしくお願いします。
どのフィーダー(チャンネル)で割り込みをかけられるようにするか
前回は一つのPWMについて隣のゾーンコントローラーと同期をさせてみました。 しかし、今作っているゾーンコントローラーは、一個のESP8266でフィーダー(チャンネル)を6個駆動しています。線路配置によらず汎用的に使えるようにするつもりですので、使い方によっては、どのチャンネルも隣が別のゾーンコントローラー配下のフィーダーになる可能性があります。 そのため、どのチャンネルでも同期がかけられるようにしておく必要がありそうです...が、考えてみると、隣のゾーンコントローラーも同じ仕様ですので、同じように同期機能があるはずです。ということは、全6チャンネルのうち3チャンネルだけに同期機能をもたせ、残りの3チャンネルは隣のゾーンコントローラーの同期機能に依存してもいいはずです。そこで3以上でデジタル回路的にきりのいい4チャンネルに同期機能をつけることにしました。
回路はこんな感じです(前編の回路に切り替え機能をつけたものですが、一部に前回載せた回路図の間違いの修正(PWM信号はHC123のBではなくnotAに入れる)と、今回追加部分の配線ミス(コンパレータの+と-のつなぎ間違い)のための変更があります)。
フィーダーからの電圧信号と自身のPWM信号をそれぞれ4チャンネル×2のマルチプレクサHC153で選択し、そこからONLYYOU信号を作るようにしました。チャンネルの選択はMCP23017で未使用のB6~7を使い、Duty-ONの引き延ばしのためのHC123は第1回で作ったALIVE信号で使ったものの残り半分を使いました。その他のゲート用にはHC00を1個追加します。 (あとで気づいたのですが、アナログマルチプレクサにすればコンパレータを1個減らせるかもしれませんね)
センサー部 (前掲の回路図の上半分です、別基板にしました)
IOピンが足りない
当初の目論見では、PWM出力として使えないGPIO16を割込受付用に使おうと思っていたのですが、ESP8266のデータシートをよくよく見たらGPIO16は割込みにも使えないじゃないですか、が~ん。 で、どこかからGPIOを奪ってくる必要が生じました。とは言ってもフィーダー6チャンネルは譲れない線ですし、I2Cも必須です。しかたないので、シリアルから召し上げることにしました(TX,RXはそれぞれGPIO1,3としても使えます)。ただ、基板もソフトもWiFiだけで済ませらるほどの完成度には程遠いので、普段はシリアルピンとして使いつつ、必要なときのみシリアルを止めて割込み用に使うことにします。回路はこんな感じです(同期のための割込み受付用には1本でいいのですが、とりあえず2本とも切り替えるようにしました、GPIO3は現状では未使用です)。
割り込みとシリアルを3ステートバッファ(HC125)経由でGPIOにつないでおき、片方のみイネーブルにします。選択用の信号は、使えない子のGPIO16からとります(使えないのではなくて、別の用途に使うべきピンのようです)。でも、どちらか一方へつなぐ線は途中で反転する必要があるので、インバータが必要です。今までせっかくゲートを残さず食べていたのに、ここに来て1つ足りなくなりました。泣く泣くICを一個追加します。HC04にすると1/6しか使わなくてもったいないお化けが出そうですので、何かほかのことにも使えるかもしれないオールラウンダーのHC00にしておきました。 シリアル/割込みの切り替えは、プログラムからはGPIO16へのdigitalWriteするだけなので、シリアル/割込みのどっちをHIGHに決めてもいいのですが、書き込みモードで起動するとGPIO16がHIGH(ハイインピーダンスではなくHIGH)になるので、このときにシリアル側が有効になるような回路にしておく必要があります。
ボード全景(本格的にごちゃごちゃになってきました)
どうやって動かすのか
この回路を機能させるには、同期のための待機を開始・終了したり、同期するチャンネルを指定する必要があります。これはサーバーから指示するようにします。サーバーは「どの区間を列車が走っていて、次にどの区間に入るか」とか「区間の中のどのあたりを列車が走っているか(→あと何秒くらい後に次の区間に入るか)」といった情報を知っているため、この情報をもとにすればいつどこで同期が必要かがわかるはずだからです。 サーバーとゾーンコントローラーはこんな感じでやり取りさせる予定です。
サーバー:「ゾーンコントローラーさん、フィーダー1で同期待機を開始して」
ゾーンコントローラー:「あいよ~」(シリアル通信を中止して割り込み受付を開始する)
ゾ:フィーダー1で同期開始...あっ列車が進入してきた、同期しよっと
サ:(列車が次の区間への移動が完了したことを確認したのち)「ゾーンコントローラーさん、同期待機を終了して」
ゾ:「あいよ~」(割り込みを解除してシリアル通信を開始する)
動画は無いの?
スミマセン、今回は基板の動作確認以上のソフトを書いていないため、動画はありません。書かなかった理由は、サーバー側もゾーンコントローラー側も動作確認のための行き当たりばったりの書き足しを重ねて汚くなってしまったので、これ以上書き足すのはやめていったん整理しようと思っているためです(じゃないとソフトウェア編でお見せできませんし...)。
前回の修正と今回の失敗など
実質的には前回の回路に入力選択機能を2つ(3つ)追加しただけなのに、ずいぶん間違いや見落としがありました、以下にまとめまておきます。今回まででひととおりの回路はできたのですが、このくらいの仕事の精度だと、回路図をひいていきなり基板を発注するのは無謀なので、回路図をひいたらそれをもとにもう一つ組んでみて、動作を確認してから発注するようにしようと思います。
- HC123のAをプルダウンしBに信号を入れていたがこれは間違いで、notAに信号をいれてBをプルアップするのが正解でした。 前回載せた回路図が間違っていて、それをもとにしたためです。ダウンエッジを引き延ばすのが目的なので、notAに信号をいれなくてはなりません。もとの回路図が間違っていたのは、ブレッドボード上の配線を直した際に回路図を直し忘れたためです。
- HC153のY1とY2を逆につないでいた。 寝ぼけていてつなぎ間違いをしたようです。
- コンパレーターの+と-をつなぎ間違えたのでFEEDER信号が負論理になってしまった。 これまた寝ぼけていて間違えました。4回路×2か所も直すのはウンザリですし、作り直すにしても正月でパーツ屋さんもきっとお休みなので、余っていたゲートで信号をひっくり返してお茶を濁しました。
- GPIO16は書き込みモード時にHIGHになることを考慮していなかった。 てっきりハイインピーダンスになるものと思い込んで、プルダウンで回路を組んだら書き込みができませんでした。思い込みはいけませんね。
最後の一つはテスターで見つけましたが、他はオシロのおかげで発見できました。私が使っているのは中国製の激安機ですが、機能的には全く不満はなく、これが有るのと無いのとでは、ソフトでいうと紙上デバッグとステップ実行くらいの差があります。最後まで読んでくださった方の中に、よい子の皆さんがいらっしゃったら、お年玉でオシロを買ったらいいと思います。
ESP8266でBトレ(第5回 ハードウェア編その5 位相同期 前編)
先週オシロが届いたので、ウレシくてガチャガチャいじくってました。夜おそくにコードがもじゃもじゃの怪しげな基板を前に、不気味な笑いを浮かべながらオシロのプローブを突き立てようとしていると、ちょっとマッドサイエンティストになった気分です。
これがそのオシロ DS5032E 中国製です。おじさんオシロは初めて使いましたが、すごく便利です。中国にはこんなにいいものがあるというのに、わざわざ日本まで爆買いにくる理由がまったくワカリマセン。
位相同期に挑戦してみる
さて、前回、位相が同期していないとどうなるかと、位相を同期しないで問題を解決する方法について説明しましたので、流れとして今回は位相同期する話ですよね、え~、どうしよう、できるかな? いきおいで手をつけてしまったので、いけるところまで行ってみます(これができないとゾーンコントローラー方式が実現できませんし...)。おじさんは普段はお金やモノを数えるソフトを書いてます(ました)が、ハードやマイコンソフトはアマチュア(というよりシロウト)ですので、ツッコミどころにはよろしくつっこんで下さい。
位相同期に必要なこと
位相同期(隣のセクションのPWMと位相を合わせる)には次の事柄をクリアすることが必要です。
- 自分のPWMの位相を意図したように変更できること
- 隣のセクションのPWMの位相がわかること
調べてみたら1つ目はわりと簡単でした。SDKのPWM用のカウンタをリスタートさせる関数がArduinoからも使えますので、これを好きなタイミング(割り込みとか)で呼び出してやれば実現できます。 PWMの波形のパターンにはいろいろあるようですが、analogWrite関数の場合はカウント開始時に出力がHIGHから始まり、アップダウンカウンタではないようです。
ググって調べました
(ソース追えないので波形で見ました)
2つ目はちょっとくふうが必要です。というのは、隣のセクションの波形そのものを知ることができないからです。しかし、列車が隣のセクションと自分のセクションにまたがっている間に自分のフィーダーにかかる電圧(波形)は、自分のフィーダーと隣のフィーダーの波形の論理和になるはずです。これに、次の2つの前提条件 (1)隣のセクションと自分のセクションのPWM周波数は(ほぼ)同じであること、(2)隣のセクションと自分のセクションのDutyは同一であること、を考慮すれば、となりのセクションの位相はわかるはずです(下図をご覧ください)。
やりかた
1つめは、コードの適切な部分で以下を呼び出すかコピペするだけです(core_esp8266_wiring_pwm.c)
void pwm_start_timer(){ timer1_disable(); timer1_attachInterrupt(pwm_timer_isr); timer1_enable(TIM_DIV1, TIM_EDGE, TIM_SINGLE); timer1_write(1); }
2つめは、フィーダー線から引っ張り出した線に検出回路をつないで、検出回路の出力でESP8266に割り込みをかけてやることで実現します。回路とソフトそれぞれについて説明しますが、説明が長くなるのを避けるため、隣のセクションのことを「あなた」自分のセクションのことを「わたし」と書きます。
回路の説明
回路では「あなただけがON」になっている期間を検出するようにします。まず、フィーダー線から取り出した信号(あなたと私の合成波形)をダイオードブリッジで極性を揃え、コンパレーターでロジックレベルにします(図中のFEEDER)。 次に、そこから「わたし」を取り除くための信号を作ります。これにはESP8266からのPWM出力を使います。ESP8266のPWMとBD6231Fの出力のタイミングを見ると、立ち上がりで10~20us、立下りで100usほどずれがあります。 そこで、立ち上がりはそのまま利用しつつ、立ち下り用を100usほど引き延ばした信号を作ってORをとればよさそうです。引き延ばしにはワンショットマルチHC123を使いました。これとPWM信号のORを取りますが、そのままだと、もともとの信号と引き延ばした信号とのつなぎ目でスパイクがでるため、もともとの信号のほうはCR回路で少し遅延させています。これを反転させて使用します(図中のPWMEXTENDED)。 これら二つの信号のANDをとれば、あなただけが電圧を出している期間にのみONになる信号ができます(図中のONLYYOU)
ソフトの説明
この部分の今回試したコードを載せます。上記で生成したONLYYOU信号と、わたしのPWM信号とを入力情報として、わたしのPWM信号をあなたのPWM信号の位相にあわせています。試行錯誤しながら書いたのであかぬけてませんがお許しください(スマートなロジックがあれば教えてください)。 実験では割り込み用にGPIO13、自分のPWM信号を取得するためのAnalog出力としてGPIO14を使いましたのでそのような記述になっていますが、本番ではGPIO13はフィーダー用に使っていますのでそのままでは使えません、また、Analog出力もいつも同じ端子ではなく、同期の都度、対象のポートに切り替える必要がありますのでその機構が必要です。さらに、どこかに問題があるらしく、たいてい10分くらいでこけます。このへんは次回以降なんとかします(するつもりです)。
//setup()の中 attachInterrupt(13, sync, CHANGE);//割り込みを設定する volatile long up = 0;//割り込み発生回数の調査用 volatile long dn = 0;//〃 volatile short adj = 0;//タイミング調整用(実行中に変化させながら様子を見たところ、120くらいがちょうどよいようです) bool resetWithFALLING = false; //割り込み処理(位相同期) void sync() { if (rest > 0) {//ちょっと間引き rest--; return; } detachInterrupt(13);//再入を防ぐため割り込みをやめる Feeder *f = Feeders->get(0); short duty = f->getAnalogValue(); int isRAISING = digitalRead(13) == 1; if (isRAISING) { up++; if (digitalRead(14) == HIGH) {//me delay resetWithFALLING = true; } else { timer1_disable(); delayMicroseconds(1000 - duty - adj); timer1_write(1); timer1_enable(TIM_DIV1, TIM_EDGE, TIM_SINGLE); rest = 5; } } else {//FALLING dn++; if (resetWithFALLING) { timer1_disable(); timer1_write(1); timer1_enable(TIM_DIV1, TIM_EDGE, TIM_SINGLE); resetWithFALLING = false; } } attachInterrupt(13, sync, CHANGE);//割り込みを許可する } volatile short rest = 0; //loop()かonTimer()の中 rest = 0;//割り込み間引き用カウンタをクリアする
で、動くの?
ビデオはこちらです。
一応、位相同期の効果は確認いただけると思います。これで落ちなくなれば(^^;;)、ゾーンコントローラー方式も実用化できそうです。 波形も載せておきます。
はまったところ
最初、2台の基板で同じ電源をつかっていたのですが、どれだけ位相を合わせても、境界通過時にDutyが変化してしまいました。もしやと思って別々の電源からの供給にしたところ、Dutyの変化が抑えられました。モータードライバ側から見た回路の条件が違うのでしょうか?
後編の予告
ゾーンコントローラのPWM出力は6つあるので、今回確認した回路をどう組み込むか考える必要があります。また、同期が必要なPWM出力の番号と、同期開始、終了のタイミングはサーバーから指示してやる必要がありますので、そのあたりも検討しようと思います。春節前に送ってもらえるように回路の設計を終わりたいと思ってましたが、今のペースだとちょっと無理カモ...
ESP-8266でBトレ(第4回 ハードウェア編その4 位相同期...の前ふり)
このブログを、なんと make: さんに紹介していただきました。ビックリ
make:さんの評判を下げないためにもちゃんと書かねば...
異なるマイコン個体間の位相差
ESP8266では、PWM用のタイマが一つ(※)なので、6セクション分出力しても位相はすべて一致しています。ですので、同一のESP8266配下のセクションの間を列車が渡るときはスムースに通過できます。しかし、おじさんが目的にしている「鉄道運行の模型化」のためには、列車は異なるESP8266配下のセクションを渡っていかなければなりません。 (※ Arduino環境です。ハードウェア的な制約かどうかは調べていません)
異なるマイコンは、それぞれが持っているカウンタからPWM信号を作っていますので、それらの位相は一致していません。また、それぞれ異なる発振器が作る「微妙に異なるクロック」で動いていますので、仮に、ある時点で位相を合わせることができたとしても、やがてずれてしまいます。もし、2つのESP8266のクロックが月差15秒(ありがちなクォーツ時計の精度です)だったとすると、約3分で1msずれます。ESP8266のPWMの周波数は(デフォルトで)1kHzですので、このケースだと約3分で1サイクルずれる計算です。
位相差があると何が問題なのか
となりあうセクションを車両が通り過ぎるとき、一時的に両方のセクションから給電されることになります。給電方式が純直流で、両方からの給電電圧が同じならば、問題は生じません。
しかしPWM制御の場合は、高い電圧の期間と0Vの期間を短い周期で繰り返し、その比率(Duty)を変えることにより、実効(平均)電圧を調節しています。
このような仕組みですので、両方のPWMの位相が一致していれば問題ありませんが、ずれている場合は、そのずれ具合によって実効電圧が変わります。例えばONの電圧が10VでDutyが30%の場合、車両がうける実効電圧は3V~6Vになります。何Vになるかは、そのときどきの位相のずれ具合によって異なります。
本当かどうか見てみます?
オシロぽちってしまいました...
この状態で車両の走り方をみてみるとこう
位相差をなくすにはどうすればよいか
これではちょっと困るので、どうにかして位相差をなくす必要があります。位相を同期させないで解決するのであれば、たとえば次のような方法が考えらます。。
次のセクションに入った瞬間に、前のセクションからの給電を止める。
セクションとセクションの間に、どちらからでも給電を受けられるセクション(中間セクション)を設け、列車が中間セクションに完全に入っているうちに給電元を切り替える。
出力に平滑回路をはさんで純直流(に近い波形)にしてしまう。
それぞれ課題や制限事項があります。1は編成あたり1動力車の列車でないと適用できません。2は中間セクションへの給電を切り替えるための仕組みが必要になります。3は...せっかくのPWMなのに、ちょっともったいないですね。 また、1 2とも、制御対象のセクションが、隣のセクションの情報を得ることが必要になります。WiFi経由で送ってもらうとすると、状況によっては100ms程度かかります。ちょっと遅すぎですので、自力でとなりセクションの情報を得る必要があります。
つづきはオシロの使い方を覚えてから...