esp8266の多くのプロジェクトでは、タッチスクリーン付きのTFTスクリーンを使用しています。 プロジェクトによっては、インターフェイスは単純な場合があります。たとえば、アプリケーションのログを表示するテキストコンソールや、入力信号を変更するためのスケジュールだけです。 また、いくつかの画面では、いくつかの画面、グラフィックボタン、テキスト入力行、さらには仮想キーボードを備えた複雑なGUI
この記事では、タッチスクリーン付きの画面をesp8266に接続し、Arduino環境でグラフィカルインターフェースを実装する方法に関する私の経験を共有したいと思います。
ビデオティーザー:
それでは始めましょう
最初の部分、ハードウェア
画面モデルの選択
現在、aliexpressで読むと、TFTスクリーンの膨大な数のモデルが販売されています-異なるサイズ、異なる解像度、タッチスクリーンの有無にかかわらず。
TFTスクリーンは接続方法が異なります-SPIバスを介して接続するスクリーンと、パラレルバスを介して接続するスクリーンがあります。
最小、SPIバス経由で接続するには、4つの信号出力(GPIO)のみが必要で、パラレルバス経由で接続するには、最低10(タッチスクリーンコントローラーは含まれません)。 パラレルバスを介した接続は、高速で、 1クロックサイクルで8ビットの情報が一度に送信され、SPIの場合は1ビットのみです。
ただし、SPI接続にはもう1つの利点があります。関与するピンが少なくなります。 esp8266では、必要なピンの数が決定的な要因です。空きGPIOの数は限られています。
SPIインターフェースを備えた最も人気のあるTFTスクリーンモジュールを選びます。
TFTスクリーンをesp8266に接続します。
ほとんどのSPI画面は類似したハードウェアインターフェイスを備えているため、同じ方法でプロセッサに接続され、名前の小さな違いに対して正確です。 以下のネームプレートには、調査結果のリストと、それらの意味の説明が含まれています。
おわりに | 別名 | esp8266への接続 | 予定 |
---|---|---|---|
SCLK | SCK、SCL | GPIO14 | SPIバスクロッキング |
SDA | MOSI | GPIO13 | プロセッサからスクリーンへのSPIデータ転送 |
CS | SS | GPIO5 | チップ選択(複数のデバイスをSPIバスに接続可能) |
A0 | RS、D / C | GPIO15 | データ/コマンド転送モードの選択 |
リセット | Rst | Vcc | ハードウェアリセット |
SDO | 味iso | - | 画面からプロセッサへのデータ転送(オプション) |
LED + | LED | Vcc | バックライトオン |
Vss | Vcc | Vcc | スクリーン電源、+ 3.3V |
GND | GND | 地球 |
RESET
およびLED+
結論は、+ 3.3ボルトの電源バスに接続できますが、必要に応じてGPIO esp8266に接続でき、画面のリセットとバックライトをプログラムで制御できます。
CS
およびA0
ピンは、便利なGPIO esp8266に接続できます。
最も重要な部分は、 SCLK
およびSDA
結果です。 これらは、SPIバスでデータを送信する責任があります。 SPI esp8266コントローラーの対応するピンに接続する必要があります。 これらはそれぞれGPIO14
とGPIO13
です。
画面にタッチスクリーンコントローラーがある場合は、SPIバスにも接続する必要があります。
おわりに | esp8266への接続 | 予定 |
---|---|---|
T_CLK | GPIO14 | SPIバスクロッキング |
T_DIN | GPIO13 | プロセッサからタッチスクリーンコントローラーへのSPIデータ転送 |
T_CS | GPIO16 | チップ選択(複数のデバイスをSPIバスに接続可能) |
T_DO | GPIO12 | コントローラーからプロセッサーへのデータ転送 |
T_IRQ | GPIO4 | タッチスクリーンタッチサイン |
esp8266 GPIO14
およびGPIO13
の出力は、画面とタッチスクリーンコントローラーに並列に接続されていることに注意してください。 実際、複数のデバイスをSPIバスに接続できます。 デバイスを選択するには、必要なデバイスのCS
出力で論理レベル0
を設定します。
ili9341画面をesp8266に接続するスキーム
パート2、ソフトウェア
画面と接続図を決定しました。今度はソフトウェアの部分に進みます。 まず、GUIを実装するグラフィックライブラリを選択します。
数十のライブラリを試した後、 uGFXライブラリを選択しました。 私の意見では、これはマイクロコントローラー用の最高のグラフィックライブラリーの一つです。 豊富な機能がモジュール性と組み合わされ、必要なコンポーネントのみがプロジェクトに含まれます。 このライブラリはオープンソースであり、非営利的な使用は無料です。 ライブラリには、プロジェクトのWebサイトで入手可能な品質のドキュメントがあります。
uGFXライブラリの大きな利点は、utf8をサポートする開発されたフォントレンダリングエンジンです。 キットには、キリル文字を含むttfファイルからフォントを生成するためのプログラムが含まれています。
ライブラリはクロスプラットフォームです-これは、アプリケーションのGUI部分をesp8266を含む任意のプロセッサ向けにアセンブルできることを意味します。
スクリーンドライバーとタッチスクリーンドライバーは専用モジュールに接続されており、必要なドライバーが含まれていない場合は、個別に実装できます。
さらに、uGFXにはuGFX studio(WYSWIGインターフェイスエディター)が付属しています。このエディターでは、インターフェイスのレイアウトを視覚的に準備でき、uGFX studioは自動的にコードを生成し、リソースを分解します。 残念ながら、現在uGFXスタジオはまだベータ版の状態にあります。ベータ版を入手するには、フォーラムで開発者に連絡する必要があります。
そして、ケーキの最後のチェリー:アプリケーションのGUIコードは、デスクトップ(Linux / Windows / OSX)の下でアセンブルし、コンピューター上でインターフェースがどのように見えるかを直接確認できます。
uGFXをプロジェクトに接続します
ライブラリはビルドシステムを使用しますが、Arduinoビルドシステムではサポートされていません。 ただし、この制限は回避できます。 この記事を参考にしてください
以下のテキストは、esp8266をサポートするArduino開発環境がすでにインストールおよび構成されていることを前提としています。 まだインストールされていない場合は、環境のインストールと構成については、 ギークタイムに関するこの記事を参照してください。
ライブラリを接続する手順:
- Arduino環境からLibrariesフォルダーを見つけます。 プラットフォームに応じて、次のような場所に配置できます。
-
OSX
/Users/<username>/Documents/Arduino/libraries/
-
Windows
-C:\Users\<username>\My Documents\Arduino\Libraries
-
Linux
/home/<username>/Documents/Arduino/libraries
uGFXをライブラリフォルダーに複製またはコピーします。 ここからダウンロードできます-すでにキリル文字フォントが組み込まれているバージョンです。
- 画面およびタッチスクリーンドライバーのI / O実装を含むラッパーライブラリを作成し、必要なuGFXコンポーネントをアセンブリに接続します。 これを行うには、LibrariesフォルダーにサブフォルダーuGFXespを作成する必要があります。およそ次の内容が含まれます。
uGFXesp ├── library.properties └── src ├── board_ILI9341.cpp ├── board_ILI9341.h ├── gdisp_lld_config.h ├── gdisp_lld_ili9341.c ├── gfxconf.h ├── gfxlib.c ├── gmouse_lld_ADS7843.c ├── gmouse_lld_ADS7843_board.cpp └── gmouse_lld_ADS7843_board.h
- library.propertiesファイルは、Arduino環境のライブラリの説明です。
name=uGFXesp version=1.0.0 author=Oleg V. Gerasimov <ogerasimov@gmail.com> maintainer=Oleg V. Gerasimov <ogerasimov@gmail.com> sentence=UI features of esp paragraph=This library add support screen and touch panel of esp board<br />Requires uGFX library<br /> category=Display architectures=esp8266 includes=gfx.h url=http://github.com
- ファイル
gdisp_lld_ili9341.c
、gmouse_lld_ADS7843.c
、gdisp_lld_config.h
タッチスクリーンコントローラーおよびスクリーンドライバーアセンブリへの接続。 -
gfxlib.c
ファイル-ライブラリ自体のアセンブリへの接続 -
gfxconf.h
ファイル-uGFXライブラリが構築される構成-その中で、必要な機能を有効/無効にすることができます - Board_ILI9341.cppファイル-スクリーンドライバーのSPI I / O実装。 これについて詳しく説明します。これは、グラフィックライブラリとesp8266を統合する上で最も重要な部分です。
#include <Arduino.h> #include <SPI.h> extern "C" { #include "user_interface.h" } // Pin, RS #define ESP_LCD_RS 15 // Pin, CS #define ESP_LCD_CS 5 // SPI : 1/ #define SPILOWSPEED 1000000 // SPI : 32/ #define SPIHIGHSPEED 32000000 static SPISettings spiSettings(SPILOWSPEED, MSBFIRST, SPI_MODE0); // static inline void cmdmode() { digitalWrite(ESP_LCD_RS, 0); } // static inline void datamode() { digitalWrite(ESP_LCD_RS, 1); } // extern "C" void esp_lcd_init_board(void) { SPI.begin(); pinMode(ESP_LCD_CS, OUTPUT); digitalWrite(ESP_LCD_CS, 1); pinMode(ESP_LCD_RS, OUTPUT); datamode(); } // - - SPI extern "C" void esp_lcd_post_init_board(void) { spiSettings = SPISettings(SPIHIGHSPEED, MSBFIRST, SPI_MODE0); } static int aquire_count = 0; // SPI: 0 CS SPI extern "C" void esp_lcd_aquirebus(void) { if (!aquire_count++) { SPI.beginTransaction(spiSettings); digitalWrite(ESP_LCD_CS, 0); } } // SPI: 1 CS SPI extern "C" void esp_lcd_releasebus(void) { if (aquire_count && !--aquire_count) { digitalWrite(ESP_LCD_CS, 1); SPI.endTransaction(); } } // extern "C" void esp_lcd_write_index(uint16_t cmd) { cmdmode(); SPI.write(cmd); datamode(); } // extern "C" void esp_lcd_write_data(uint16_t data) { SPI.write(data); }
- gmouse_lld_ADS7843_board.cppファイルは、スクリーンドライバーのSPI I / O実装です。 さらに詳しく説明します。
#include <Arduino.h> #include <SPI.h> extern "C" { #include "user_interface.h" } // Pin, TC_IRQ #define ESP_TC_IRQ 4 // Pin, CS #define ESP_TC_CS 16 // SPI 2/ #define SPISPEED 2000000 static SPISettings spiSettings(SPISPEED, MSBFIRST, SPI_MODE0); // extern "C" int esp_gmouse_init_board() { pinMode(ESP_TC_CS, OUTPUT); digitalWrite(ESP_TC_CS, 1); pinMode(ESP_TC_IRQ, INPUT); return 1; } // TC_IRQ ( ) extern "C" int esp_getpin_pressed() { // watch dog, esp8266 system_soft_wdt_feed (); // return digitalRead (ESP_TC_IRQ)==0; } static int aquire_count = 0; // SPI: 0 CS SPI extern "C" void esp_aquire_bus() { if (!aquire_count++) { SPI.beginTransaction(spiSettings); digitalWrite(ESP_TC_CS, 0); } } // SPI: 1 CS SPI extern "C" void esp_release_bus() { if (aquire_count && !--aquire_count) { digitalWrite(ESP_TC_CS, 1); SPI.endTransaction(); } } // extern "C" uint16_t esp_read_value(uint16_t port) { SPI.write (port); return SPI.transfer16(0); }
実際、準備作業は終わりました。 ソースファイルのセットはgithubにあります
これで準備が完了しました。美しく便利なGUIでプログラムまたはスケッチの開発を始めましょう。
GUIを使用したスケッチの開発
前の記事で 、現代のクリスマスツリー用の「スマート」延長コードについて書いた。 スケッチGUIは2つの画面で構成されています
- クリスマスの背景
- オン/オフボタンライト付きの画面:
以下は、このプロジェクトのGUIによって実装されたコードのスニペットです。
// GHandle ghContainerMain; // GHandle ghButton1,ghButton2,ghButton3,ghButton4,ghButtonAll,ghButtonVoice,ghButtonTree; // gdispImage ballImg,bearImg,candleImg,microphoneImg,treeImg,bigTreeImg,lightsImg; // GListener glistener; // extern "C" void gwinButtonDraw_ImageText(GWidgetObject *gw, void *param);
void guiCreate(void) { gfxInit(); // "" geventListenerInit(&glistener); geventAttachSource(&glistener, ginputGetKeyboard(0), 0); gwinAttachListener(&glistener); // GUI gwinSetDefaultFont(gdispOpenFont("DejaVuSans16")); gwinSetDefaultStyle(&WhiteWidgetStyle, FALSE); gwinSetDefaultColor(HTML2COLOR(0x000000)); gwinSetDefaultBgColor(HTML2COLOR(0xFFFFFF)); // , SPIFFs gdispImageOpenFile(&ballImg, "ball.bmp"); gdispImageOpenFile(&bearImg, "bear.bmp"); gdispImageOpenFile(&candleImg, "candle.bmp"); gdispImageOpenFile(µphoneImg, "music.bmp"); gdispImageOpenFile(&treeImg, "tree.bmp"); gdispImageOpenFile(&lightsImg, "lights.bmp"); gdispImageOpenFile(&bigTreeImg, "bigtree.bmp"); // GUI GWidgetInit wi; gwinWidgetClearInit(&wi); wi.gx = 0; wi.gy = 0; wi.g.width = 176; wi.g.height = 220; wi.g.show = TRUE; ghContainerMain = gwinContainerCreate(0, &wi, 0); wi.g.parent = ghContainerMain; wi.customDraw = gwinButtonDraw_ImageText; wi.customStyle = 0; wi.customParam = &bigTreeImg; wi.gx = 0; wi.gy = 0; wi.text = ""; ghButtonTree = gwinButtonCreate(0, &wi); wi.g.show = FALSE; wi.customParam = &ballImg; wi.g.width = 88; wi.g.height = 73; wi.text = ""; ghButton1 = gwinButtonCreate(0, &wi); wi.customParam = &candleImg; wi.gx = 88; wi.gy = 0; wi.text = ""; ghButton2 = gwinButtonCreate(0, &wi); wi.customParam = &bearImg; wi.gx = 0; wi.gy = 73; wi.text = ""; ghButton3 = gwinButtonCreate(0, &wi); wi.customParam = &lightsImg; wi.gx = 88; wi.gy = 73; wi.text = ""; ghButton4 = gwinButtonCreate(0, &wi); wi.customParam = &treeImg; wi.gx = 0; wi.gy = 146; wi.text = ""; ghButtonAll = gwinButtonCreate(0, &wi); wi.customParam = µphoneImg; wi.gx = 88; wi.gy = 146; wi.text = ""; ghButtonVoice = gwinButtonCreate(0, &wi); }
static bool screenSaver = false; // void switchScreen (bool flag) { gwinSetVisible (ghButton1,flag); gwinSetVisible (ghButton2,flag); gwinSetVisible (ghButton3,flag); gwinSetVisible (ghButton4,flag); gwinSetVisible (ghButtonAll,flag); gwinSetVisible (ghButtonVoice,flag); gwinSetVisible (ghButtonTree,!flag); screenSaver = !flag; } static unsigned long timeLastActivity =0; void loop() { unsigned long now = millis(); // GEvent* pe = geventEventWait(&glistener, 2); if (pe && pe->type == GEVENT_GWIN_BUTTON) { GEventGWinButton *we = (GEventGWinButton *)pe; if (we->gwin == ghButton1) {/* */} if (we->gwin == ghButton2) {/* */} if (we->gwin == ghButton3) {/* */} if (we->gwin == ghButton4) {/* */} if (we->gwin == ghButtonAll) {/* */}; if (we->gwin == ghButtonVoice) {/* */}; if (we->gwin == ghButtonTree) {switchScreen (true); startRecognize();} timeLastActivity = now; } // 10 , if (!screenSaver && now - timeLastActivity > 10000) { switchScreen (false); } delay (10); }
その結果、合理的な数のコード行により、本格的で、私の好みにとっては美しいGUIが得られます。 githubでスケッチの完全版
その他の使用例
シンプルなオシロスコープ
Githubソース: スケッチ自体
テトリス
Githubソース: テトリス
全体として、この記事では、オープンソースで利用可能なライブラリを使用して、便利で美しいGUIソリューションを作成しました。