目次
前
次
LCDメッセージボードスケッチ
最近の地下鉄、電車には、ドアの上にLCDを利用した
メッセージボードを用意していることがあります。
この掲示板を2行16桁のLCDでエミュレートします。
PersonalComputerから、与えた文字列を
表示すれば、LCD掲示板になります。
ブロック図で示すと、システム構成は以下。
LCDには14ピンありますが、Arduinoからは6ピン
制御で、次の信号線を接続します。
- DB7 19(LCD 14)
- DB6 18(LCD 13)
- DB5 17(LCD 12)
- DB4 16(LCD 11)
- E 15(LCD 6)
- RS 14(LCD 4)
Arduinoで使われているマイコンAVRでは
ポートCに、LCDを接続することになります。
回路図では結線は、次のようになります。
ハードウエアの接続が決まれば、スケッチで
LCDを使えるようにします。
ArduinoIDEで、LCD制御用ライブラリを選択
しておきます。
ピンと信号の割当は、スケッチの先頭に
記述します。(setup、loopの外で!)
LiquidCrystal lcd(14,15,16,17,18,19);
ハードウエア上の仕様を決めたなら、LCD
を接続しておきます。
表示文字列をシリアルで設定するので
プロトコルを考えます。
Arduinoには、コマンドインタプリタを
用意しておきます。
コマンドインタプリタで使うコマンド
を定義します。
- ? help
- L send strings with line number
- C clear LCD display
コマンド'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を使って処理します。
目次
前
次