« 2011年1月 | トップページ | 2011年5月 »

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)

« 2011年1月 | トップページ | 2011年5月 »