ArduinoMEGA用のスケッチができたので、メモしておきます。
【追記】漢字ROM判断や縦横切替、スクロールなどの機能追加
実際の表示例は、こんな風になります。
追加ライブラリ:
Adafruit_TFTLCD
Adafruit_GFX
fontx TFTKanji
fontR ここ・漢字ROM無しなら、SD内のフォントfileを使う
追加フォント:
VMNL12.lzh http://homepage3.nifty.com/silo/FONTV/
漢字ROM スイッチサイエンス
入力データ中の特殊コード:
\n 改行
\a この行をSDへ追加保存
\c 色を変更する(次が0~7)
\d 保存ファイル削除
\f 表示データを保存ファイルからとする
\s スクリーンクリア
\1~4 倍角表示
\6~9 画面回転(0~3)、0,2はスクロールモード
// IMPORTANT: Adafruit_TFTLCD LIBRARY MUST BE SPECIFICALLY // CONFIGURED FOR EITHER THE TFT SHIELD OR THE BREAKOUT BOARD. // SEE RELEVANT COMMENTS IN Adafruit_TFTLCD.h FOR SETUP. //Technical support:goodtft@163.com // SDカード用ライブラリ #include <SD.h> #include <SPI.h> // FONTライブラリ #include <fontR.h> #include <fontx.h> // 漢字パターン格納用 unsigned char matrixdata32[32]; //16×16用表示データ unsigned char matrixdata16[16]; //16× 8用表示データ int s; //a font memory size #include <Adafruit_GFX.h> // Core graphics library #include <Adafruit_TFTLCD.h> // Hardware-specific library // The control pins for the LCD can be assigned to any digital or // analog pins...but we'll use the analog pins as this allows us to // double up the pins with the touch screen (see the TFT paint example). #define LCD_CS A3 // Chip Select goes to Analog 3 #define LCD_CD A2 // Command/Data goes to Analog 2 #define LCD_WR A1 // LCD Write goes to Analog 1 #define LCD_RD A0 // LCD Read goes to Analog 0 #define LCD_RESET A4 // Can alternately just connect to Arduino's reset pin // Assign human-readable names to some common 16-bit color values: #define BLACK 0x0000 #define BLUE 0x001F #define RED 0xF800 #define GREEN 0x07E0 #define CYAN 0x07FF #define MAGENTA 0xF81F #define YELLOW 0xFFE0 #define WHITE 0xFFFF Adafruit_TFTLCD tft(LCD_CS, LCD_CD, LCD_WR, LCD_RD, LCD_RESET); // If using the shield, all control and data lines are fixed, and // a simpler declaration can optionally be used: // Adafruit_TFTLCD tft; int16_t x = 0; int16_t y = 0; File dispF; uint8_t size = 2, xsize = size, yf = 0, ROM = 1; uint16_t color = WHITE, bg = BLUE; uint16_t palette[8] = {BLACK,BLUE,RED,GREEN,CYAN,MAGENTA,YELLOW,WHITE}; char input[12] = "dispMsg.txt"; void setup(void) { // ROMの初期化 53,51,50,52 // Unoでは、10,11,12,13 pinMode (SS, OUTPUT); Serial.begin(115200); /*SPI通信の設定*/ SPI.begin (); SPI.setBitOrder(MSBFIRST); SPI.setDataMode(3); SPI.setClockDivider(SPI_CLOCK_DIV16); Serial.println(F("TFT LCD Kanji test")); readFontASCII(0x70, 260048); if (matrixdata16[8]==0) { ROM = 0; Serial.println(F("SD Font is used")); } Serial.println(F("Using Adafruit 3.5\" TFT Mega Board Pinout")); Serial.print("TFT size is "); Serial.print(tft.width()); Serial.print("x"); Serial.println(tft.height()); tft.reset(); uint16_t identifier = tft.readID(); if (identifier == 0x9481) { Serial.println(F("Found ILI9481 LCD driver")); } else { Serial.print(F("Unknown LCD driver chip: ")); Serial.println(identifier, HEX); return; } // SDカードの初期化 35,51,50,52 if (!SD.begin(35)) { // Unoでは、 9,11,12,13 Serial.println(F("SD card error !")); return; } tft.begin(identifier); tft.setRotation(3); tft.fillScreen(BLUE); tft.setCursor(0, 0); // 準備ができたら「準備完了!」と送信。 // ArduinoIDEはShift_JISなのでエスケープ文字をつけて文字コードを送信する。 Serial.print("Arduino,\x8F\x80 \x94\xF5 \x8A\xAE \x97\xB9 \x81\x49\n"); // if (SD.exists(input)) dispF = SD.open(input); } void loop(void) { int ix=16, iy=16, p=32, ixb; // 文字コード格納用 static unsigned int kanji; // 受信データが届くまで待つ if (!dispF) while (!Serial.available()); else if (!dispF.available()) { dispF.close(); return; } // 文字コードを検知して1バイト文字なら1バイトだけ抜き出し、 // 2バイト文字なら2バイトをくっつける if (dispF) kanji = (unsigned int)dispF.read() << 8; else kanji = (unsigned int)Serial.read() << 8; if ((kanji >= 0x8000 && kanji <= 0xA000) || kanji >= 0xE000) { if (!dispF) { while (!Serial.available()); kanji |= Serial.read(); } else kanji |= dispF.read(); xsize = size; // 全角ピッチ // パターン取得 if (ROM) showSJIS2byte(kanji) ; // sendDotsToSerial32(); } else { // 半角 kanji >>= 8; if (kanji == 0x5C) { int peek,c; if (!dispF) { while (!Serial.available()); peek = Serial.peek(); } else peek = dispF.read(); if (peek == 0x6E) { // \n 改行 if (!dispF) { Serial.read(); } x = 1000; // 強制改行 return; } else if (peek== 0x61) { // \a ファイル追記 Serial.println("File creation and addition"); Serial.read(); dispF = SD.open(input, FILE_WRITE); while(Serial.available()) dispF.write(Serial.read()); dispF.close(); return; } else if (peek== 0x63) { // \c 色変更 if (!dispF) { Serial.read(); while (!Serial.available()); c = Serial.read(); } else c=dispF.read(); color = palette[c-0x30]; return; } else if (peek== 0x64) { // \d ファイル削除 Serial.println("File remove"); dispF.close(); SD.remove(input);Serial.read(); return; } else if ((peek == 0x66) || (peek == 0x73)) { // \f ファイル読込 \s クリア tft.fillScreen(BLUE); x=0;y=0;yf=0; tft.setScroll(tft.height()); if (peek==0x66) dispF = SD.open(input); Serial.read(); return; } else if ((peek >= 0x31) & (peek <= 0x34)) { // \w 倍角 size = peek-0x30; xsize = size; // 全角ピッチ Serial.read(); return; } else if ((peek >= 0x36) & (peek <= 0x39)) { // \r Rotate tft.setRotation(peek-0x36); tft.setScroll(tft.height()); Serial.read(); return; } else { char othercode[20]; sprintf(othercode,"Another code=%2x",Serial.peek()); Serial.println(othercode); } } // kanji = AsciiZen(kanji); xsize = 8; // 半角ピッチ // パターン取得 if (ROM) showSJIS1byte(kanji) ; } if (ROM==0){ unsigned long p = KanjiReadX(kanji, matrixdata32) ; // 1バイトに満たない場合は穴埋めされるので // それに合わせて穴埋めする。 ix = (p >> 24) & 0xff; ixb = (ix+7)>>3; // 戻り値からフォントサイズのみ抜き出す。 iy = (p >> 16) & 0xff; s = p & 0xffff; // char st[16]; // sprintf(st, "%d,%d,size=%d\n", ix, iy, s); // Serial.println(st); // sendDotsToSerial32(); } if (x > tft.width() - ix * size) { // Clip right x = 0; y = (y > tft.height()-(iy*size+2)*2)? 0:y+iy*size + 2; if (yf || (y==0)) { if (yf==0) {yf = 1;} int rotate = tft.getRotation(); if (rotate==0) tft.scroll(tft.height()-y-(iy*size+2)); if (rotate==2) tft.scroll(y+(iy*size+2)); tft.fillRect(0, y, tft.width(), iy*size+2, bg); } } // 表示用ループ。 if (ROM) { for (int i = 0; i < 8; i++) { char byteDigit = (1 << i); if (xsize<8) for (int b = 0; b < ix; b++) { // 全角をp/iy行分分散で描く tft.fillRect(x + b*size, y+i*size, size, size, (matrixdata32[b] & byteDigit)? color:bg); tft.fillRect(x + b*size, y+(8+i)*size, size, size, (matrixdata32[b+ix] & byteDigit)? color:bg); } else for (int b = 0; b < ix/2; b++) { // 半角をp/iy行分分散で描く tft.fillRect(x + b*size, y+i*size, size, size, (matrixdata16[b] & byteDigit)? color:bg); tft.fillRect(x + b*size, y+(8+i)*size, size, size, (matrixdata16[b+ix/2] & byteDigit)? color:bg); }} x += (xsize<8)? ix * size: ix/2*size; } else { // SD font int z = 0,ys = 0; // Serial.println(s); // Serial.println(ixb); while (z < s) { for (int i = 0; i < 8; i++) tft.fillRect(x + i*size, y+ys, size, size, (matrixdata32[z] & (1 << (7-i)))? color:bg); x += 8*size; if (!(++z % ixb)) { ys += size; x -= ixb*8*size; } } x += ix * size; } } /*シリアルモニタへ16*16のデータを表示する void sendDotsToSerial32() { for (int i = 0; i < 8; i++) { char byteDigit = (1 << i); for (int b = 0; b < 16; b++) Serial.write((matrixdata32[b] & byteDigit)? "XX":"--"); Serial.println(); } for (int i = 0; i < 8; i++) { char byteDigit = (1 << i); for (int b = 16; b < 32; b++) Serial.write((matrixdata32[b] & byteDigit)? "XX":"--"); Serial.println(); } Serial.println(); } //sendDataToSerial32 */
AdafruitTFTLCDライブラリに、ILI9481のrotation実行とスクロール機能を追加しました。
1)void Adafruit_TFTLCD::setRotation関数
2)void Adafruit_TFTLCD::drawPixel関数
3)void Adafruit_TFTLCD::setScroll関数
4)void Adafruit_TFTLCD::scroll関数
Arduino Nanoでも無事動いたが、メモリーがギリギリだぁ~。

漢字ROM内の全角oがOとしてデザインされているバグがあり、次で迂回した。
fontx.h fontR.h を変更点を含め、メモしておきます。
πDuinoという開発キットで、IDEがShift_JISでなくUTF8だったため、次のように拡張しました。