RaspberryPiからaitendoのLCD[C128X64SPI-12P]への画像表示
文字はうまくいったので今回は「あの」方法を使って4階調の画像を表示します。それは、白と黒を目に見えない速さで高速で切り替える、という方法です。
用意するもの
- RaspberryPi
- 液晶モジュール
- ソフトウェア
- gcc (Debian 4.6.3-12+rpi1) 4.6.3 (デフォルトではいってるはず)
- wiringPi (インストール方法はwiringPiを使ってC言語でGPIOからLEDを点滅させる)
- 画像データ (当記事参照)
- プログラムファイル (当記事参照)
- 1ms、1μsを縮ようとする気概
プログラム
lcd_pict.c
#include <wiringPi.h> #include <wiringPiSPI.h> #include <stdio.h> #include <iconv.h> #include <string.h> #include <stdlib.h> #define LCD_SDA 12 // GPIO 10 #define LCD_SCL 14 // GPIO 11 #define LCD_A0 6 // GPIO 25 #define LCD_CS 10 // GPIO 8 #define PAGE_SEL 0xB0 // (3) #define COL_SEL 0x10 // (4) unsigned char imagedata[8192] = {0}; // 128*64 void glcd_write_data(unsigned char dat) { digitalWrite(LCD_A0, 1); // 1ならデータ。0ならコマンド。 // unsigned char datr = ~dat; // 白黒反転 wiringPiSPIDataRW(0, &dat, 1); } // コマンドを出力する void glcd_write_cmd(unsigned char cmd) { digitalWrite(LCD_A0, 0); // 1ならデータ。0ならコマンド。 wiringPiSPIDataRW(0, &cmd, 1); } void glcd_init(void) { //RST = 0; delay(10); //RST = 1; glcd_write_cmd(0xE2); // (14) S/W RESWT glcd_write_cmd(0xA3); // (11) LCD bias(1/7) //glcd_write_cmd(0xAF); // (1) Display ON glcd_write_cmd(0xA0); // (8) segment direction.(normal direction) glcd_write_cmd(0xC8); // (15) Common Direction.(normal direction) glcd_write_cmd(0x22); // (17) Regultion resistor select(0x010) //25 glcd_write_cmd(0x81); // (18) EV Select. glcd_write_cmd(0x2f); // (18) Select EV value.(0x101111) glcd_write_cmd(0x2f); // (16) Power control(VB,VR,VF全部1) glcd_write_cmd(0x40); // (2) Initial display line(0に設定, MAX63) glcd_write_cmd(0xB0); // (3) Set page address(Y=0に設定, MAX15) glcd_write_cmd(0x10); // (4) Set coloumn addr MSB glcd_write_cmd(0x00); // (4) Set coloumn addr LSB(X=0に設定, MAX255) //glcd_write_cmd(0xAF); // (1) Display ON glcd_write_cmd(0xA4); // (10) all pixel ON(normal display) glcd_write_cmd(0xA6); // (9) Inverse Display(normal display) glcd_write_cmd(0xAF); // (1) Display ON } // 座標のセット void glcd_set_axis(int x, int page) { int col; // Selecting Page (3) glcd_write_cmd(PAGE_SEL | page); // Selecting Column col = (x & 0xF0) >> 4; // 上位ビット glcd_write_cmd(COL_SEL | col); // glcd_write_cmd(x & 0x0f); // 下位ビット } void glcd_clear() { int i,j; for (j = 0; j < 8; j++) { glcd_set_axis(0, j); for (i = 0; i < 128; i++) glcd_write_data(0x00); } } int init_picture() { // ▼画像ファイルオープン FILE *fp; fp = fopen( "mono.dat", "rb" ); if( fp == NULL ) { printf( "mono.dat が開けません\n" ); return -1; } fread( imagedata, sizeof( unsigned char ), 128*64, fp ); fclose(fp); } void show_picture(int time) { int colmun, page, dot; unsigned char buf; for (page = 0; page < 8; page++) { glcd_set_axis(0, page); for (colmun = 0; colmun < 128; colmun++) { buf = 0; for (dot = 0; dot < 8; dot++) { if (imagedata[page*128*8+colmun*8+dot] <= time) buf++; if (dot != 7) buf = buf << 1; } glcd_write_data(buf); } } } int main() { // 初期化 if (wiringPiSetup() == -1) { printf("wiringPiのセットアップに失敗しました。\n"); return 1; } int initv = wiringPiSPISetup(0, 10000000); printf("initv=%d\n", initv); if (initv < 0) { printf("wiringPiSPIのセットアップに失敗しました。\n"); return 1; } pinMode(LCD_A0, OUTPUT); glcd_init(); printf("init ok\n"); // ▼ここからメイン glcd_clear(); init_picture(); int i=0; while(1) { show_picture(i); i++; if (i>2) i=0; // delay(1000); } return 0; }
必要ファイル
画像のデータです。結果に表示されているような4階調のデータです。普通にプログラムの中で階調数を指定できるようにしておけば良かったです。
mono.dat
実行・出力例
gcc lcd_pict.c -o lcd_pict -I/usr/local/include -L/usr/local/lib -lwiringPi ./lcd_pict
静止画だとそれなりに見えてるんですけど、実際にはちらつきがひどくて実用的ではありません。4分の1の面積くらいですとちゃんと見えるので、Raspberry Piの速度の問題のようです。
とりあえず-O3くらいは入れてみますかね・・・。