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関数
if (driver == ID_9481) { uint8_t mode[4] = {0x1A, 0xE8, 0xC9, 0x2B}; writeRegister8(ILI9341_MADCTL, mode[rotation]); // MADCTL }2)void Adafruit_TFTLCD::drawPixel関数
} else if (driver == ID_9481) { fillRect(x, y, 1 ,1, color); }3)void Adafruit_TFTLCD::setScroll関数
void Adafruit_TFTLCD::setScroll(uint16_t pos) { CS_ACTIVE; CD_COMMAND; write8(0x13); delayMicroseconds(10); write8(0x33); CD_DATA; delayMicroseconds(10); write8(0x00); write8(0x00); write8(pos>>8); write8(pos); write8(0x00); write8(0x00); CS_IDLE; }4)void Adafruit_TFTLCD::scroll関数
void Adafruit_TFTLCD::scroll(uint16_t pos) { CS_ACTIVE; CD_COMMAND; write8(0x37); CD_DATA; delayMicroseconds(10); write8(pos>>8); delayMicroseconds(10); write8(pos); CS_IDLE; }Arduino Nanoでも無事動いたが、メモリーがギリギリだぁ~。

漢字ROM内の全角oがOとしてデザインされているバグがあり、次で迂回した。
if (code==0x828F) { // 全角小文字oがROMでOになっている readFontASCII(0x70, 261328); for (int i=0;i<32;i++) matrixdata32[i] = 0; for (int i=0;i<8;i++) { matrixdata32[i+4] = matrixdata16[i]; matrixdata32[i+20] = matrixdata16[i+8]; } } else readFontJIS(c1, c2);fontx.h fontR.h を変更点を含め、メモしておきます。
πDuinoという開発キットで、IDEがShift_JISでなくUTF8だったため、次のように拡張しました。
// 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, convF; uint8_t size = 2, xsize = size, yf = 0, ROM = 1, ROT=0; uint16_t color = WHITE, bg = BLUE; uint16_t palette[8] = {BLACK,BLUE,RED,GREEN,CYAN,MAGENTA,YELLOW,WHITE}; //char input[12] = "dispMsg.txt"; char input[12] = "utf8Msg.txt"; char convT[12] = "UtfSjis.tbl"; void setup(void) { // ROMの初期化 53,51,50,52 // Unoでは、10,11,12,13 pinMode (10, 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 PiDuino 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(10)) { // 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(F("Arduino,\x8F\x80 \x94\xF5 \x8A\xAE \x97\xB9 \x81\x49\n")); // Serial.print("Arduino,準備完了!\n"); if (SD.exists(input)) dispF = SD.open(input); if (SD.exists(convT)) convF = SD.open(convT, FILE_READ); if (!convF) { Serial.print("変換表ファイルがない\n"); return; } } // end of Setup 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(); if (ROT<3) { dispF = SD.open(input); tft.fillScreen(BLUE); tft.setRotation(++ROT); x=0;y=0;yf=0; tft.setScroll(tft.height()); } else Serial.print("\n入力してください\n"); return; } // 文字コードを検知して1バイト文字なら1バイトだけ抜き出し、 // 2バイト文字なら2バイトをくっつける byte utf8[4]; byte sjis[2]; uint32_t sp_addres; int fnt_cnt; if (dispF) utf8[0] = (unsigned char)dispF.read(); else utf8[0] = (unsigned char)Serial.read(); if(utf8[0]<0x80){ //UTF8 1バイト文字の場合 utf8[1] = 0x00; utf8[2] = 0x00; fnt_cnt = 1; } else if(utf8[0]>=0xC2 && utf8[0]<=0xD1){ //UTF8 2バイト文字の場合 if (!dispF) { while (!Serial.available()); utf8[1] = Serial.read(); } else utf8[1] = dispF.read(); xsize = size; // 全角ピッチ utf8[2] = 0x00; fnt_cnt = 2; } else if(utf8[0]>=0xE2 && utf8[0]<=0xEF){ //UTF8 3バイト文字の場合 if (!dispF) { while (!Serial.available()); utf8[1] = Serial.read(); while (!Serial.available()); utf8[2] = Serial.read(); } else { utf8[1] = dispF.read(); utf8[2] = dispF.read(); } xsize = size; // 全角ピッチ fnt_cnt = 3; } else { utf8[1] = 0x00; utf8[2] = 0x00; fnt_cnt = 1; } if(utf8[0]>=0x80){ //半角ASCII文字を判別 UTF8_To_SJIS_cnv(utf8, &sp_addres); //UTF8コードからUTF8→Sjis変換テーブルファイルのアドレスを計算 Flash_UTF8SJIS_Table_Read(sp_addres, sjis); //変換テーブルファイル"Utf8Sjis.tbl"からShift_JISコード取得 kanji = (uint16_t)sjis[0]<<8 | sjis[1]; // パターン取得 // if (ROM) showSJIS2byte(kanji) ; // sendDotsToSerial32(); } else { // 半角 kanji = utf8[0]; 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(); tft.scroll(tft.height()-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; // } } //***********UTF-8コードをSD Memory内の変換テーブルを読み出してShift-JISコードに変換**** void UTF8_To_SJIS_cnv(byte* utf8, uint32_t* spiffs_addrs) { uint32_t UTF8uint = ((uint32_t)utf8[0]<<16) + ((uint32_t)utf8[1]<<8) + utf8[2]; if(utf8[0]>=0xC2 && utf8[0]<=0xD1){ //0xB0からS_JISコード実データ。0x00-0xAFまではライセンス文ヘッダなのでそれをカット。 *spiffs_addrs = ((((uint32_t)utf8[0]<<8) + utf8[1])-0xC2A2)*2 + 0xB0; //文字"¢" UTF8コード C2A2~、S_jisコード8191 }else if(utf8[1]>=0x80){ if(utf8[0]==0xE2){ *spiffs_addrs = (UTF8uint-0xE28090)*2 + 0x1EEC; //文字"‐" UTF8コード E28090~、S_jisコード815D }else if(utf8[0]==0xE3){ *spiffs_addrs = (UTF8uint-0xE38080)*2 + 0x9DCC; //スペース UTF8コード E38080~、S_jisコード8140 }else if(utf8[0]==0xE4){ *spiffs_addrs = (UTF8uint-0xE4B880)*2 + 0x11CCC; //文字"一" UTF8コード E4B880~、S_jisコード88EA }else if(utf8[0]==0xE5){ *spiffs_addrs = (UTF8uint-0xE58085)*2 + 0x12BCC; //文字"倅" UTF8コード E58085~、S_jisコード98E4 }else if(utf8[0]==0xE6){ *spiffs_addrs = (UTF8uint-0xE6808E)*2 + 0x1AAC2; //文字"怎" UTF8コード E6808E~、S_jisコード9C83 }else if(utf8[0]==0xE7){ *spiffs_addrs = (UTF8uint-0xE78081)*2 + 0x229A6; //文字"瀁" UTF8コード E78081~、S_jisコードE066 }else if(utf8[0]==0xE8){ *spiffs_addrs = (UTF8uint-0xE88080)*2 + 0x2A8A4; //文字"耀" UTF8コード E88080~、S_jisコード9773 }else if(utf8[0]==0xE9){ *spiffs_addrs = (UTF8uint-0xE98080)*2 + 0x327A4; //文字"退" UTF8コード E98080~、S_jisコード91DE }else if(utf8[0]>=0xEF && utf8[1]>=0xBC){ *spiffs_addrs = (UTF8uint-0xEFBC81)*2 + 0x3A6A4; //文字"!" UTF8コード EFBC81~、S_jisコード8149 if(utf8[0]==0xEF && utf8[1]==0xBD && utf8[2]==0x9E){ *spiffs_addrs = 0x3A8DE; // "~" UTF8コード EFBD9E、S_jisコード8160 } } } } //***********SDカード内のUTF8Sjis変換テーブル読み込み************* void Flash_UTF8SJIS_Table_Read(uint32_t addrs, byte *buf) { convF.seek(addrs); buf[0] = convF.read(); buf[1] = convF.read(); }