mbed を使ったロボット作成 第3回

【LCDに何か出してみる】
はじめに
皆さんが接している殆どのデジタル機器には、ユーザに何かを使てるインターフェースが提供されています。
簡単なものだとLEDです。LEDの点灯している色や点滅している感覚なので、そのデバイスが検知している状態をユーザーに伝えています。
また、スマホなどのハイスペックな機器では、グラフィカルな表示で画面があったり、タッチ操作により、機器の制御を行うことができます。
現在作成しているロボットでは、LEDの点滅くらいしかしていないので、何か表示を試みようと色々探してみたところ、16文字×2行に対応したLCDモジュールがあったので、これを制御してみようと思います。
LCDモジュールについて
今回使用するLCDモジュールはデータ転送が8ビットと4ビットのいずれかを選択できます。マイコン側の空きポートの関係上、4ビットのデータ転送方式を選択しました。
また、可変抵抗を接続することで、コントラストを制御することができます。
LCDモジュールの詳細は以下のとおり。
製品名 | 16文字×2行 超ハイコントラスト大文字LCDモジュール |
メーカー | Sunlike Display Tech. Corp. |
型番 | SC1602BS*B(LCDバックライト無) |
概要 | 1. 5×7ドット+カーソル表示2. 液晶コントローラ内蔵 3. 5V単一電源(艇消費電流) 4. 1/16デューティサイクル |
値段 | 500円(秋月電子通商調べ) |
電力に必要な5V電源とGNDは、マイコンの電圧仕様と同じなのでそこから盗み取って接続します、Vo(コントラスト調整電圧)は電源から可変抵抗(10KΩ)を介して接続します。
R/W信号はWrite固定の為、GNDへ接続。RS(Register Select)及びE(Enable Signal),Data0~Data3をマイコンのポートに接続します。
mbedとの接続は以下のとおり。
ソフトウェアについて
開発環境は、「mbedを使ったロボット作成 第1回」でご紹介した「ARMのオンラインコンパイル環境」を使って作成していきます。
LCDデバイス制御用のドライバクラスを作成し、デバイスに特化した制御はこのクラスに吸収させます。利用する側からはドライバクラスのprintf等の出力機能だけで表示制御できた方が便利なので、Streamクラスを継承させたクラスとさせます。
TextPanel.h
#ifndef _TEXTPANEL_H_ #define _TEXTPANEL_H_ #include "mbed.h" /* * Text LCD Panel (SC1602BS*B) Access Driver */ class TextPanel : public Stream { public: TextPanel(PinName regsel ,PinName enable,PinName data0 ,PinName data1 ,PinName data2 ,PinName data3 ); void clearScreen(); void positionSet(int column, int row); protected: DigitalOut _regsel, _enable; BusOut _data; int _column; int _row; /* Stream implementation functions */ virtual int _putc(int value); virtual int _getc(); void byteWrite( int value ); void commandWrite( int command ); void dataWrite( int data ); int addressConvert(int column, int row); void charSend(int column, int row, int c); }; #endif /* _TEXTPANEL_H_ */
TextPanel.cpp
#include "TextPanel.h" #include "mbed.h" /* define */ #define TEXT_LCD_ROW_MAX 2 /* TEXT LCD ROW MAX */ #define TEXT_LCD_COL_MAX 16 /* TEXT LCD COL MAX */ #define REG_SEL_HI 1 /* Register Select High */ #define REG_SEL_LO 0 /* Register Select Low */ #define ENABLE_SIG_HI 1 /* Enable Signal High */ #define ENABLE_SIG_LO 0 /* Enable Signal Low */ /*******************************************/ /* Constructer */ /* param regsel Register Select信号ポート */ /* param enable Enable 信号ポート */ /* param data0-3 :データ信号ポート */ /*******************************************/ TextPanel::TextPanel(PinName regsel , PinName enable , PinName data0 , PinName data1 , PinName data2 ,PinName data3 ): _regsel(regsel),_enable( enable ),_data( data0, data1, data2, data3 ){ int count = 0; /* command mode set */ _enable = ENABLE_SIG_HI; _regsel = REG_SEL_LO; /* Wait */ wait( 0.016 ); /* 16msec wait for powered up */ /* 10msec */ /* init seq:send 0x3 3times(4bit interface) */ for( count = 0 ; count < 3 ; count++ ){ byteWrite( 0x3 ); wait( 0.00164 ); /* 1.64ms wait */ } byteWrite( 0x2 ); /* 4-bit mode */ wait( 0.000040f ); /* 40usec wait */ commandWrite( 0x28 ); /* Function Set DL:0(4bit) N:1(2Line) F:5*7dot */ commandWrite( 0x0C ); /* Disable ON/OFF Control */ commandWrite( 0x06 ); /* Entry Mode Set Increment */ clearScreen(); } /**********************************/ /* スクリーンをクリアする */ /* param:無し */ /* return:無し */ /**********************************/ void TextPanel::clearScreen(){ commandWrite( 0x01 ); /* Clear Display */ wait( 0.00164 ); } /************************************/ /* デバイスにデータを転送する */ /* param:value 転送するデータ(byte) */ /* return:無し */ /************************************/ void TextPanel::byteWrite( int value ) { /* Uppwer 4bit Send */ _data = value >> 4; wait(0.000040f); /* 40us wait */ _enable = ENABLE_SIG_LO; wait(0.000040f); /* 40us wait */ _enable = ENABLE_SIG_HI; /* Lower 4bit Send */ _data = value >> 0; wait(0.000040f); /* 40us wait */ _enable = ENABLE_SIG_LO; wait(0.000040f); /* 40us wait */ _enable = ENABLE_SIG_HI; } /**********************************/ /* コマンドデータ転送処理 */ /* param:command 転送するコマンド */ /* return:無し */ /**********************************/ void TextPanel::commandWrite( int command ) { _regsel = REG_SEL_LO; byteWrite( command ); } /**********************************/ /* データ転送処理 */ /* param:data 転送するデータ */ /* return:無し */ /**********************************/ void TextPanel::dataWrite( int data ){ _regsel = REG_SEL_HI; byteWrite( data ); } /**********************************/ /* 行・列情報 コマンド変換 */ /* param:column 出力先:列位置 */ /* param:row 出力先:行位置 */ /* return:転送コマンド */ /**********************************/ int TextPanel::addressConvert(int column, int row) { return 0x80 + (row * 0x40) + column; } /**********************************/ /* 文字データの転送を行う */ /* param:column 出力先:列位置 */ /* param:row 出力先:行位置 */ /* param:c 送信する文字コード*/ /* return:無し */ /**********************************/ void TextPanel::charSend(int column, int row, int c) { int a = addressConvert( column, row ); /* 表示位置計算コマンドの生成 */ commandWrite( a ); /* 出力先転送 */ dataWrite( c ); /* 表示データ転送 */ } /**********************************/ /* 1文字分のデータ転送を行う */ /* param:value 送信する文字コード */ /* return:送信した文字コード */ /**********************************/ int TextPanel::_putc(int value) { /* 改行コード? */ if (value == '\n') { _column = 0; _row++; /* 最終行の場合 */ if (_row >= TEXT_LCD_ROW_MAX ) { _row = 0; } /* 改行コード以外 */ } else { /* 1文字分データ転送 */ charSend(_column, _row, value); _column++; /* 行端に達した場合 */ if (_column >= TEXT_LCD_COL_MAX ) { _column = 0; _row++; /* 最終行の場合 */ if (_row >= TEXT_LCD_ROW_MAX ) { _row = 0; } } } return value; } /**********************************/ /* 入力文字の取得は行わない */ /* param 無し */ /* return -1(常に) */ /**********************************/ int TextPanel::_getc() { return -1; } /**********************************/ /* 出力位置を変更する */ /* param column 出力位置 列 */ /* param row 出力位置 行 */ /* return 無し */ /**********************************/ void TextPanel::positionSet(int column, int row) { _column = column; _row = row; }
main.cpp
#include "mbed.h" #include "TextPanel.h" #if 1 TextPanel lcd(D11, PC_9, D12, D13, D14, D15 ); // rs, e, d4-d7 #else TextLCD lcd(PA_7, PC_9, PA_6, PA_5, PB_9, PB_8 ); // rs, e, d4-d7 #endif DigitalOut myled(LED2); int main() { wait(0.001); lcd.clearScreen(); wait(0.001); lcd.positionSet(0, 0); lcd.printf( "TESTtestTest\n"); int iCounter = 0; while(1) { lcd.positionSet(0, 1); lcd.printf( "%d",iCounter); iCounter++; wait(1.0); myled = 1; // LED is ON wait(1.0); // 200 ms myled = 0; // LED is OFF wait(1.0); // 1 sec } }
実行結果
簡単なプログラムによるポート制御で
マイコンからLCDの表示制御ができることが確認できました。
次回はUSBポートについて制御してみたいと思います。
【参考】
mbedを使ったロボット作成 第1回
mbedを使ったロボット作成 第2回
ホームページ http://www.ois-yokohama.co.jp
facebook https://www.facebook.com/orientalinformationservice/
1 thoughts on “mbed を使ったロボット作成 第3回”
この投稿はコメントできません。