2010/08/17(火)mbedでロータリーエンコーダを読んでみた

2010/08/18 05:53 mbednucho
mbedのCookbookを覗いていたら、QEIライブラリというものを見かけました。
このライブラリはロータリーエンコーダのパルス数を数えるためのものなようです。
ロータリーエンコーダは使う予定があるので、試しに使ってみました。

ロータリーエンコーダとは

 ロータリーエンコーダとは回転量を測定するために使われるセンサです。安価で扱いが簡単なインクリメンタル式と高価なアブソリュート式の二種類があり、今回扱うものはインクリメンタル式の方です。*1
 インクリメンタル式のロータリーエンコーダは軸が一定量回転するごとに位相がずれたA相とB相のパルスを出力します。A相とB相は回転方向によって出力タイミングが逆の関係になるため、どちらの方向へどれだけ回っているのかということを計測することができるわけですね。
 また、A相、B相の立ち上がり立下りから1周期分のパルス出力で4個の分解能を取ることができるため、エンコーダ分解能は出力パルスの4倍ということになります。
つまり、360度回転する間に24パルス出力するロータリーエンコーダであれば
360[deg] / (24[pulse]*4) = 3.75[deg]
の分解能があると計算できます。

rotaryencorder_pulse.png


*1 : 延々周り続ける電子レンジのつまみとかは確かこれです

QEIライブラリを使ってみる

QEIはQuadrature Encoder Interfaceの略でインクリメンタル式のロータリーエンコーダを読むためのライブラリです。
今回はとりあえず手元にあった秋月で200円で売っているエンコーダの出力パルス数を計測し、キャラクタLCDに表示するものを作ってみました。
100818-051809.jpg

回路図

RotaryEncorder_test.PNG

プログラム

QEI_test
#include "QEI.h"
#include "TextLCD.h"


TextLCD lcd(p5, p6, p11, p12, p13, p14); // rs, e, d0-d3
Serial pc(USBTX, USBRX);

#define ROTATE_PER_REVOLUTIONS  24
//Use X4 encoding.
QEI wheel(p30, p29, NC, ROTATE_PER_REVOLUTIONS, QEI::X4_ENCODING);
//Use X2 encoding by default.
//QEI wheel (p30, p29, NC, 624);

int main() {
    while(1){
        wait(0.1);
        lcd.printf("Pulses: %07d\n", wheel.getPulses());
        lcd.printf("Rotate: %04.3f\n", (double)wheel.getPulses()/(ROTATE_PER_REVOLUTIONS*4));
    }
}


それでは要点の説明です。
#define ROTATE_PER_REVOLUTIONS  24
//Use X4 encoding.
QEI wheel(p30, p29, NC, ROTATE_PER_REVOLUTIONS, QEI::X4_ENCODING);
QEIのインスタンスを生成しています。
第一、第二引数にA相のピン、B相のピンを設定します。
第三引数はオプションで回転数を数えるピンがあればそれを設定するようです。
第四引数はロータリーエンコーダが一回転あたり何パルス出力するかを設定しています。*2
第五引数はモードを設定しています。X4_ENCODINGモードであればロータリーエンコーダの分解能を完全に使って1パルス出力で4カウント増加します。X2_ENCODINGモードであれば、ロータリーエンコーダの分解能を半分にして1パルス出力で2カウント増加します。おそらくX2_ENCODINGモードにすると周波数が高い時に取りこぼしが少なくなると考えられるので、分解能があまり必要でなく精度が必要な場合はこちらを使うという風に使い分けるのだと思います。


        lcd.printf("Pulses: %07d\n", wheel.getPulses());
        lcd.printf("Rotate: %04.3f\n", (double)wheel.getPulses()/(ROTATE_PER_REVOLUTIONS*4));
キャラクタLCDに出力しています。
1行目ではwheel.getPulses()メソッドによって初期状態から現在のどちら方向にどのくらい回ったかというのを取得しています。
2行目では軸が何回転したかというのを計算して表示しています。

*2 : でも内部では使用されてなくて、何のために設定しているかちょっとよくわかりません…^^;。

終わりに

機械接点式のロータリーエンコーダであるため、チャタリングというノイズがのり速く回したりするとどんどん実際の回転数とズレが出てきてしまいますね。X2_ENCODINGモードだとちょっとましになるのかな…?

準備が出来たら次はこのモータで計測を行ってみたいと思ってます。

参考

ロータリーエンコーダを使う

2010/07/04(日)mbedでZY-FGD1442701V1を動かしてみた その2

2010/07/04 22:52 mbednucho
前回の続きでZY-FGD1442701V1に画像を表示してみました。

SDカードまたはmbedのフラッシュメモリから16bitビットマップ画像を読み取るということをしています。
16bitビットマップ画像(R5 G5 B5)はこちらを参考にGimp2を使って準備しました。

動かしてみたところ

100703-213115.jpg
  
100703-205336.jpg

色数が65536色だけあって、表示は思っていたよりもずっと綺麗です。

回路図

ZY_FGD1442701V1_sample2.PNG

相変わらずカオスな回路図ですみません…。
SDカード、液晶共にVccはmbedのVoutと接続しています。
mbed内のフラッシュメモリを使う場合はSDカード部分は必要ありません。

プログラム

SDカードから読み込みをする場合
ZY_FGD1442701V1_sample2

mbedのフラッシュメモリから読み込みをする場合
ZY_FGD1442701V1_sample2_local
今回のプログラムはここに置いておきます。
SDカードまたはmbedのフラッシュメモリ内に作成したビットマップ画像をsample.bmpという名前で置いておけば液晶に表示されるはずです。

処理について

単純に、ビットマップ画像を2ビットずつ読み込んで、液晶に2ビット送信して…という処理をしています。

初期化はデモプログラムの時とほとんど同じですが、そのままだと画像が反転して表示されたので
    WriteCOM(0x36);//MV,MX,MY,RGB
    WriteDAT(0xC8);
の部分を
    WriteCOM(0x36);//MV,MX,MY,RGB
    WriteDAT(0x88);
とだけ変えました。
このへんの詳細はデータシートのP60あたりに載っています。

また、16bitビットマップの取り扱いについてはbeizのノート@ ウィキさんを参考にさせて頂きました。
参考というかそのまま(^^;

処理時間

初期化に860ms表示に763msかかっていますが、beizのノート@ ウィキさんに載っているように液晶への書き込みをバッファリングしたら、さらに高速化できるものと思われます。

2010/07/01(木)mbedでZY-FGD1442701V1を動かしてみた その1

2010/07/01 23:18 mbedimportnucho
ZY-FGD1442701V1とはaitendoで売られている1.44インチTFT液晶モジュールです。
3.3V単一電源で駆動できるほかデモプログラムも用意されているため、とりあえず動かして見るといったことが簡単にできます。
また、キャリーボード付きで1200円と非常に安価という特徴もあります。

ちょっと前に買って積んだままになっていたものを見つけたので、mbedを使って動かしてみました。

動かしてみたところ

100701-131252.jpg

ひどい写真だ…。
画面いっぱいに赤色を表示させています。

回路図

ZY_FGD1442701V1_sample.PNG

mbedも駆動が3.3Vなので、とてもシンプルな回路図となりますね。

プログラム

ZY_FGD1442701V1_sample
mbedにはBusOutというライブラリが用意されていて、今回はこのライブラリを使用しました。
この例のようにバイト単位で出力を行うときなど、繋ぐピンを意識せず処理を行うことができるので非常に便利です。


今回はとりあえずデモプログラムをmbed向けにほんの少しだけ書き換えただけです^^;
次回は16bitビットマップ画像をSDカードから読み込んで表示させてみたいと思います。

2010/06/04(金)mbedのNTP Clientを試してみた

2010/06/04 01:33 mbednucho
mbedにはRTC(リアルタイムクロック)という現在時刻を刻み続けることのできる部品が乗っています。
VBピンに2.1Vから3.6Vの電池を繋いでおけば、mbedの電源を切っても時間を覚えておくことが可能です。

mbedのベータテスト中の新しいCookbookページの中にそのRTCの時間をネットワークから設定するNTP Clientというライブラリが追加されていました。
今回はこれと前回使ったText LCDライブラリを利用して、ネットワークから同期して時間を合わせる時計を作ってみることにしました。

100604-012951.jpg


今回つくったプログラムはここに置いておきました。
中身はほとんどサンプルファイルのままなのですが、本質的な部分と思われる個所だけ以下に抜き出しておきます。
    Host server(IpAddr(), 123, "ntp.jst.mfeed.ad.jp");
    ntp.setTime(server);//RTCに時間をセットする

    ctTime = time(NULL);//RTCの時間を呼び出す
    ctTime += 32400; //世界標準時刻から日本標準時刻に直すために、32400秒(9時間)進める
    strftime(buf,sizeof(buf), "%A %m/%d/%Y %H:%M:%S\n", localtime(&ctTime));//フォーマットに直して
    printf("\r\nTime is now : %s JST\r\n", buf);//表示

また、新CookBookの中には新しいTextLCDのライブラリも追加されていましたので、今回は新しい方のライブラリを使用しました。
配線とTextLCDオブジェクトを作る際の引数がほんの少しだけ変わっているので注意してください。
(R/WをGNDを接続するようになり、TextLCDオブジェクトにそのピンを指定しないようになっています)


イーサネットが標準でついていると、このような拡張性があるのが嬉しいですね。