2.8 inch TFT タッチスクリーンシールド

TFT 液晶ディスプレイ + タッチスクリーン + microSD のコンボシールドで、5V / 3.3V での駆動及び LEONARDO での動作が可能です。タッチペンもオマケで付いてきます (購入時価格: ¥1,430)。

私の購入したものadafruit 2.8" TFT Touch Shield for Arduino のコピー品だと思われます。

パッケージには、

2.8寸UNO模块
駆动:ILI9341	息线: 8位并口
分辨率: 240X320	触摸: 有

とあります。日本語訳すると、

2.8 インチ UNO モジュール
コントローラ: ILI9341    バス: 8bit パラレル
解像度: 240x320 タッチパネル: 有

といった所でしょうか。以下の記事で使われているものと全く同じと思われます。

この記事の著者は、記事中で実行しているサンプルのソースコードをファイルとして提供しておらず、「動画に流れるソースコードを参考に写経しろ」 というマゾヒストです (写経した人のソースコードはこちら)。

このシールドを使うのに必要なライブラリは以下の3つです。Arduino IDE の libraries フォルダにコピーしてください (zip で取得したのであれば [スケッチ | ライブラリをインクルード | .zip 形式のライブラリをインストール...] からでも OK)。

最初のサンプルスケッチとしては、TFT ライブラリに含まれる graphicstest.pde がいいでしょう。しかしながらこのシールド、そのままサンプルスケッチを動作させても画面が真っ白になってしまうのです。

これは tft.readID() を実行すると ID として 0x0101 が返ってくるのですが、ライブラリがこの ID に対応していないからで、とりあえずの対策は Adafruit_TFTLCD.cpp の一部を書き換える事です。

// Ditto with the read/write port directions, as above.
uint16_t Adafruit_TFTLCD::readID(void) {

  ...

  id = hi; id <<= 8; id |= lo;
  return 0x9341;
}

このようになっている所を

// Ditto with the read/write port directions, as above.
uint16_t Adafruit_TFTLCD::readID(void) {

  ...

  id = hi; id <<= 8; id |= lo;
  if (id == 0x0101)
    return 0x9341;
  else
    return id;
}

こう書き換えるだけです。これだけですべてのサンプルスケッチが正しく動作するようになります。

サンプルスケッチを元に microSD カードから BMP 画像を読み込ませてみました。撮影技術がアレなのでイマイチな写りですが、実際にはそこそこキレイに表示されています。

なお、Amazon で出品者に「サンプルください!」と連絡すると MEGA 経由で K60-2.8inch_Arduino_ILI9341_V3.1.rar というファイルが貰えます。で、この中にも改変された Adafruit_TFTLCD.cpp があるのですが、資料を読んでびっくり。この製品の TFT コントローラは ILI9341 ではなく LGDP4535 なんだだそうです。パッケージやファイル名に ILI9341 とあるのは何だったのか。

このシールドでタッチパネルを使う場合には補正が必要です。ディスプレイの表示領域でのタッチパネルの最小値と最大値を確認してキャリブレーションを行う必要があります。

#include <stdint.h>
#include "TouchScreen.h"
#include <Adafruit_TFTLCD.h>

#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

#define YP A2  // must be an analog pin, use "An" notation!
#define XM A3  // must be an analog pin, use "An" notation!
#define YM 8   // can be a digital pin
#define XP 9   // can be a digital pin

#define TS_MINX 170 // X Min Value (Raw)
#define TS_MAXX 940 // X Max Value (Raw)
#define TS_MINY 170 // Y Min Value (Raw)
#define TS_MAXY 910 // Y Max Value (Raw)

Adafruit_TFTLCD tft(LCD_CS, LCD_CD, LCD_WR, LCD_RD, LCD_RESET);
TouchScreen ts = TouchScreen(XP, YP, XM, YM, 300);

void setup(void) {
  Serial.begin(9600);
}

void loop(void) {
  TSPoint p = ts.getPoint();

  if (p.z > ts.pressureThreshhold) {
     Serial.print("("); 
     Serial.print(adjust_x(p.x)); 
     Serial.print(','); 
     Serial.print(adjust_y(p.y)); 
     Serial.print(")");
     Serial.print("\tX = "); Serial.print(p.x);
     Serial.print("\tY = "); Serial.print(p.y);
     Serial.print("\tPressure = "); Serial.println(p.z);
  }

  delay(100);
}

int adjust_x(int x) {

  int TFT_MAX = tft.width() - 1;
  return constrain(map(x, TS_MINX, TS_MAXX, 0, TFT_MAX), 0, TFT_MAX);

}

int adjust_y(int y) {

  int TFT_MAX = tft.height() - 1;
  return constrain(map(y, TS_MINY, TS_MAXY, 0, TFT_MAX), 0, TFT_MAX);

}

タッチした位置の情報がシリアルモニタに表示されます。(X, Y) の後に表示されている X= / Y= が抵抗膜の X / Y 値です。液晶の白く表示されている部分で X / Y それぞれの最小値と最大値を控えておき、ソースコードの TS_MINX / TS_MINY / TS_MAXX / TS_MAXY の値を書き換えます。再コンパイルして実行すると (X, Y) が TFT 液晶の座標に一致するようになります。

UNO とかだと目的のアプリケーションに (3DS にあるような) キャリブレーション機能を持たせる余裕はないと思うので、補正値をマジックナンバーで書き込むか、microSD 等から設定値を読み込むしかないかもしれません。

See Also:


ここにある情報が役に立って、「調べる手間が省けたからオマイに飯でもおごってやるよ」 というハートウォーミングな方がいらっしゃいましたら、下のボタンからどうぞ。

メニュー: