ワイヤレスLCD(赤外線データ通信)
概要
LCDは製作する装置に内蔵して利用するのが一般的です。
しかし、離れた場所に設置するような装置では、常時LCDに表示する必要はありません。
つまり、確認する必要が生じた時のみ、LCDを持って行き接続し、データを表示をさせれば良い事になります。
そうすることにより、装置の小型化や低消費電力化を図ることが出来ます。
通常は、装置とLCDの接続は、コネクタ(ケーブル)で行いますが、今回は、赤外線を利用(ワイヤレス)して、非接触でデータ通信を行い、LCDにデータを表示させました。
非接触のメリットは、
- コネクタの抜き差しの手間が省ける。
- 雨天であっても、装置に近づけるだけでデータが表示できる。(つまり装置の蓋を開ける必要がない)
等が考えられます。
クライアント側に実装する、ユーザアプリケーションのために、「ワイヤレスLCD制御ライブラリ」を提供します。
ライブラリの仕様は、mikroCコンパチブルとしました。従って、関数名さえ変更すれば、どちらのライブラリでも同じように動作させることが出来ます。
| mikroC版LCD制御ライブラリ | ワイヤレスLCD制御ライブラリ <ユーザアプリケーションより呼び出します> |
|---|---|
| Lcd_Init | Lcd_Init_Remote |
| Lcd_Out | Lcd_Out_Remote |
| Lcd_Out_Cp | Lcd_Out_Cp_Remote |
| Lcd_Chr | Lcd_Chr_Remote |
| Lcd_Chr_Cp | Lcd_Chr_Cp_Remote |
| Lcd_Cmd | Lcd_Cmd_Remote |
動作原理
動作原理(ハードウェア)
◎赤外線の送信
高輝度赤外線LED(OSIR5113A)を使用します。
◎赤外線の受信
テレビ・ビデオ等のリモコンに使用されている受光モジュール(SPS-443)を使用します。
ピンフォトダイオード、アンプ、フイルター回路が内蔵されています。
38kHzの副搬送波で振幅変調された赤外線のみを検出する事(ノイズ対策)が出来ます。
◎副搬送波(38kHz)の発生
PIC内蔵のCCPモジュールをPWMモードで使用し、38kHzを発生させます。
動作原理(ソフトウェア)
◎提供関数(クライアント側)
- Lcd_Init_Remote();
LCDを初期化します。 - Lcd_Out_Remote(char row, char column, char *text);
行(row)と列(column)を指定して、LCDに文字列(text)を表示します。 - Lcd_Out_Cp_Remote(char *text);
カレントカーソルに、LCDに文字列(text)を表示します。 - Lcd_Chr_Remote(char row, char column, char out_char);
行(row)と列(column)を指定して、LCDに文字(out_char)を表示します。 - Lcd_Chr_Cp_Remote(char out_char);
カレントカーソルに、LCDに文字(out_char)を表示します。 - Lcd_Cmd_Remote(char out_char);
LCDにコマンド(out_char)を送信します。
※mikroCコンパチブルにしましたので、詳細については、其方(HELP)を参照してください。
※動作確認のため、クライアント側には、PIC16F88を使用しましたが、他のPICでも同様に動作します。
◎メイン処理
スイッチ(SW1)の設定により、サーバ側、クライアント側を切り替え、各処理を呼び出します。
SW1=GND→サーバ側(Lcd_Server関数)
SW1=Vdd→クライアント側(Lcd_Client関数)
◎クライアント処理
副搬送波(38kHz)を発生させるために、CCPモジュールをPWMモードで初期化します。
A/D変換を行い、サーバ側に表示データを送信します。
※ユーザアプリケーションは、このクライアント処理を修正して、実装します。
◎サーバ処理
LCDおよびUSARTを初期化します。
クライアントからのデータを受信します。
受信データを解析し、LCDを制御します。
回路図
ソースコード
- remote_lcd.c
//********************************************************************** /* <ワイヤレスLCD(赤外線データ通信)> */ //********************************************************************** //■マクロ定義 #define BYTE unsigned short #define WORD unsigned int #define DWORD unsigned long // sbit SW at RA5_bit; #define EOF 0x00 // sbit LED at RB1_bit; #define ON 1 #define OFF 0 //LCD sbit LCD_RS at RB6_bit; sbit LCD_EN at RB7_bit; sbit LCD_D7 at RA1_bit; sbit LCD_D6 at RA0_bit; sbit LCD_D5 at RA7_bit; sbit LCD_D4 at RA6_bit; sbit LCD_RS_Direction at TRISB6_bit; sbit LCD_EN_Direction at TRISB7_bit; sbit LCD_D7_Direction at TRISA1_bit; sbit LCD_D6_Direction at TRISA0_bit; sbit LCD_D5_Direction at TRISA7_bit; sbit LCD_D4_Direction at TRISA6_bit; //********************************************************************** //■関数宣言 extern void main(); extern void Lcd_Server(); extern void Lcd_Client(); extern void Lcd_Init_Remote(); extern void Lcd_Out_Remote(char row, char column, char *text); extern void Lcd_Out_Cp_Remote(char *text); extern void Lcd_Chr_Remote(char row, char column, char out_char); extern void Lcd_Chr_Cp_Remote(char out_char); extern void Lcd_Cmd_Remote(char out_char); extern void Lcd_Send_Chr(unsigned short dt); extern void Lcd_Send_Str(unsigned short* pData); //********************************************************************** //■メイン関数 void main() { OSCCON = 0b01110000; TRISA = 0b11111111; TRISB = 0b00001100; // LED = OFF; // if (SW == 1) { Lcd_Client(); } else { Lcd_Server(); } } //********************************************************************** //■ワイヤレスLCDサーバ関数 void Lcd_Server() { char dt, cnt, buf[32]; // ANSEL = 0b00000000; // Lcd_Init(); Lcd_Cmd(_LCD_CURSOR_OFF); Lcd_Cmd(_LCD_CLEAR); for (cnt = 0; cnt < 16; cnt++) { Lcd_Chr(1, cnt + 1, 0xFF); Delay_ms(50); } for (cnt = 0; cnt < 16; cnt++) { Lcd_Chr(2, cnt + 1, 0xFF); Delay_ms(50); } Delay_ms(1000); Lcd_Cmd(_LCD_CLEAR); // Uart1_Init(1200); // while(1) { cnt = 0; while (1) { if (Uart1_Data_Ready() != 1) { continue; } // dt = Uart1_Read(); if (dt != EOF) { buf[cnt] = dt; cnt++; } else { buf[cnt] = 0x00; LED = ~LED; break; } // if (cnt == 32) { cnt = 0; continue; } } // switch (buf[0]) { case 'A': Lcd_Out(buf[1], buf[2], &buf[3]); break; case 'B': Lcd_Out_Cp(&buf[1]); break; case 'C': Lcd_Chr(buf[1], buf[2], buf[3]); break; case 'D': Lcd_Chr_Cp(buf[1]); break; case 'E': Lcd_Cmd(buf[1]); break; } } } //********************************************************************** //■ワイヤレスLCDクライアント関数 void Lcd_Client() { char buf[16]; WORD ad; // ANSEL = 0b00001111; // Lcd_Init_Remote(); // while (1) { ad = Adc_Read(0); ad = ad * 4.8828125; WordToStr(ad, buf); Lcd_Out_Remote(1, 1, buf); Lcd_Out_Cp_Remote("mV"); // ad = Adc_Read(1); ad = ad * 4.8828125; WordToStr(ad, buf); Lcd_Out_Remote(1, 9, buf); Lcd_Out_Cp_Remote("mV"); // ad = Adc_Read(2); ad = ad * 4.8828125; WordToStr(ad, buf); Lcd_Out_Remote(2, 1, buf); Lcd_Out_Cp_Remote("mV"); // ad = Adc_Read(3); ad = ad * 4.8828125; WordToStr(ad, buf); Lcd_Out_Remote(2, 9, buf); Lcd_Out_Cp_Remote("mV"); // Delay_ms(100); } } //********************************************************************** //■ワイヤレスLCD初期化関数 void Lcd_Init_Remote() { Pwm1_Init(38000); // 38kHz duty=50% Pwm1_Set_Duty(PR2 / 2); Pwm1_Stop(); } //********************************************************************** //■ワイヤレスLCD文字列出力(行列指定)関数 void Lcd_Out_Remote(char row, char column, char *text) { Lcd_Send_Chr('A'); Lcd_Send_Chr(row); Lcd_Send_Chr(column); Lcd_Send_Str(text); Lcd_Send_Chr(EOF); } //********************************************************************** //■ワイヤレスLCD文字列出力(カレント位置)関数 void Lcd_Out_Cp_Remote(char *text) { Lcd_Send_Chr('B'); Lcd_Send_Str(text); Lcd_Send_Chr(EOF); } //********************************************************************** //■ワイヤレスLCD文字出力(行列指定)関数 void Lcd_Chr_Remote(char row, char column, char out_char) { Lcd_Send_Chr('C'); Lcd_Send_Chr(row); Lcd_Send_Chr(column); Lcd_Send_Chr(out_char); Lcd_Send_Chr(EOF); } //********************************************************************** //■ワイヤレスLCD文字出力(カレント位置)関数 void Lcd_Chr_Cp_Remote(char out_char) { Lcd_Send_Chr('D'); Lcd_Send_Chr(out_char); Lcd_Send_Chr(EOF); } //********************************************************************** //■ワイヤレスLCDコマンド出力関数 void Lcd_Cmd_Remote(char out_char) { Lcd_Send_Chr('E'); Lcd_Send_Chr(out_char); Lcd_Send_Chr(EOF); } //********************************************************************** //■ワイヤレスLCDデータ送信(1文字)関数 void Lcd_Send_Chr(unsigned short dt) { short cnt; //start-bit Pwm1_Start(); Delay_us(833); Pwm1_Stop(); //data-bit(LSB.....MSB) for (cnt = 0; cnt < 8; cnt++) { if ((dt & 0b00000001) != 0) { Delay_us(833); } else { Pwm1_Start(); Delay_us(833); Pwm1_Stop(); } // dt >>= 1; } //stop-bit Delay_us(833); // Delay_ms(10); } //********************************************************************** //■ワイヤレスLCDデータ送信(文字列)関数 void Lcd_Send_Str(unsigned short* pData) { while (*pData != 0x00) { Lcd_Send_Chr(*pData); pData++; } } //**********************************************************************









