目次

LCDメッセージボードスケッチ

 最近の地下鉄、電車には、ドアの上にLCDを利用した
 メッセージボードを用意していることがあります。



 この掲示板を2行16桁のLCDでエミュレートします。



 PersonalComputerから、与えた文字列を
 表示すれば、LCD掲示板になります。

 ブロック図で示すと、システム構成は以下。



 LCDには14ピンありますが、Arduinoからは6ピン
 制御で、次の信号線を接続します。



 Arduinoで使われているマイコンAVRでは
 ポートCに、LCDを接続することになります。

 回路図では結線は、次のようになります。



 ハードウエアの接続が決まれば、スケッチで
 LCDを使えるようにします。

 ArduinoIDEで、LCD制御用ライブラリを選択
 しておきます。


 ピンと信号の割当は、スケッチの先頭に
 記述します。(setup、loopの外で!)

  LiquidCrystal lcd(14,15,16,17,18,19);

 ハードウエア上の仕様を決めたなら、LCD
 を接続しておきます。



 表示文字列をシリアルで設定するので
 プロトコルを考えます。

 Arduinoには、コマンドインタプリタを
 用意しておきます。
 コマンドインタプリタで使うコマンド
 を定義します。

 コマンド'L'は、2行あるうちにどちらかを指定
 しなければなりません。

 コマンド+行番号+文字列というフォーマットに
 しておきます。

 Arduinoは、シリアル受信割込みに対応しているので
 受信バッファに入った文字列を、ユーザーが用意した
 バッファに転送後、処理する方法を考えます。

 受信した文字があれば、シリアル受信割込みハンドラ
 の中で、受信バッファから取出し、用意した配列へと
 コピーするコードを記述します。

 Arduinoの場合、割込みはxxxEventという関数で定義
 するので、次のような記述で対応できます。

void serialEvent(){
  char ch;
  if ( Serial.available() > 0 ) {
    // get 1 charactor
    ch = Serial.read();
    // store
    sbuf[sindex] = ch ;
    // increment
    sindex++ ;
  }
  // judge
  if ( ch == '\r' ) {
    sindex = 0 ; 
    uflag = ON ;
  }
}

 1文字列の内容は、バッファsbufに入れておきます。
 端末からは、文字列の最後に'\r'(Enter)が入って
 送信されてくるとプロトコルを決めます。

 処理すべき文字列が、バッファの中に入ったことを
 loop()に通知するため、フラグuflagを利用します。

 loopの中では、コマンドインタプリタを使い
 バッファの中のコマンド、パラメータを判断
 します。処理は簡単です。

    cmd = sbuf[0] ;
    // help
    if ( cmd == '?' ) { show_help() ; }
    // clear
    if ( cmd == 'c' ) { lcd.clear(); }
    // copy
    if ( cmd == 'l' ) {
      // get line number
      linex = sbuf[1] - '0' ;
      // copy
      for ( i = 0 ; i < LINELAST ; i++ ) {
        // adjust pointer
        j = i+2 ;
        // judge
        if ( sbuf[j] == '\r' ) break ;
        // store
        lcd.setCursor(i,linex) ;
        lcd.write(sbuf[j]);
      }
    }

 コマンドインタプリタで利用しているヘルプ処理は
 文字列を表示するだけなので、Serialのメソッドを
 使って記述します。

void show_help() {
  Serial.println("? help");
  Serial.println("L send strings with line number");
  Serial.println("C clear LCD display");
}

 主な処理を定義したので、スケッチにまとめます。

#include <LiquidCrystal.h>

/* 14:RS 15:E 16:DB4 17:DB5 18:DB6 19:DB7 */
LiquidCrystal lcd(14,15,16,17,18,19);

#define LINELAST 16

#define OFF 0
#define ON  OFF+1

#define BSIZE 24

char uflag ;
char sbuf[BSIZE] ;
char sindex ;
char cmd ;

void show_help() {
  Serial.println("? help");
  Serial.println("L send strings with line number");
  Serial.println("C clear LCD display");
}

void setup() {
  //
  Serial.begin(9600);
  // set 16 characters , 2 lines
  lcd.begin(16, 2);
  // display off cursor
  lcd.noCursor();
  //
  uflag = OFF ;
  sindex = 0 ;
}

// the loop() method runs over and over again,
// as long as the Arduino has power
void loop()
{
  char linex ;
  char i ;
  char j ;
  // command interpreter
  if ( uflag == ON ) {
    uflag = OFF ;
    // get command 
    cmd = sbuf[0] ;
    // help
    if ( cmd == '?' ) { show_help() ; }
    // clear
    if ( cmd == 'c' ) { lcd.clear(); }
    // copy
    if ( cmd == 'l' ) {
      // get line number
      linex = sbuf[1] - '0' ;
      // copy
      for ( i = 0 ; i < LINELAST ; i++ ) {
        // adjust pointer
        j = i+2 ;
        // judge
        if ( sbuf[j] == '\r' ) break ;
        // store
        lcd.setCursor(i,linex) ;
        lcd.write(sbuf[j]);
      }
    }
  }
}

void serialEvent() {
  char ch;
  //
  if ( Serial.available() > 0 ) {
    // get 1 charactor
    ch = Serial.read();
    // store
    sbuf[sindex] = ch ;
    // increment
    sindex++ ;
  }
  // judge
  if ( ch == '\r' ) {
    sindex = 0 ; 
    uflag = ON ;
  }
}

 このスケッチを使うときは、ArduinoIDEの端末
 エミュレータでは'\r'を入力できないので、
 TeraTermを使って処理します。

目次

inserted by FC2 system