先の投稿「8bitパラレルTFTのタッチ機能が使えました」の後、”STM32F411(BlackPill)” に移植した結果を報告します。
今回の構成です。
1.STM32F411(BlackPill)
2.3.95" TFT LCD Shield,ILI9488 480x320 8bitParallel,4線式抵抗TouchScreen(と思われる)
3.Arduino IDE 2.3.2
4.TFT_eSPIライブラリ
5.ST-LINK V2(あった方が断然楽)
まずは、ピンの接続だけをBlackPill用に変更してみました。が勿論うまくゆくはずもなく...。でも初期画面表示は出来てタッチ機能も働いているようです。しかし、それに応じての新たな表示が出来ません。タッチする場所により画面の乱れ方も違います。ヒントは無いかと
libraries\Adafruit_TouchScreen\TouchScreen.cpp
を眺めていると、"readTouchX" や "readTouchY" で "pinMode" が変更されていました。ひょっとしたらと、".getTouch()" のあと、表示をさせる前に "pinMode(*,OUTOUT)" を入れてみたところ、動作しました。
void tftOutput() {
pinMode(XP, OUTPUT);
pinMode(XM, OUTPUT);
pinMode(YP, OUTPUT);
pinMode(YM, OUTPUT);
}
Arduino IDE のTools の設定は次のようにしました。
TFT_eSPI ライブラリで必要とされる "User_Setup.h" は以下です。
(なお、"User_Select_Setup.h" の中身は不要なので全行をコメント化しておきます。)
User_Setup.h
#define USER_SETUP_INFO "User_Setup"
#define STM32
#define STM_PORTB_DATA_BUS
#define TFT_PARALLEL_8_BIT
#define ILI9488_DRIVER
#define TFT_PARALLEL_8_BIT
#define TFT_CNTRL_PORT GPIOA
#define TFT_DATA_PORT GPIOB
#define TFT_DATA_SHIFT 0 // take the lower bits/pins 0..7
// The ESP32 and TFT the pins used for testing are:
#define TFT_RST PA0 // Reset pin, toggles on startup
#define TFT_CS PA1 // Chip select control pin (library pulls permanently low
#define TFT_DC PA2 // Data Command control pin - must use a pin in the range 0-31
#define TFT_WR PA3 // Write strobe control pin - must use a pin in the range 0-31
#define TFT_RD PA4 // Read strobe control pin
#define TFT_D0 PB0 // Must use pins in the range 0-31 for the data bus
#define TFT_D1 PB1 // so a single register write sets/clears all bits.
#define TFT_D2 PB2 // Pins can be randomly assigned, this does not affect
#define TFT_D3 PB3 // TFT screen update performance.
#define TFT_D4 PB4
#define TFT_D5 PB5
#define TFT_D6 PB6
#define TFT_D7 PB7
#define LOAD_GLCD // Font 1. Original Adafruit 8 pixel font needs ~1820 bytes in FLASH
#define LOAD_FONT2 // Font 2. Small 16 pixel high font, needs ~3534 bytes in FLASH, 96 characters
#define LOAD_FONT4 // Font 4. Medium 26 pixel high font, needs ~5848 bytes in FLASH, 96 characters
#define LOAD_FONT6 // Font 6. Large 48 pixel font, needs ~2666 bytes in FLASH, only characters 1234567890:-.apm
#define LOAD_FONT7 // Font 7. 7 segment 48 pixel font, needs ~2438 bytes in FLASH, only characters 1234567890:-.
#define LOAD_FONT8 // Font 8. Large 75 pixel font needs ~3256 bytes in FLASH, only characters 1234567890:-.
//#define LOAD_FONT8N // Font 8. Alternative to Font 8 above, slightly narrower, so 3 digits fit a 160 pixel TFT
#define LOAD_GFXFF // FreeFonts. Include access to the 48 Adafruit_GFX free fonts FF1 to FF48 and custom fonts
#define SMOOTH_FONT
#define SPI_FREQUENCY 55000000 // STM32 SPI1 only (SPI2 maximum is 27MHz)
// #define SPI_FREQUENCY 80000000
// Optional reduced SPI frequency for reading TFT
#define SPI_READ_FREQUENCY 20000000
// The XPT2046 requires a lower SPI clock rate of 2.5MHz so we define that here:
#define SPI_TOUCH_FREQUENCY 2500000
次にino本体を示します。
F411_8Para_TFTeSPI_Calc.ino
#include <TFT_eSPI.h>
#include "User_Setup.h" // User_Setup_Select.h 内の全ての行はコメント化
#include <TouchScreen.h>
#define BLACK 0x0000 /* 5 6 5 */
#define WHITE 0xFFFF /* ???? ? ??? ??? ? ???? */
#define RED 0xF800 /* 1111 1 000 000 0 0000 */
#define PINK 0xF81F /* 1111 1 000 000 1 1111 */
#define YELLOW 0xFFE0 /* 1111 1 111 111 0 0000 */
#define GREEN 0x07E0 /* 0000 0 111 111 0 0000 */
#define CYAN 0x07FF /* 0000 0 111 111 1 1111 */
#define BLUE 0x001F /* 0000 0 000 000 1 1111 */
//#define TFT_D0 PB0
//#define TFT_D1 PB1
//#define TFT_CS PA1
//#define TFT_DC PA2
#define XP PB0 // D0 8 can be a digital pin at UNO
#define YP PB1 // D1 9 can be a digital pin at UNO
#define XM PA2 // DC=RS A2 must be an analog pin, use "An" notation!
#define YM PA1 // CS A3 must be an analog pin, use "An" notation!
TFT_eSPI tft = TFT_eSPI();
/*
* @brief Construct a new Touch Screen object
*
* @param xp X+ pin. Must be an analog pin
* @param yp Y+ pin. Must be an analog pin
* @param xm X- pin. Can be a digital pin
* @param ym Y- pin. Can be a digital pin
* @param rx The resistance in ohms between X+ & X- to calibrate pressure
* sensing
*/
TouchScreen ts = TouchScreen(XP, YP, XM, YM, 613);
// 613 ohms at mine. 300 is the default sensitivity
String symbol[4][4] = {
{ "7", "8", "9", "/" },
{ "4", "5", "6", "*" },
{ "1", "2", "3", "-" },
{ "C", "0", "=", "+" }
};
int16_t X, Y, Z;
int32_t Num1, Num2, Number;
char action;
boolean result = false;
void tftOutput() {
pinMode(XP, OUTPUT);
pinMode(XM, OUTPUT);
pinMode(YP, OUTPUT);
pinMode(YM, OUTPUT);
}
void setup(void) {
Serial.begin(115200); // CDC. generic Serial
tft.init();
tft.setRotation(2);
tft.fillScreen(WHITE);
draw_BoxNButtons();
Number = Num1 = Num2 = 0;
}
void loop() {
TSPoint p = ts.getPoint();
X = map(p.x, 1023, 0, 0, tft.width()); // mapping for setRotation(2)
Y = map(p.y, 1023, 0, 0, tft.height());
Z = p.z;
if (Z > 0 && X > 0 && Y > 0 && X < 320 && Y < 480) {
/*
Serial.print("X=");
Serial.print(X);
Serial.print(",Y=");
Serial.print(Y);
Serial.print(",Z=");
Serial.println(Z);
*/
tftOutput(); // Set the pins Output mode for displaying
DetectButtons(X, Y);
if (result == true) // '=' key pressed
CalculateResult();
DisplayResult();
}
delay(200);
}
void DetectButtons(int X, int Y) {
// Detecting Buttons on Column 0 ---------------------------------
tft.setTextColor(BLACK);
tft.setTextSize(3);
if (X > 0 && X < 50) {
if (Y > 269 && Y < 300) { //If cancel Button is pressed
Serial.println('C');
Number = Num1 = Num2 = 0;
tft.fillRect(220, 0, 20, 60, CYAN);
tft.drawChar('C', 220, 2);
result = false;
delay(400);
tft.fillRect(220, 0, 20, 30, CYAN);
}
if (Y > 210 && Y < 260) { //If Button 1 is pressed
Serial.println('1');
if (Number == 0) Number = 1;
else Number = (Number * 10) + 1; //Pressed twice
}
if (Y > 160 && Y < 205) { //If Button 4 is pressed
Serial.println('4');
if (Number == 0) Number = 4;
else Number = (Number * 10) + 4; //Pressed twice
}
if (Y > 108 && Y < 156) { //If Button 7 is pressed
Serial.println('7');
if (Number == 0) Number = 7;
else Number = (Number * 10) + 7; //Pressed twice
}
}
// Detecting Buttons on Column 1 --------------------------------
if (X > 55 && X < 100) {
if (Y > 269 && Y < 300) {
Serial.println('0'); //Button 0 is Pressed
if (Number == 0) Number = 0;
else Number = (Number * 10) + 0; //Pressed twice
}
if (Y > 214 && Y < 256) {
Serial.println('2');
if (Number == 0) Number = 2;
else Number = (Number * 10) + 2; //Pressed twice
}
if (Y > 160 && Y < 205) {
Serial.println('5');
if (Number == 0) Number = 5;
else Number = (Number * 10) + 5; //Pressed twic
}
if (Y > 108 && Y < 156) {
Serial.println('8');
if (Number == 0) Number = 8;
else Number = (Number * 10) + 8; //Pressed twic
}
}
// Detecting Buttons on Column 2 ----------------------------------
if (X > 115 && X < 175) {
if (Y > 269 && Y < 300) {
Serial.println('=');
Num2 = Number;
result = true;
tft.drawChar('=', 220, 30);
}
if (Y > 210 && Y < 256) {
Serial.println('3');
if (Number == 0) Number = 3;
else Number = (Number * 10) + 3; //Pressed twice
}
if (Y > 160 && Y < 205) {
Serial.println('6');
if (Number == 0) Number = 6;
else Number = (Number * 10) + 6; //Pressed twice
}
if (Y > 108 && Y < 156) {
Serial.println('9');
if (Number == 0) Number = 9;
else Number = (Number * 10) + 9; //Pressed twice
}
}
// Detecting Buttons on Column 3 --------------------------------------
if (X > 182 && X < 236) {
Num1 = Number;
Number = 0;
tft.fillRect(220, 0, 20, 30, CYAN);
tft.setCursor(220, 2);
if (Y > 108 && Y < 156) {
Serial.println('/');
action = 4;
tft.println('/');
}
if (Y > 160 && Y < 205) {
Serial.println('*');
action = 3;
tft.println('*');
}
if (Y > 214 && Y < 256) {
Serial.println('-');
action = 2;
tft.println('-');
}
if (Y > 269 && Y < 300) {
Serial.println('+');
action = 1;
tft.println('+');
}
}
delay(100);
}
void CalculateResult() {
if (action == 1)
Number = Num1 + Num2;
if (action == 2)
Number = Num1 - Num2;
if (action == 3)
Number = Num1 * Num2;
if (action == 4)
Number = Num1 / Num2;
}
void DisplayResult() {
Serial.println(Number);
tft.fillRect(30, 30, 180, 50, CYAN);
tft.setTextColor(BLACK);
tft.drawNumber(Number, 30, 30);
}
void draw_BoxNButtons() {
//Draw the Result Box
tft.fillRect(0, 0, 240, 80, CYAN);
//Draw Column 0
tft.fillRect(0, 260, 60, 60, RED);
tft.fillRect(0, 200, 60, 60, BLACK);
tft.fillRect(0, 140, 60, 60, BLACK);
tft.fillRect(0, 80, 60, 60, BLACK);
//Draw Column 2
tft.fillRect(120, 260, 60, 60, GREEN);
tft.fillRect(120, 200, 60, 60, BLACK);
tft.fillRect(120, 140, 60, 60, BLACK);
tft.fillRect(120, 80, 60, 60, BLACK);
//Draw Column 1,3
for (int b = 260; b >= 80; b -= 60) {
tft.fillRect(180, b, 60, 60, BLUE);
tft.fillRect(60, b, 60, 60, BLACK);
}
//Draw Horizontal Lines
for (int h = 80; h <= 320; h += 60)
tft.drawFastHLine(0, h, 240, WHITE);
//Draw Vertical Lines
for (int v = 0; v <= 240; v += 60)
tft.drawFastVLine(v, 80, 240, WHITE);
//Display keypad lables
tft.setTextSize(4);
tft.setTextColor(WHITE);
for (int j = 0; j < 4; j++) {
for (int i = 0; i < 4; i++) {
tft.setCursor(20 + (60 * i), 96 + (60 * j));
tft.println(symbol[j][i]);
}
}
tft.setTextSize(3);
tft.setTextColor(BLACK);
tft.drawNumber(Number, 30, 30);
}
前回よりかなりシンプルになっていますが、これで動作しました。最後まで見ていただきありがとうございました。