サインスマート 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 3とサインスマート 1.8インチLCDの接続
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とサインスマート 1.8インチ LCDの接続

Raspberry PI 3のSPIの設定

Raspberry Piで「raspi-config」コマンドを使って次のようにSPIを設定します。

  1. rootで「raspi-config」 コマンドをを起動します
    $ sudo raspi-config
  2. 9 Advanced Options を選択します
  3. A5 SPI を選択します

    SPI の選択

    ※2017/02/05 SPIの使用設定の不可

    「raspi-config」コマンドで、次のようにSPIの設定ができないようになってしまいました。「7 Advanced Options」になっています。

    SPIの設定不可

    「7 Advanced Options」を選択します。SPIの項目がありません。

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

サインスマート 1.8