工業製造
産業用モノのインターネット | 工業材料 | 機器のメンテナンスと修理 | 産業プログラミング |
home  MfgRobots >> 工業製造 >  >> Manufacturing Technology >> 製造プロセス

Arduino 2.4インチTFT LCDシールドでSDカードからBMP画像を表示する

部品と用品

Arduino UNO 1

このプロジェクトについて

こんにちは、このチュートリアルはArduino UNO用2.4インチTFT LCDシールドについての前2回の続きです。第1回はインターフェースとタッチ機能の問題修正(反転軸も含む)、第2回は図形描画関数とタッチボタン作成についてでした。

今回はSDカードから画像を読み取り、画面に表示する方法です。まずSDカードをPCに挿し、FAT32でフォーマットしてから画像を転送してください。画像は必ず「BMP」形式、24ビットビットマップにしてください。正しく表示するには解像度を240×320にする必要があります。

Arduino 2.4インチTFT LCDシールドでSDカードからBMP画像を表示する

これは画面の通常の向きで、240×320の画像を表示できます。デフォルトの回転設定は setRotation(0) です。

Arduino 2.4インチTFT LCDシールドでSDカードからBMP画像を表示する

これは setRotation(1) に設定した場合の画面向きで、320×240の画像を表示できます。

どちらでもお好みで選べます。画面の回転を変えるか、PC側で画像を回転させるかです。画像ファイル名を覚えておくかコピーして、SDカードをシールドに挿入してください。

Arduino 2.4インチTFT LCDシールドでSDカードからBMP画像を表示する

これが私のSDカード内の24ビットBMP画像ファイル名です。コード内では「Img1」を「Img1.bmp」として呼び出します。

ライブラリ

私が動作確認できたライブラリです:こちらからダウンロード
このライブラリを使用してもサンプルコードで白画面になる場合は、ご自身の環境に合ったライブラリを探してください。

コード

動画で使用したコードを.ino形式で公開しています。使用するファイル名は適宜変更してください。困ったときはチュートリアルを参照してください。

コード詳細

TFT_Shield_SD_1.ino(基本的な画像表示)

/* 2.4" TFT LCDタッチシールド用
 * SDカードに保存されたBMP画像を読み取り画面に表示
 * 詳細は SurtrTech.com 参照
 */
#include <SPFD5408_Adafruit_GFX.h>    // コアグラフィックライブラリ
#include <SPFD5408_Adafruit_TFTLCD.h> // ハードウェア固有ライブラリ
#include <SPI.h>
#include <SD.h>

#define LCD_CS A3
#define LCD_CD A2
#define LCD_WR A1
#define LCD_RD A0
#define SD_CS 10

Adafruit_TFTLCD tft(LCD_CS, LCD_CD, LCD_WR, LCD_RD, A4);

void setup() {
  Serial.begin(9600);
  tft.reset();
  uint16_t identifier = tft.readID();
  pinMode(10, OUTPUT);
  digitalWrite(10, HIGH);
  tft.begin(identifier);
  if (!SD.begin(SD_CS)) {
    progmemPrintln(PSTR("failed!"));
    return;
  }
}

void loop() {
  bmpDraw("Logo.bmp", 0, 0);
  delay(2000);
  bmpDraw("Img2.bmp", 0, 0);
  delay(2000);
  bmpDraw("Img3.bmp", 0, 0);
  delay(2000);
}

#define BUFFPIXEL 20  // 描画速度、20が最適だが60も可能(UNOのRAMを多く消費)

// BMP描画関数 - SDカードからファイルを読み取り変換・描画
// シリアルモニターにエラー時メッセージも表示
// この関数は変更しないでください :D
void bmpDraw(char *filename, int x, int y) {
  File bmpFile;
  int bmpWidth, bmpHeight;
  uint8_t bmpDepth;
  uint32_t bmpImageoffset;
  uint32_t rowSize;
  uint8_t sdbuffer[3*BUFFPIXEL];
  uint16_t lcdbuffer[BUFFPIXEL];
  uint8_t buffidx = sizeof(sdbuffer);
  boolean goodBmp = false;
  boolean flip = true;
  int w, h, row, col;
  uint8_t r, g, b;
  uint32_t pos = 0, startTime = millis();
  uint8_t lcdidx = 0;
  boolean first = true;

  if((x >= tft.width()) || (y >= tft.height())) return;

  Serial.println();
  progmemPrint(PSTR("Loading image '"));
  Serial.print(filename);
  Serial.println('\'');

  if ((bmpFile = SD.open(filename)) == NULL) {
    progmemPrintln(PSTR("File not found"));
    return;
  }

  if(read16(bmpFile) == 0x4D42) { // BMPシグネチャ
    progmemPrint(PSTR("File size: "));
    Serial.println(read32(bmpFile));
    (void)read32(bmpFile);
    bmpImageoffset = read32(bmpFile);
    progmemPrint(PSTR("Image Offset: "));
    Serial.println(bmpImageoffset, DEC);
    progmemPrint(PSTR("Header size: "));
    Serial.println(read32(bmpFile));
    bmpWidth = read32(bmpFile);
    bmpHeight = read32(bmpFile);

    if(read16(bmpFile) == 1) { // プレーン数=1
      bmpDepth = read16(bmpFile);
      progmemPrint(PSTR("Bit Depth: "));
      Serial.println(bmpDepth);

      if((bmpDepth == 24) && (read32(bmpFile) == 0)) { // 非圧縮24ビット
        goodBmp = true;
        progmemPrint(PSTR("Image size: "));
        Serial.print(bmpWidth);
        Serial.print('x');
        Serial.println(bmpHeight);

        rowSize = (bmpWidth * 3 + 3) & ~3;

        if(bmpHeight < 0) {
          bmpHeight = -bmpHeight;
          flip = false;
        }

        w = bmpWidth;
        h = bmpHeight;
        if((x+w-1) >= tft.width()) w = tft.width() - x;
        if((y+h-1) >= tft.height()) h = tft.height() - y;

        tft.setAddrWindow(x, y, x+w-1, y+h-1);

        for (row=0; row= sizeof(sdbuffer)) {
              if(lcdidx > 0) {
                tft.pushColors(lcdbuffer, lcdidx, first);
                lcdidx = 0;
                first = false;
              }
              bmpFile.read(sdbuffer, sizeof(sdbuffer));
              buffidx = 0;
            }
            b = sdbuffer[buffidx++];
            g = sdbuffer[buffidx++];
            r = sdbuffer[buffidx++];
            lcdbuffer[lcdidx++] = tft.color565(r,g,b);
          }
        }

        if(lcdidx > 0) {
          tft.pushColors(lcdbuffer, lcdidx, first);
        }
        progmemPrint(PSTR("Loaded in "));
        Serial.print(millis() - startTime);
        Serial.println(" ms");
      }
    }
  }
  bmpFile.close();
  if(!goodBmp) progmemPrintln(PSTR("BMP format not recognized."));
}

// 以下、ヘルパー関数群
uint16_t read16(File f) {
  uint16_t result;
  ((uint8_t *)&result)[0] = f.read();
  ((uint8_t *)&result)[1] = f.read();
  return result;
}

uint32_t read32(File f) {
  uint32_t result;
  ((uint8_t *)&result)[0] = f.read();
  ((uint8_t *)&result)[1] = f.read();
  ((uint8_t *)&result)[2] = f.read();
  ((uint8_t *)&result)[3] = f.read();
  return result;
}

void progmemPrint(const char *str) {
  char c;
  while(c = pgm_read_byte(str++)) Serial.print(c);
}

void progmemPrintln(const char *str) {
  progmemPrint(str);
  Serial.println();
}

TFT_Shield_SD_2.ino(タッチ操作で画像切り替えスライドショー)

/* 2.4" TFT LCDタッチシールド + UNO用
 * 画面を押した位置に応じて画像が切り替わるスライドショー
 * 画像はSDカードから読み取り
 * 詳細は SurtrTech.com 参照
 */
#include <SPFD5408_Adafruit_GFX.h>
#include <SPFD5408_Adafruit_TFTLCD.h>
#include <SPI.h>
#include <SD.h>
#include <SPFD5408_TouchScreen.h>

#if defined(__SAM3X8E__)
#undef __FlashStringHelper::F(string_literal)
#define F(string_literal) string_literal
#endif

// シールドに合わせてピンを確認してください
#define YP A3
#define XM A2
#define YM 9
#define XP 8

// タッチ機能が動かない場合は上記の値を確認(A1 A2 7 6 の可能性も)
// キャリブレーション値 - まずキャリブレーションコードを実行して設定
#define TS_MINX 176
#define TS_MINY 159
#define TS_MAXX 921
#define TS_MAXY 884
#define MINPRESSURE 10
#define MAXPRESSURE 1000

TouchScreen ts = TouchScreen(XP, YP, XM, YM, 300);

#define LCD_CS A3
#define LCD_CD A2
#define LCD_WR A1
#define LCD_RD A0
#define SD_CS 10

Adafruit_TFTLCD tft(LCD_CS, LCD_CD, LCD_WR, LCD_RD, A4);

char x[] = "x1.bmp"; // ファイル名を配列で宣言し、数字部分を操作して画像切り替え

void setup() {
  Serial.begin(9600);
  tft.reset();
  uint16_t identifier = tft.readID();
  pinMode(10, OUTPUT);
  digitalWrite(10, HIGH);
  tft.begin(identifier);
  if (!SD.begin(SD_CS)) {
    progmemPrintln(PSTR("failed!"));
    return;
  }
  tft.setRotation(1);
  bmpDraw(x, 0, 0);
}

void loop() {
  if(x[1] < 49) x[1] = 49;
  if(x[1] > 52) x[1] = 52; // '1'=49, '4'=52

  TSPoint p = ts.getPoint();
  pinMode(XM, OUTPUT);
  pinMode(YP, OUTPUT);

  if (p.z > MINPRESSURE && p.z < MAXPRESSURE) {
    p.x = map(p.x, TS_MINX, TS_MAXX, 0, tft.width());
    p.y = map(p.y, TS_MINY, TS_MAXY, 0, tft.height());

    // setRotation(1)なのでY軸で左右判定
    if(p.y > 0 && p.y < 100) {
      Serial.println("Left");
      x[1] = x[1] - 1;
      bmpDraw(x, 0, 0);
      delay(300);
    }
    else if(p.y > 200 && p.y < 320) {
      Serial.println("Right");
      x[1] = x[1] + 1;
      bmpDraw(x, 0, 0);
      delay(300);
    }
  }
}

// bmpDraw関数はコード1と同じため省略

回路図

シールドタイプなので配線はシンプルです :D
Arduino 2.4インチTFT LCDシールドでSDカードからBMP画像を表示する

製造プロセス

  1. グリーティングカード産業:歴史、製造、未来トレンド
  2. クレジットカード:歴史・設計・製造・未来トレンド
  3. 液晶ディスプレイ(LCD):技術、製造、将来展望
  4. Primal Display:Raspberry Pi LCD温度モニターの構築
  5. Kuman 3.5インチTFTディスプレイをRetroPieにインストールするステップバイステップガイド
  6. ILI9341 2.4インチTFTタッチシールドでのビットマップアニメーション実装ガイド
  7. Arduino LCDプロジェクト: 16x2ディスプレイとプッシュボタンで作るサッカーゲーム
  8. テキストレシピから料理画像を生成するAI、Stacked GANで写実的な成果
  9. DATA MODUL、スマートWi-Fi制御搭載23.1インチ超薄型TFTディスプレイを発表
  10. Distec、Ortustechの7インチ トランスフェクティブ TFTディスプレイを発表:堅牢、屋外視認性、低消費電力
  11. Nuvo-7160GC:6 TFLOPS、120W GPU対応、4K出力の堅牢GPU-PC─マシン ビジョン、VR、オートメーション向け