「サインスマート 1.8″ LCDをArduinoに表示させる」で サインスマート 1.8″ LCDをArduinoで表示させましたが、今度は、Raspberry PI 3で表示させます。
参考にさせてもらったサイトは、「Raspberry Pi 2でカラーグラフィック液晶の制御」です。
Raspberry PI 3とサインスマート 1.8インチ LCDの接続
Raspberry PI 3とサインスマート 1.8″ LCDは次のように接続します。今回プログラムで使用するwiringPiでの割り当てポートも示します。
Raspberry PI | LCD | WiringPi |
---|---|---|
GPIO 11 (SCLK) | SCL | |
GPIO 10 (MOSI) | SDA | |
GPIO 8 (CE0) | CS | 10 |
GPIO 24 | RS/DC | 5 |
GPIO 25 | RES | 6 |
5V Power | VCC | |
Ground | GND |
実際に接続した図を次に示します。
Raspberry PI 3のSPIの設定
Raspberry Piで「raspi-config」コマンドを使って次のようにSPIを設定します。
- rootで「raspi-config」 コマンドをを起動します
$ sudo raspi-config
- 9 Advanced Options を選択します
- A5 SPI を選択します
※2017/02/05 SPIの使用設定の不可
「raspi-config」コマンドで、次のようにSPIの設定ができないようになってしまいました。「7 Advanced Options」になっています。
「7 Advanced Options」を選択します。SPIの項目がありません。
仕方がないので、次のように手動で変更し、SPIを使用可能にしました。
sudo vi /boot/config.txt
次の構文を最後に追加します。
dtparam=spi=on
再起動後、「ls」コマンドにより、次の内容を確認します。
$ ls -l /dev/spidev* crw-rw---- 1 root spi 153, 0 Oct 10 18:47 /dev/spidev0.0 crw-rw---- 1 root spi 153, 1 Oct 10 18:47 /dev/spidev0.1
サインスマート 1.8″ LCDのプログラムの作成
Raspberry PIで、Cライブラリ「WiringPi」を用いて、サインスマート 1.8″ LCDを表示させました。SPIインタフェースについては、Raspberry PI 3のデバイスとしてデータを送信しました。WiringPiのインストール方法は、「Raspberry PIでRTC-8564NBの時計プログラムの作成」に示します。
作成したプログラムの説明を次に示します。
- 52-55行目で、SPIデバイスの初期化を行います。
- 74-81行目で、LCDの表示をブランクアウトしています。
- 84-91行目で、160ドットを画面野中央のトップからボトムに表示するデータを作成しています。10ドットごとに色を変えています。
- 96-99行目で、4kバイト単位にSIPデバイスに送信し、LCDに表示しています。
#include <stdint.h> #include <unistd.h> #include <stdio.h> #include <stdarg.h> #include <stdlib.h> #include <getopt.h> #include <fcntl.h> #include <sys/ioctl.h> #include <linux/types.h> #include <linux/spi/spidev.h> #include <wiringPi.h> #define RSpin 5 // レジスタ選択ピン指定 #define REpin 6 // リセット信号ピン指定 #define LCD_BF 4096 // 1度に転送するデータ数(最大4096) static uint8_t SPIMode = 0,SPIbit=8; //SPIモード0 bit数8 static uint32_t SPISpeed =60000000; // 32MHz // SPIデバイス定義 // # ls -l /dev/spidev* で確認できる。 // Pi2の場合CE1に接続した場合は0.0 // CE2に接続した場合は0.1 だった。 static char *SPIDevice = "/dev/spidev0.0"; int fd,ret=0; int LCD_Cmd(unsigned char,int,...); void SetDot(int x, int y, int color); unsigned char BMPData[0xf000/LCD_BF][LCD_BF]; int main(int argc,char *argv[]){ // wiringPi初期化 if(wiringPiSetup()==-1) printf("wiringPi error\n"); // wiringPi初期化エラー // ピンの初期化 pinMode(RSpin,OUTPUT); pinMode(REpin,OUTPUT); // 液晶リセット信号送信 digitalWrite(REpin,0); delay(100); digitalWrite(REpin,1); delay(100); // SPIデバイスの初期化 fd = open(SPIDevice,O_RDWR);if(fd<0) printf("SPI Device error\n"); //SPI デバイス初期化エラー ret = ioctl(fd,SPI_IOC_WR_MODE,&SPIMode);if(ret <0) printf("SPI Mode error\n"); //SPI Mode設定エラー ret =ioctl(fd,SPI_IOC_WR_BITS_PER_WORD,&SPIbit);if(ret <0) printf("SPI bit/Word error\n");//SPI bit/Word設定エラー ret =ioctl(fd,SPI_IOC_WR_MAX_SPEED_HZ,&SPISpeed);if(ret <0) printf("SPI Speed error\n"); //SPI Speed設定エラー LCD_init(); // 液晶描画方向設定 LCD_Cmd(0x36,1,0xC0); // 縦長 0x48 横長0x28 // 描画エリア設定 0~BMPのサイズ LCD_Cmd(0x2A,4,0x00,0x00,0x00,128); LCD_Cmd(0x2B,4,0x00,0x00,0x00,160); LCD_Cmd(0x3A,1,0x06); //色深度設定 16bit=0x05 18bit=0x06 // 表示RAM転送モードに設定 CmdSend(0x2C); int i,k, x, y; long color; for(i=0; i<0xf000/LCD_BF ;i+=1) { for(k=0; k<LCD_BF; k+=1) { BMPData[i][k] = 0x00; } DataSend(LCD_BF,BMPData[i]); } for(x=0; x<128 ;x++) { if(x!=64) continue; for(y=0; y<160 ;y++) { if((y%10) == 0) color = 0xff0000; else color = 0xff; SetDot( x, y , color); } } for(i=0; i<0xf000/LCD_BF ;i+=1) { DataSend(LCD_BF,BMPData[i]); } close(fd); // SPIデバイス開放 return 0; } void SetDot(int x, int y, int color) { int pos = (x+(y*128))*3; BMPData[pos/LCD_BF][(pos%LCD_BF)] = (color & 0xff0000)>>16; BMPData[pos/LCD_BF][(pos%LCD_BF)+1] = (color & 0xff00)>>8; BMPData[pos/LCD_BF][(pos%LCD_BF)+2] = color & 0xff; } // LCDへのコマンド転送 // LCD_Cmd(コマンド,設定値サイズ(Byte),設定値(カンマ区切り)); int LCD_Cmd(unsigned char TrCmd,int TrByte, ...){ int dti=0; unsigned char TrData[TrByte]; va_list dt; va_start(dt,TrByte); for(dti=0;dti<TrByte;dti++)TrData[dti]=va_arg(dt,int); va_end(dt); CmdSend(TrCmd); if(TrByte > 0)DataSend(TrByte,TrData); } // LCDへのデータ転送 // TrByte=転送データサイズ // TrData=転送するデータ // 8bit値 うまく転送できない場合はchar型の変数を渡すとうまくいく。 int DataSend(int TrByte,unsigned char TrData[]){ digitalWrite(RSpin,1); // RS信号切替 uint8_t ReData[TrByte];//受信用変数 // 転送するデータの準備 struct spi_ioc_transfer tr={ .tx_buf =(unsigned long)TrData, .rx_buf =(unsigned long)ReData, .len = TrByte, .delay_usecs = 1, .speed_hz = SPISpeed, .bits_per_word= SPIbit, }; // 転送 ret =ioctl(fd,SPI_IOC_MESSAGE(1),&tr); if(ret<1)printf("SPI 転送エラー(Data)\n"); int i=0; return ret; // 受信データサイズを返す } // コマンド転送 int CmdSend(unsigned long TrData){ digitalWrite(RSpin,0); // RS信号切替 uint8_t ReData; //受信用変数 // 転送するデータの準備 struct spi_ioc_transfer tr={ .tx_buf =(unsigned long)&TrData, .rx_buf =(unsigned long)&ReData, .len = 1, .delay_usecs = 1, .speed_hz = SPISpeed, .bits_per_word= SPIbit, }; // 転送 ret =ioctl(fd,SPI_IOC_MESSAGE(1),&tr); if(ret<1)printf("SPI 転送エラー(Com)\n"); return ReData; // 受信データを返す } int LCD_init(void){ // 液晶リセット信号送信 digitalWrite(REpin,0); delay(1); digitalWrite(REpin,1); delay(1); //液晶初期化コマンド送信 CmdSend(0x01); // ソフトリセット delay(15); CmdSend(0x11); // スリープ解除 delay(10); // フレームレート設定 LCD_Cmd(0xB1,3,0x01,0x2C,0x2D); LCD_Cmd(0xB2,3,0x01,0x2C,0x2D); LCD_Cmd(0xB3,6,0x01,0x2C,0x2D,0x01,0x2C,0x2D); // 液晶反転設定 LCD_Cmd(0xB4,1,0x07); // 電源設定(PWCTR1~3) LCD_Cmd(0xC0,3,0xA2,0x02,0x84); LCD_Cmd(0xC1,1,0xC5); LCD_Cmd(0xC2,2,0x0A,0x00); LCD_Cmd(0xC3,2,0x8A,0x2A); LCD_Cmd(0xC4,2,0x8A,0xEE); LCD_Cmd(0xC5,1,0x0E); CmdSend(0x20); // ガンマ設定 LCD_Cmd(0xE0,16,0x0F,0x1A,0x0F,0x18,0x2F,0x28,0x20,0x22,0x1F,0x1B,0x23,0x37,0x00,0x07,0x02,0x10); LCD_Cmd(0xE1,16,0x0F,0x1B,0x0F,0x17,0x33,0x2C,0x29,0x2E,0x30,0x30,0x39,0x3F,0x00,0x07,0x03,0x10); CmdSend(0x29); CmdSend(0x13); }
コンパイル・リンクは次のコマンドで実行します。
# gcc -o lcdtest lcdtest.c -lwiringPi
サインスマート 1.8″ LCDのプログラムの実行
作成したプログラムを次のコマンドで実行します。
# sudo ./lcdtest
実行した結果を次に示します。青のドットが一列に表示され、10ドットごとに黄色のドットに変わって表示されています。