3ch スイッチ(フタバ CPS-1 的なモノ)

前回、「PIC の I/O から出力できる電流は 25mA 程度だよ。」と書いた。ってことは最初に作った 3ch (AUX) スイッチは最大で 25mA 程度の機器しか接続できないということになる。25mA って LED 1個。これではちょっと寂しい。トランジスタのスイッチ使ってもう少し電流流せるように改良した回路と、ついでにバージョンアップしたソースコードを公開しておく。

まず最初に、使用部品は以下。

・ユニバーサル基盤         100円  小さいので十分
・8pin IC ソケット         100円  2個入り
・1/4W カーボン抵抗 5.1KΩ  50円  10個入り
・トランジスタ 2SC1815 Y    80円  4個入り
・積セラ コンデンサ 0.1uF  130円  5個入り
・PIC12F629                120円  1個
-------------------------------------------------
                      合計 580円

※価格は福岡の某電子パーツ屋さん価格

当初、これを作ろうと思ったときに目指したのはフタバの CPS-1 という製品。買うと確か 3000円くらい。しかし、自分で作ればコレ相当なモノがわずか 580円!(工具やらハンダやらケーブルやらは余りが家にあるの前提。)大人のホビーを目指すなら是非自作してみて欲しい。

ただし、完全に CPS-1 互換というワケではない。トランジスタに 2SC1815 を選んでいるので、流せる電流は最大 150mA となっている。CPS-1 は 200mA とかなってた気がしたのでちょっと少ない。

ちなみに、2SC1815 は増幅度 120~240 の Y を選択。ベース電流を約 1mA にしているので、増幅度が最低の 120 だったとしたら 1mA x 120 = 120mA となり、その程度の電流で抑えておくのが良いんだろうと思われる。LED だったら 20mA x 6 個。足りないなら別のトランジスタ使うといい。

参考までに 2SC1815 のベース電流 1mA というのは... 6V(受信機電圧) - 0.6(ベースエミッタ抵抗分) / 5.1kΩ = 約 1mA となっている。PIC の最大電圧は 5.5V だけど 受信機からの 6V そのまま入れてるってのは前回の回路図と同じ。ってことで回路図は以下。

Sw_a

渡り線使えばもう少し基盤を小さくできるが、作りやすさを重視した。これでも 15m x 25m くらいと十分小さいと思われる。

受信機からのパルス信号を GP3 で受け、Hi/Lo を確認して GP2 をオンオフしている。GP2 はトランジスタのベースに繋がっているので... GP2 がオンじゃないとトランジスタの先に繋げる機器に電気が流れない。0.1uFの積セラコンデンサが PIC12F629 の VDD と VSS に接続されているが... IC に対して 0.1uF の積セラを接続するというのは定石らしい。誤動作防止のおまじないになるとかなんとか。

そしてこの基盤に乗せる PIC12F629 用のプログラムソースは以下。対応する MPLAB IDE 8.60 以上、HI-TECH C は 9.81 をターゲットとしている。

「sw_a.zip」をダウンロード

そう言えば前回のソースも HI-TECH C 9.81 用なので、未満のバージョンを使っているとコンパルエラーになる。HI-TECH C は 9.80 と 9.81 で PIC の各種レジスタ用の定数名が変更になっているのよね。なぜ 0.01 程度のマイナーバージョンアップでこれだけ大がかりな変更をしたのかは謎だけれども... 過去の資産なんてない身分の人は素直に 9.81 用の定数名を使っておいた方がいいと思われる。

さらにいうと、このソースはアナログ付きの PIC12F675 がターゲットでもそのままコンパイルできるようになっている。PIC12F675 を使う場合は I/O のアナログをオフにする(デジタルにする)必要があるので、#ifdef _12F675 で ANSEL = 0x00; が実行されるようにしている。PIC12F675 が余ってる人もそのまま使って欲しい。

この回路は I/O 6ピン の PIC の 2ピン しか使っていない簡単な回路。プログラムも簡単だし C 言語だからアセンブラより理解しやすい(と、思う)。ラジコンユーザーのマイコン・電子工作入門としては最適なんじゃないかと思ったり思わなかったりする。

そして、前回のソースコード分の回路図はまた今度。

| | コメント (1) | トラックバック (0)

AUXスイッチとブレーキランプ ~ ソースコード編

PIC12F629 に手を出したという前回の日記から若干時間がった。その間、PIC12F629 で色々遊んでみたが... 基本的にあまり複雑なことをしようと考えないで、電飾制御用の単純なコードを処理するマイコンとして使うことにした。

まず、複雑なことをしようとすると電子的な知識の無さから回路を考えるのに苦労する。そして、実際の電子回路を伴うデバッグはとても面倒。それでもまだ 8pin の PIC12F629 だから何とかなる。だがしかし...

もう少し複雑なことをしたい。

だが PIC12F629 だとピンが足りない。

ピンが多い PIC に手を出す。

こうなると何かにはまる。PIC16F88 とか、ピンが多くて値段も手頃な PIC は福岡でも手に入る。でもこれらには手を出さないことにした。だって、この辺に手を出すとラジコンする時間が無くなるんだもん...

ってことで、前回は F104 のリアの自動点滅するLEDを3ch目(AUX)でオンオフするコードと回路を作った(AUX スイッチ)。今回は TB03、ツーリングカー用の電飾を作る。(ST/AUX スイッチ)仕様は以下。

(1)ヘッドランプ 2灯 x 2(左右) = 4灯
(2)テールランプ 1灯 x 2(左右) = 2灯
(3)ブレーキランプ 1灯 x 2(左右) = 2灯
(4)合計 8灯
(5)ヘッドランプ、テールランプは 3ch目(AUX)でオンオフできる
(6)ブレーキランプはスロットル(ST)が Lo のときに点灯する

合計 8個の LED をさせるので、AUX スイッチより回路は複雑になる。そして、電流のことも考えないといけない。PIC12F629 の I/O ピンで出力可能な電流は 25mA 程度らしい。正直、F104 用の AUX スイッチを作ったときはこの辺をまったく考慮していなかった。素人って怖い。でも、自動点滅型の赤色 LED 1個だから... 20mA 程度かな。足りたんだと思う。

AUX スイッチは F104 以外でも使う予定だし、その場合用の回路も考えておくことにしよう。兎に角、LED たくさん使う場合は PIC12F629 の I/O からの出力にそのままつないではダメで、この場合は「トランジスタ」を使ってあげる必要があるらしい。「トランジスタ」とかなんか本格的な電子工作っぽい。

さて、トランジスタ使った実際の回路の話はまた次回。今回はプログラムのソースコードのお話。

前回の AUX スイッチで成功したコードを元に、改良を加えていこう。

AUX スイッチでは GP3 で受信機の AUX パルス信号を受信し Hi/Lo を判定していた。今回の ST/AUX スイッチでは、その名の通り、ST、ステアリングのパルス信号も見る必要がある。GP3 ここは GP3 の隣、GP4 を使う。そして、GP3 用と GP4 用の wait_lo/wait_hi 関数を作成した。

void wait_lo3()
{
    while (1) {
        if (!GPIO3) {
            __delay_us(100);
            if (!GPIO3) break;
        }
    }
}

void wait_lo4()
{
    while (1) {
        if (!GPIO4) {
            __delay_us(100);
            if (!GPIO4) break;
        }
    }
}

void wait_hi3()
{
    while (1) {
        if (GPIO3) break;
    }
}

void wait_hi4()
{
    while (1) {
        if (GPIO4) break;
    }
}

wait_lo 関数で 100us 以上の Lo を待ち、それがあったら今度は wait_hi 関数で Hi(パルスの立ち上がり)を待つ。そして、Hi の間隔を見て、出力ピンの出力をオンオフさせてあげる。AUX を処理したら ST を処理して、それが終わったら AUX を... このように交互に処理させてあげることにする。最適化がない HI-TECH C の Lite Mode だと同じループ内でふたつの処理をさせない方が楽と思う。

unsigned char aux;

~略~

while (1) {
    if (aux) {
        // aux 処理
        ~略~
    } else {
        // st 処理
        ~略~
    }
    
    // aux 変数を反転させる
    aux = aux ^ 1;
}

こんな感じ。これはこれで動く。最初はこれで動かしてた。でも、これだと AUX と ST と、両方のパルス信号を確実に入力してる場合にしか動作しない。気分的にブレーキランプはいらないな... と思って ST 側のコネクタを外すと... 繋がってない ST 側の Li をずっと待ってしまう。このコードだとループの最初が AUX 側の処理なので、受信機の電源をオンにしたときに送信機の AUX が Hi の状態だとヘッドランプとテールランプが点灯した状態で ST の無限ループに入ってしまう。

まあ、これは「仕様です。」としてもいい内容かも知れない。が、何となく気になるので wait_ 関数を以下のように変更する。

#define LO_TIMEOUT  200
#define HI_TIMEOUT  200

unsigned char wait_lo3(void)
{
    unsigned int i = 0;
    while (1) {
        if (!GP3) {
            __delay_us(100);
            if (!GP3) return 1;
            return 0;
        }
        i++;
        if (i >= LO_TIMEOUT) break;
    }
    return 0;
}

unsigned char wait_hi3(void)
{
    unsigned int i = 0;
    while (1) {
        if (GP3) return 1;
        i++;
        if (i >= HI_TIMEOUT) break;
    }
    return 0;
}

// ※GP4用も同じく作る

まあ、ループにタイムアウトを設けてやればいいのよね。定数で定義しているタイムアウトの数字は PIC のクロックに応じて変更してあげた方がいい。例えば PIC12F683 の 8MHz を使うなら倍とか。4MHz で大体 2~3ms くらいでタイムアウトする。それくらいの速度で AUX と ST の監視を切り替えるようにした。MPLAB のプロジェクト付きソースコードは以下。

「sw_ta.zip」をダウンロード

このコード、とりあえず動く。コメントたくさん書いてるので見ればなんとなく理解できると思われる。ちなみに、このプログラムを使った基盤は既に作成済みでTB-03 用に新しく作った HSV-010(GT-500) のボディに搭載されている。3ch 目でヘッドライトオンオフできる市販パーツってあまりないので、個人的にかなり満足している。(このボディはホンダなのにフェラーリカラーという謎仕様になっているので今度写真アップする。)

...次回に続く。

| | コメント (0) | トラックバック (0)

4MHz なめんな?

マイコンに手を出して C 言語でプログラミングしているワケだけれども... 4MHz というクロック周波数を正直なめてました。マイクロ秒(us)単位で処理を判定するプログラムを書こうと思ったらコンパイラが吐き出すバイナリを意識しないとダメね。

有償のコンパイラを使ったらまたちょっと違うのかも知れないが、HI-TECH C を Lite(無償) モードだとちょっとでも冗長なコード書いたら数十サイクルくらい楽に消費される。

4MHz の PIC の 1 サイクルは 1us らしい。数十サイクル = 数十 us なんだけどこれがループで積み上がるとミリ秒(ms)単位でズレがでる。2200us(2.2ms)間隔のパルス信号を処理しようとしているのに ms 単位のズレとか無理。「組込系の人って大変なんだね。」とか思った次第です。

ちなみに、PIC は 1 命令 1 サイクルらしいから「ここでこの処理したら遅延は何 us だ?」とか、アセンブラだと考えながら、計算しながらプログラムが可能になる。そうか。それでみんなアセンブラでプログラム組んでるのか。

だがしかし、俺はこんなことでは快適な C 言語環境を手放さない。ラジコンの電飾制御プログラムくらいだったらコンパイラのコツを掴めばなんとかなる。と、思う。

ってことで一昨日のプログラムを少し変更。変更箇所は HI-TECH C の __delay 関数について若干の勘違いがあった部分。

「4MHz の場合、__delay 関数には引数として 197 しか入れれないよ。」ってのをどこかで読んだ。だから区切りの良い数字で __delay_us(100) を 16 回 for ループしてたワケなんだけれども... デバッグするとこの for ループもかなりのサイクルを消費することが判明。っても 数十サイクル、数十 us くらいなので AUX の HI/LO スイッチにとっては何の問題でもないんだけれども... 何となく気になるので書き直そう、と。

で、最初は __delay_us(100) を 16 行書いてみた。これはこれで悪くないんだけども... 個人的に同じコードを複数回書くとか嫌い。ホントにコレしか方法ないのか? と色々調べると... えーとね、__delay 関数に 197 しか指定できないのは __delay_ms の場合でした。__delay_us なら 197120 まで指定できました。そう、ミリ秒とマイクロ秒を勘違していました。素直に __delay_us(1600) と書き直しました。スッキリしました。

どうやら HI-TECH C の _delay 系関数は 197,120 サイクルを超える時間を設定できないということらしい。4MHz の場合、197,120サイクルは 197,120us であり、端数切り捨てして 197ms だ。__delay_ms の説明で 197 となっていたのを __delay_us も同じだと勘違いしてたみたい。__delay_us を使うなら堂々と __delay(1600) とか書いていい。いいんだよ。

ってことで修正版

「sw3ch_c2.txt」

若干のおっちょこちょいもあったが... この辺の事情を踏まえて次は一昨日書いた通りツーリングカー用の電飾制御プログラムを書こうと思っている。仕様は以下。

(1)AUX の HI/LO でフロント/リアライトの ON/OFF を制御
(2)TH の LO/HI でブレーキライトの ON/OFF を制御

ブレーキは LO 側でオン、フロント/リアは HI でオン、処理が逆になる。まあ、これはいいとして... AUX のパルスと TH のパルスの両方を見る必要があるのがポイント、だと一昨日も書いた。まあ、これをどうしようかというところで C 言語でプログラムした場合の注意点が出てきたワケです。

えとね、最初はね、50us くらいでループさせてその中で 2 つの処理を平行してやって行こうと思っていたのね、でもね、これをするとね、ディレイの計算がね、不可能だったのね。

まあ、約 2ms 間隔のパルス信号だから 2 つ同時に処理とか考えず、TH と AUX を交互に見ればいいだろうと。ブレーキしてから1~2パルス間隔くらいライトが点灯するのが遅れるかも知れないけど、そんなの人間が認識するのは不可能だろうと。実際にプログラム作ってブレッドボードで仮組みしてやてみたらこの方法でうまくいった。

ソースコードはもう少しブラッシュアップしてから、基盤レイアウトと一緒に公開しようと思う。ちなみに今回のツーリングカーは GT500 のレースカーのボディなのでウインカーとかない。普通の乗用車のボディとかドリフトカーだったらウィンカーが付く。そしてステアリングの信号見てウィンカー出したいとか思うかも知れないし、ニュートラルが一定時間続いたらハザード出したいとか思うかも知れない。TH、ST、AUX、入力が3本。フロント/リア、ブレーキ、ウインカー、出力が3本。8 ピンの PIC をフルに使えばこのくらいはできそうだ。最終的にはそこが目標になると思うけどドリフトしないし乗用車のボディとか持ってないからたどり着くかどうかは不明。

| | コメント (0) | トラックバック (0)

マイコンに手を出しちゃった

ついにマイコンに手を出してしまった。

ラジコンのね、電飾をね、マイコンでね、制御してあげるとかね、そういうことをしたくなったのね。だってね、買うとね、高いんだもの。作るとね、安いんだもの。

なんとなく昔の自作パソコンの雰囲気だ。今はパソコン自作するより完成品買った方が安いけど。

パソコンの自作より敷居が高いと感じるのは半田付けが必要なところか。半田付けってあんまりしたことないし、そもそも電子回路とか全然読めないし書けない。だかしかし簡単な回路だったら記号勉強すればなんとかなる。半田付けも練習すればなんとかなる。

マイコンのプログラミングは... まあ、なんていうか、正直余裕ッス。

ってことで、手を出したマイコンは「PIC」ってやつ。特に 8 ピンの PIC がラジコンの電飾制御には良く使われるようだ。8 ピンの PIC はとても小さいのでラジコンにも搭載しやすそうだ。PIC12F629 や PIC12F675 なんてのが福岡でも入手しやすい。PIC12F675 はA/D コンバータ付きで高い。A/D コンバータ使わない場合は PIC12F629 で十分と思われる。

PIC12F683 ってのもあって、これは 629/627 よりメモリも多くて若干高性能なんだけど福岡では売ってなかった。でかいプログラム書くようになったら通販で買ってみようかと思うが、まず最初は160円で買える PIC12F629 で遊んでみればいいと思う。

まず、Web読んだり本読んだり色々情報集める。本数冊買った瞬間自作よりも完成品買った方が安くなるとか考えちゃだめだ。そんなこと考えたら先に進めない。

PIC にパソコンからプログラムを書き込むにはなにやらライティング用のハードが必要らしい。PICkit3 ってのを4,500円で買った。この時点で完成品買った方が... とか考えてもだめだ。考えたら先に(ry

PICkit3 ってのを買えばそれに PIC12F629 挿してすぐにプログラムを書き込めると思っていたら... ソケット部分は別途必要らしい。ネットに転がってた回路を見て以下の基盤を作った。8ピンしか使わないから8ピンが書き込めればいい。

Pickit3_8pin

さて、プログラム書こうか。どんなプログラムを書くかというと... とりあえずね、F104 に付けてる点滅する赤いリアライトをプロポの 3ch 目(AUX)でオンオフさせたいと考えた。

ってことで受信機の仕様を調べる。受信機にはピンが3本ある。+と-とSとなってる。+と-はそのままだ。Sってなんだ? どうやらSからパルス信号が出てるらしい。パルスの幅で HI と LO を見るらしい。

このパルス信号、サンワとフタバで微妙に違う。が、違いが微妙なので AUX でオンオフ判定しようと思うくらいならサンワとフタバで同じプログラムができる。

サンワの場合、パルス幅が1500マイクロ秒(以下 us)でニュートラルだ。フタバは 1520us らしい。微妙な違いだ。とりあえず、AUX でオンオフ判定したワケなんだから、パルス幅が 1600us 以上でオン、以下でオフ、となるコードを書くことにした。

さて、PIC12F629 は 8ピンだ。うち 2ピンは+と-(+が1ピン目で-が8ピン目だ)で使うので、残りの 6ピンを入出力で使うことができる。この入出力ピン(I/Oピン)のことを GPIO っていう。PIC12F629 の 2ピン目~7ピン目を GPIO 5~GPIO 0 と呼ぶ(ピン番号と GPIO番号が逆になっている)。この辺は 8ピンの PIC で共通らしい。

今回の AUX でオンオフするプログラムでは、GPIO 3(4ピン目)で受信機のS、パルス信号を入力し、GPIO 2(5ピン目)でバックライトに向けての出力をオンオフしてあげる。

さて、問題はプログラムを何で書くかだ。ラジコンの電飾用のプログラムはアセンブラが多いと思われる。実際、今回作る程度のプログラムだったらアセンブラでも簡単に書ける。だがしかし、普段高級言語を使ってる身にとっては、アセンブラは非人道的な言語だと思えてしまう。

コンパイラの最適化はあまりされてないようだが、PIC 用のフリーの C コンパイラもあるようなので、ここは C 言語を使う。ラジコンの電飾制御程度のプログラムだったらアセンブラでメモリ節約... とか考えなくてもいいと思う。他人が書いたアセンブラのコードも参考にしたいのでアセンブラも一応勉強した。が、基本 C 言語でやっていきたいと思う。

ってことで書いた C 言語のソースコードは以下

sw3ch_c.txt

元々がアセンブラで公開されていたコードを C 言語に移植したのでなんかちょっと変なコードになってると思われる。が、とりあえず動いたのでよしとした。そのうちプログラム変更すると思われる。オフのときはスリープにするとかできないんだろうか。その辺を調べてみよう。

が、とりあえず完成品を作ってみたくなったので以下の基盤を作って F104 に組み込んだ。

Sw2ch_4x9

この図では受信機から来る 6V をそのまま PIC12F629 に入れてる。PIC12F629 の動作電圧は 2V ~ 5.5V らしい。5V で使うのが理想的とかなんとか。だがしかし今回は 6V の電圧で動かしてる。だって、接続する F104 のバックライトが 6V 前提なんだもん。5V とかだったらおそらく暗くなっちゃう。6V で PIC 動かす基盤の例もあるので、その辺はあまり気にしないことにした。

とりあえず初 PIC 作品は無事完成。プロポの 3ch目(AUX)で無事バックライトのオンオフができるようになりました、と。

次はツーリングカー用の電飾基盤を作ろうと思っている。3ch目でフロントライトとリアライトをオンオフできて、スロットルを監視して LO だったらバックライトをオンにしてあげる。つまり、TH と AUX の 2ch のパルス信号を監視する必要がある。これをアセンブラで書くとしたら(自分は)気が狂う。が、C 言語なら余裕と思われる。なので C 言語で書く。

ちなみに、マイコンに手を出した僕を見て奥さんは「バカじゃないの?買った方が安いじゃない。」って言ってた。どうも女には理解ができない世界らしい。なのでこう説明してあげた。「何いってんだよ。高いか安いかじゃないんだよ。楽しいか楽しくないかなんだよ!!」

| | コメント (2) | トラックバック (0)