2016年10月9日日曜日

TLC5940でサーボ制御

最近思うところあって、というかドローンをやりたくなって多チャンネルのサーボ制御を試しています。ドローンというと最近はマルチコプターが多勢ですが、昔からあるRQ-11レイヴンとかケタリング・バグみたいなああいうドローンです。


さて、タイトルの件ですが、ネットでググると沢山の製作例がヒットします。というのも、Arduino日本語リファレンスにTLC5940を使ったLEDドライバが書かれており、これから派生してサーボ制御になったものと思われます。
が、これらの情報(Arduinoを使った例)は全く参考になりませんでした。

というのも、Arduinoはユーザーが制御を意識せずに使えるため、ライブラリの中身を見ない限りはどういう制御をしているのかがわからないためです。これはある面では大きな利点ですが、別の面では欲しい情報が見つからないどころか、検索の邪魔になる欠点もあります。


TLC5940というICのおさらいですが、本来は多チャンネルLEDドライバとして作られたICです。IC自体の動作電圧範囲は3-5.5Vですが、出力が定電流オープンドレインのため、LEDの電源は17Vまで耐えられます。シンク電流は最大120mA(IC電源電圧による制限あり)で、小型のハイパワーチップLED程度なら充分にドライブできます。
最近のLEDバックライトな液晶テレビは、バックライトをタイル状に分割し、「暗い部分はバックライトで暗くする」という方法でコントラストを稼いでいたりします。旧来の画面全体に対して1セットの光源ではテレビ1台に対してドライバが1個あれば済みますが、このような方法を使う場合は多チャンネル(ただし1個自体の電力は少なめ)というドライバが必要になり、そのような場所にTLC5940を始めとした多チャンネルドライバは最適な選択肢となりえます。実際、TLC5940の用途にはディスプレイバックライトも含まれています。
他にもいろいろな用途がありますが、もちろん今回はLEDドライバとしては使いません。





TLC5940はオープンドレインですが、適当な抵抗でプルアップすればPWMを出力することも可能です。今回はプルアップに1kOhmを使用し、IREFに3.3kOhmを使用しました。プルアップ電流は電圧に応じて4-9mA程度、シンク電流は12mA程度です。

TLC5940はオープンドレインですから、アクティブLowとなります。GSCLKに入れるPWMが安定であれば設定したLowパルス幅をきれいに出力できますが、Highのパルス幅を正確に制御しようとした場合、次のGSCLKのタイミングも合わせる必要があります。

STM32F1のタイマはマスタ・スレーブを利用して定期的にTIMを走らしたり止めたりができますから、この機能を利用してPWMを送ることにします。
パルス幅のソースはGSCLKですが、GSCLKのカウンタをリセットするためにBLANKも定期的に送り込む必要があります。GSCLKを4096パルス送った後にBLANKを送ります。このタイミングはTIMで作ろうとすると面倒なのと、BLANKは直接タイミングに影響することは無いため、TIM3のOCを2個使用して割り込みでGPIOをSet,Resetしています。またこのOC割り込みの中でTIM2のアップデートイベントを発生させています。このイベントによりTIM2のプリスケーラを含めたカウンタがクリアされるため、常に同じ位相を維持できます。
またTIM3の別のOCを使用してTIM2を4096パルス分だけ動かしています。TIM自体はワンショットか連続かを選択できますが、n回だけ走らせる、というような動かし方をする場合、大抵は別のTIMからENAを制御する必要があります。1Hz100回程度であればUpdateイベントでカウンタを監視し、一定回数でTIMを止めるといったことも可能ですが、今回は1MHzで走らせているのでソフトウェアで行うことは不可能と考えました。

データの転送にはSPIを使用し、XLATはSPI転送終了後にGPIOでトグルします。IC自体は30MHzまで受けれるようですが、STM側の都合から18MHzで転送しています。またDMAを使用せず、ソフトウェアでポーリングして転送しているため、かなり遅いです。ただ16chであればせいぜい24バイトですから、あまり気にしないことにします。


基本的にサーボの制御は50Hz程度のPWMを送信します。しかし今回は制御の都合から約222HzのPWMを送信しています。もっと複雑な制御を行えば50Hzに合わせることも可能でしょうが、SG92Rで試したところ、一応パルス幅通りに動いたため問題ないと判断しました。


ということで、16chまでのサーボ制御はできるようになりました。以前にGPIOに対してDMA転送して16chパルスを生成しましたが、この方法ではRAMを大量に食う、データバスを大きく専有する、といった問題点がありました。TLC5940を使えば1xSPI、2xTIMが必要になりますが、CPUリソースはあまり専有せずに16chを制御できます。またTLC5940は任意個数をカスケード接続できますから、サーボが50個とか100個必要になっても多少の変更で対応できます。



最後になりますが、TLC5940を使う際(LEDドライバとして含め)に気をつけるべきこととか。

基本的に各ピンはプルアップ・プルダウンを適切に挿入しておくべきです。少なくともSCLKをプルダウン、BLANKをプルアップで固定しておきます。BLANKがHの場合は出力が止まりますから、LEDが点灯しっぱなしになるようなことはありません。ただ念のため他の入力端子も固定しておきましょう。SIN,XLAT,GSCLKですが、これらはプルダウンとなります。これらが不適切な場合は、マイコンがリセットされているときにICに触れるとLEDがチカチカするという挙動を示すことになります。静電気にも弱くなりますから、可能な限り浮動しないようにしましょう。

TLC5940はCMOSレベルです。例えばTLC5940を5V、マイコンを3.3Vで動かした場合、直結することはできません。バッファを挟むか、TLC5940も3.3Vで動作させる必要があります。ただしTLC5940を3.3Vで動作させた場合はシンク電流は60mAに制限されます。3.3Vで60mAを超えて流した場合は発熱します。

そして重要なことですが、LEDとTLC5940の間に抵抗を挟んでも電流が制限されることはありません。無駄な抵抗というか、損失が多くなるだけですから、LEDと直列に抵抗を挟んで電流を制限することはやめましょう。順方向電流の違うLEDを混在させたい場合は一番電流が少ないLEDに合わせましょう。それが嫌ならDC(Dot Correction)を使って電流を制限することもできます。ただしこの場合はDCが不適切に設定された環境ではLEDが破壊される可能性があることに留意しましょう。
DC自体は起動時にEEPROMから読み込まれるため、DCを使用しない場合は初期化する必要はありません。EEPROMでは3Fhに初期化され、これはIREFで設定した電流値の100%を流すことができます。

あとはまぁ、詳しくはデータシートを読めということでひとつ。


/*
せっかく多チャンネルの制御ができるようになったのですから、色々遊びたいです。例えば主翼にフラップとエルロンで4サーボ、水平尾翼はエレボンで2サーボ、垂直尾翼で2サーボ、動力は2系統で2ESC、計12ch、とか。これくらい動かすものがあるとCCV的な制御もできそうです。
でもRQ-11って3chしか無いんですよね。カメラジンバルだって無いし。ということで目指す形はF-22みたいな感じになると思います。まずはセスナみたいな高翼単発機でしょうけども。いずれはEDFもやりたいなぁと思いつつ。

昔にラジコン飛行機をやっていた頃は国内メーカーの3ch入門機が1.5-2万円くらいでしたが、最近はそのクラスの機体は見かけない気がします(あんまり調べてないですが)。そのメーカーは「最初から上手な人はいません」と入門機の重要性を説いていましたが、最近では高価な機体しか作っていないですね。
ホビー界隈が全体的に高価格化して新規ユーザーの獲得はあんまり考えていないような気がします。メーカーからすればお前には言われたくねぇよって感じでしょうけども。
*/

0 件のコメント:

コメントを投稿