デジタルビデオカメラでタイマー録画(ソフトウェア編)

はじめに

前回までに「構想編」「ハードウェア編」とお届けしてきました本企画も今回の「ソフトウェア編」が再終回です。ただ、私自身ソフトウェアについてはあまり詳しくないので少々気恥ずかしいですし、とんちんかんなことを書くかもしれませんが、その辺は太く鷹揚にご容赦願います。


PICについて

PICに関してはいろんな参考書やあちこちのWebページで取り上げられていますのでいまさら私などがここで述べるまでも無いと思います。ですが、今のところはPICの中でも16F84のタイプがポピュラーで大抵の資料はこのシリーズに関するものが多いですので、ここではあまりポピュラーでないため資料の少ない12C509に関して簡単に触れておこうと思います。

12C509Aは12bitコアのRISCマイコンで、CPUコアからメモリからすべてワンチップの中に内蔵しているワンチップマイコンです。プログラム用メモリに対するアドレス/データバスとRAM用のアドレス/バスとは互いに独立した「ハーバードアーキテクチャ」を採用しています。このため、命令とデータを同時に読み込んで同時に処理をすることが出来、さらにはパイプライン処理も行うため、コンパクトな割には高速な動作が可能になっています。
プログラムメモリとRAMはそれぞれ1,024ワードと41ワード分だけ持っており、最大動作クロック周波数は4MHzになっています。

クロック発振器については外付け発振器やクリスタル、セラロック等を利用することもできますが、内部にも簡単なRC発振器を持っていて外付け部品無しで動作することも可能です。実際、今回用意した外付け部品はダイオードが1点とノイズ取り用のコンデンサが1点だけ、というシンプルさでした。

12C509Aの場合、シンプル、コンパクトかつ安価なので、今回のような本当にちょっとした処理にはうってつけなのですが、私のような初心者にとってはネックな点がひとつあります。それは、プログラムメモリが書きこみがCD-RやDVD-Rと同様に1回切りのワンタイムROMなところです。ちょっとプログラムを間違えるとそれっきりでその部品はおしゃか。ごみになってしまうところです。
実際、今回の場合もソースプログラムには有る程度「お手本」があったので「そう間違えることはないだろう」と高をくくっていたのですが、案の定失敗して3つダメにしてしまいました。

さて、どうしようと困っていた矢先、うまいタイミングで12C509Aとピンコンパチブルでより高機能な12F629、12F675といったフラッシュメモリタイプのPICが登場してきました。

これらは、20MHz14ビットコアでコンパレータ入力があったりA/Dコンバータ入力に対応していたり、EEPROMが内蔵されていたりとかなり高機能になっていますので、これからPICをはじめられる方は最初からこれらのフラッシュタイプ(CD-RW同様、消去して書き換え可能なタイプ)ではじめられた方が良いのではないか、と思います。

PIC12C509A(左)と12F629(右)

ただし、12C509Aにまして世間に資料が出回っておらず、一部の命令、レジスタ構成や初期設定のやり方なども12C509Aとは多少異なるところがありますのでソースコードはそれなりに手直ししなければなりませn。その点はご注意ください。例えば、今回私が実験したときもメーカが用意したインクルードファイルなどを見つけることができず、自分で用意しなければなりませんでした。


開発環境

なんていうと大袈裟ですが、今回私がPICのプログラム開発と書きこみに利用したツールを紹介します。

まずソースコードについては、普通のテキストエディタで入力しただけで、特別なものは使っておりません。

言語についてはC言語やBASICなども用意されているようですが、私は素直にアセンブリ言語を利用しました。

アセンブラはPICの開発元のMICROCHIP社が無償で公開している「MPASM」を使いました。同社のホームページに行けば誰でもダウンロードできます。当然ながら英語のソフトなのですが、日本法人のホームページにいくと簡単な使い方や、同社がおこなったセミナーのテキストなどもみられますのでそれほど困ることはないと思います。

アセンブラだけでなくシミュレータなどの機能もついていますので、実際に書き込む前にPCの画面上でシミュレーション、デバッグが可能です。
流れとしては、エディタで.ASMのソースファイルを作り、MPASMでコンパイルして、できあがった.HEXファイルをプログラマを利用してPICのチップに書き込む、という順序になります。

秋月電子通商のPICライター

プログラマについては、以前自作したものもあったのですが、

  • 不精なので使い方のマニュアルというか「こつ」をすっかり忘れてしまったという点
  • ほとんど16F84専用で12C509Aや12F629などには対応していない点
  • 今後もPICを使った工作をいろいろやりたいという点


などから、今回は秋月から出ているPICプログラマキットを買ってきて作りました。(写真 上)

確か\6,700くらいした上、途中でバージョンが3から4に上がったためそのバージョンアップキットが\1,700くらいして、結構お金がかかってしまいました。頑張って元を取らねば!


プログラムの構成

恥ずかしながら、こちら (12C509A用 12F629用) がソースコードになります。リンク先はWeb掲載の関係で拡張子を.txt としてありますが、.asm とリネームしてアセンブラにかければHEXファイルが出来あがります。

(もっとも、アセンブルにあたってインクルードファイルが別途必要ですが、権利の関係でここには掲載しませんので悪しからず。)

リストのほうにもコメントが入れてありますが、簡単に説明したいと思います。

まず、冒頭部分は使用するプロセッサに関する宣言とコンフィギュレーションに関する設定です。"R=DEC"という部分は、特に指定の無い数字は10進数ですよ、という宣言です。これをしておかないと、例えばただ"10"と入力するとこの数字は16進数の"10"すなわち10進数でいうと16ということになってしまいます。(まず私はここで失敗しました)

続いて、入出力端子のうち使用するGP0、GP1、GP2に対して名前を定義しています。これは、「GP2ポートに対してHighを出力する」と記述するよりは「LancOut端子にHighを出力する」と、した方がソースを他人がみたり自分が後から見たりするときに判りやすいためですね。

端子の定義の後は、定数の定義です。これについても上と同様、LANC OUTに出力するコマンドコードやLANC INから読み込むステータスコードを理解しやすい名前に直しています。

ここまでが、定数の定義です。定数については一度決めたら変わることはありません。
これに続いている”cnt1”の部分は変数になります。もっと具体的に言えば、「レジスタ」として使用するRAMのアドレスの設定になります。つまり例えば"cnt1"という変数は16進数で”10”のアドレスのRAMを指しますが、そのRAMの中に入っているデータの内容は時には4だったり、時には8だったり、はたまた255だったりと常に変化しています。

これら変数のうち、cnt1からcnt4は主に繰り返し回数をカウントするためのカウンタとして利用されていますが、これに対してその後の部分のtx0,tx1・・・rx7と続いている部分はLANC端子を行き来するメッセージを一時的に保存するバッファの役割をしています。たとえば、tx0からtx3の4バイトにLANC
のコマンドコードを代入して置いてから"LANC"サブルーチンを呼び出すと、LANCの信号線にコマンドを送出した後にrx4からrx7までの4バイトに相手機器から受信したステータスコードを受け取って戻ってくる、という具合になっています。
(もっとも今回のプログラムで利用しているのは実際にはtx0、tx1、rx4の3バイトのみですが。)

具体的には、tx0に'18'(今から動作命令を送るぞ、というコマンドメッセージ)、tx1に'3A'(録画スタートをしなさい、というサブコマンドメッセージ)をストアしてLANCサブルーチンを呼び出すと、メッセージを受け取ったスレーブ機器側は、その機器の状態を表すステータスコードがrx4に保存されてリターンします。例えば当初待機状態の場合はステータスコードは   であるのが、録画開始コマンドを受信して録画状態になると'04'というステータスコードが返ってくるようになります。

さて、変数の定義が終わりますといよいよ本体のプログラムですが、なぜか、前半はサブルーチンのプログラムばかりが並んでありプログラム本体となるメインの部分はほんの数行しかありません。

まず現れるのが初期化のサブルーチンです。いくら今回の回路がLANCコマンドを送ろうとも、相手側の制御される側の機器の電源が切れていたり肝心のLANCケーブルが抜けていたりしていては話になりません。しかたがいまして、ここのサブルーチンがやっていることは要は「相手が起きているか」どうかを確認するという作業です。
具体的には、LANC通信をおこなった後にrx4のアドレスに'00'以外の何らかのステータスコードが受信できているかどうかを調べることです。何かの理由で'00'のステータスしか帰ってこないと、サブルーチン内で延々とループしてしまいます。

続いて現れるのは、録画開始コマンド送出&録画モード移行確認のサブルーチンです。ご覧になるとお判りになる通り、やっていることはtx0、tx1に録画開始のLANCコマンドを代入しておいてLANCサブルーチンを呼び出してコマンド送出した後、実際にrx4のステータスを確認して本当に録画状態にはいったかどうかを確認します。録画状態になっていない場合は、再度コマンド送出からリトライを行います。

その次の部分は上と同様停止コマンド送出&停止状態移行確認のサブルーチンです。ここは、コマンドとステータスのコードが異なるだけで、やっていることは上と同じです。

次のサブルーチンは一定時間だけ待つだけのサブルーチンです。内蔵タイマーと割り込みを使っても良いのですが、これはLANC接続する相手機や周辺回路の動作が安定するまでの間のディレイをもたせているだけですので、ここはシンプルにカウンタの減算ループを3重回しして約2秒のディレイを作りだしています。

サブルーチンの最後が、一番メインであるLANC送受信のためのサブルーチンです。

おおまかに、前半がtx0からtx3までの4バイト分の送信データの書きこみ、後半がrx4からrx7までの受信データの読み込み、となっています。

まずはじめにやっていることは、8バイト1セットのLANC通信データ(ここでは仮にパケットということにしておきます)の先頭部分を見つけ出すことです。まず思いだしていただきたい点は、LANC通信はスレーブ側が通信のタイミングを決定していて、スタートビットはスレーブ機器の方が出力するということです。正しくパケットの先頭を見つけないと、折角送信したコマンドが全然別の意味に伝わったり、スレーブ側の出力するステータスデータとマスター側の出力するコマンドとが同じ信号線の上で衝突する、ということも発生してしまいます。したがって、先頭を見つけることは非常に大切です。

ではどうやって先頭を検出しているかというと、通常パケット内のあるバイトのスタートビットから次のバイトのスタートビットまでの間隔というのはせいぜい12,3ビット分しかないのに対して、あるパケットの最後のバイトのスタートビットから次のパケットの最初のバイトのスタートビットまでの間隔は少なくとも14ビット以上ある、ということを利用しています。つまり、ふたつのスタートビットの間隔が14ビット分以上開いている部分を監視して、そこをみつけるとLANCにコマンド送信を開始します。

書きこみ/読みこみにあたっては、INDFレジスタを利用した間接アドレッシング方式でデータを指定しています。具体的にはtx0、tx1、・・・rx7の順に参照レジスタファイルをインクリメントして、それぞれの内容をビットシフトしつつLANC端子にシリアルデータとして書きこんだり読み込んだりしています。

なお、後半の読み込み部分は基本的には書きこみと同様ですが、異なっている部分は冒頭の部分でわざと半ビット分だけタイミングを遅らせている点です。これは、こうしないとスレーブ側がデータを書き換えているエッジの前後の、データが変化途上で確定していない部分を読み込んでしまって意図した通りのデータが読み出せなくなってしまうのを防ぐための処理です。

さて、サブルーチンが一通り終わると、あとはポートやレジスタ等の初期設定の部分があらわれて、最後にメインのプログラムになります。
メインといっても全然大したこと無くて、ただループしながらサブルーチンを呼び出しているだけ。具体的には映像信号の同期検出回路からの出力を監視しているGP1ポートが'L'だったらLANCに対して録画開始コマンドを、GP1ポートが'H'だったらLANCに対して停止コマンドをそれぞれ送る、という内容です。それぞれ2回繰り返しているのは検出信号のチャタリングやノイズによる誤動作を低減する目的です。

以上が本プログラムが行っている動作の概要です。


最後に

今回はちょっと文字ばかりになってしまい読みづらくて申し訳ありません。最後に完成したアダプタの写真を紹介します。実は半田付けよりもこういうケース加工が一番面倒、という話もあります。

完成したアダプタ

使用している様子

いちおう、自分で作ったものなので理屈は良くわかっているのですが、実際に接続したビデオデッキの電源をONにすると自動的にデジタルビデオカメラが録画を開始する様子を実際に目にすると感動モノです!

なお、PICマイコンにはまだ3つほど入力ポートが空いていますので、例えばプログラムを手直ししてもらって入力ポートを録画スタートボタン、ズームテレボタン、ズームワイドボタン、フォトボタンなどのスイッチに割り当てることで自作リモコンを作ることも比較的簡単にできると思います。興味のある方、ぜひチャレンジしてみてはいかがでしょうか?

では、長くなりましたが、3回にわたってお届けしてきた本シリーズもこれにて終了させていただきます。

久々にパワーをかけたコンテンツでしたので、ご感想など戴ければ大変嬉しいです。次回の更新まではまた新たなアイデアを練るための充電期間としてしばらくお時間を戴くかもしれませんが、よろしくお願いします。

趣味の工作の部屋 に戻る