「サインスマート 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ドットごとに黄色のドットに変わって表示されています。



