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との接続

ソフトウェアについて

開発環境は、「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回

この投稿はコメントできません。