Это не картинки
Это рисунки сделанные стилусом. Они не требуют ресурса, потому что нигде не хранятся. В плане “рисовалки” достаточно и про мини 168. А вот если нарисованное сохранять, то да!, нужны другие платы.
Ты картинку из #16 стилусом рисовал чтоль? Маньяк…
Не я, дочь попросил. Я так не нарисую. Я могу строго по координатам как в 12 посте (у).
Заменил две библиотеки на три новые.
На уно рисовалки работают, на хардварном спи - нет. На есп32 тест-скетч заработал и на хардварном варианте, но не сильно быстрее чем на софтовом. Адаптация свелась к перенумерации выводов. Думаю с RP2040 будет также. Тачскина библиотека компилируется только с уно. Из-за того что версии библиотек новые с выводом картинки в 150 Кб придётся заново кумекать.
// для ЕСП32
#include <Adafruit_GFX.h> // Библиотека обработчика графики
#include <Adafruit_ILI9341.h> // Программные драйвера для дисплеев ILI9341
#define WIDTH 320
#define HEIGHT 240
#define TFT_CS 5
#define TFT_DC 12
//#define TFT_RST -1 // Пин подключения вывода RESET (ПРИ -1 СОЕДИНЯЕМ С +3,3В)
//#define TFT_MISO 19 // Пин подключения вывода дисплея SDO(MISO)
//#define TFT_MOSI 23 // Пин подключения вывода дисплея SDI(MOSI)
//#define TFT_CLK 18 // Пин подключения вывода дисплея SCK
Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC);
//Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC, TFT_MOSI, TFT_CLK, TFT_RST, TFT_MISO); // Создаем объект дисплея и сообщаем библиотеке распиновку для работы с графикой
void setup() {
tft.begin();
tft.setRotation(1);
}
void loop() {
float scale[6];
for (byte i = 0; i < 6; i++)
scale[i] = (float)rand() / RAND_MAX / 4;
for (int y = 0; y < HEIGHT; y++) {
for (int x = 0; x < WIDTH; x++) {
uint8_t r, g, b;
r = 15.5 + 15.5 * sin(x * scale[0] + sin(y * scale[1]));
g = 31.5 + 31.5 * cos(y * scale[2] + sin(x * scale[3]));
b = 15.5 + 15.5 * sin((x+y) * scale[4] + sin(y * scale[5]));
uint16_t rgb565 = b | (g << 5) | (r << 11);
tft.drawPixel(x, y, rgb565);
}
}
}
по умолчанию какая скорость SPI не вспомню, но настраивается:
#ifdef HARD_SPI
#ifdef WIFI
// SPI для ESP32
// tft.setSPISpeed(20000000); // отдельные экземпляры дисплеев не работают на такой скорости
#else // откорректируйте под конкретный экземпляр
// SPI для RP2040
// tft.setSPISpeed(25000000);
#endif
#endif
у адафруита своя библиотека для работы с тачем
В примерах видел упоминания, не факт что пограммно-аппаратно подойдёт к китайским тачам.
Эта <Adafruit_STMPE610.h> с каким то отдельным модулем. “TouchScreen.h” вот эта ещё мелькает в примерах.
пробовать надо, в крайнем случае TFT_eSPI библиотеку использовать, она многие тачи поддерживает
Тут ещё надо со стратегией определиться. Зачем мне это надо? Рисовалка просто как рисовалка или пульт сенсорный на блютуз для машинки это про мини 168 потянет. Фотоальбом это надо 16Мб пи пико. Можно по блютуз сразу отрисованные пиксели слать на пк и там сохранять нарисованное.
А не проще (и удобнее) рисовать сразу на ПК?
Нет, пк большой и стационарный, а рисовалка маленькая и автономная с толстокожим сенсором
Не, всё срослось быстро. Конечно хотелось бы быстро, но для имитации индикаторов часов пойдёт

//вывод фотокартинок
#include <Adafruit_GFX.h>
#include <Adafruit_ILI9341.h>
#include <SPI.h>
#include "ris_.h"//файл хранения массивов фотокартинок
#define TFT_CS 5
#define TFT_DC 12
//#define TFT_RST -1 // Пин подключения вывода RESET (ПРИ -1 СОЕДИНЯЕМ С +3,3В)
//#define TFT_MISO 19 // Пин подключения вывода дисплея SDO(MISO)
//#define TFT_MOSI 23 // Пин подключения вывода дисплея SDI(MOSI)
//#define TFT_CLK 18 // Пин подключения вывода дисплея SCK
Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC);//
long Y=0;//
void setup() {
//Serial.begin(9600);
tft.begin();
tft.setRotation(2);
tft.fillScreen(tft.color565(0,0,0));
}
void loop() {
drawFoto(0,0,ris_00,240,320);delay(2000);//смена картинок
drawFoto(0,0,ris_11,240,320);delay(2000);//
}
/////////////////////////////////////////////////////////////////
void drawFoto(int x,int y, const uint8_t *bitmap,int w,int h) {//функция вывода фотокартинки
if(x<0||x+w>240||y<0||y+h>320){return;}
tft.setAddrWindow(x,y,x+w-1,y+h-1);
SPI.beginTransaction(SPISettings(40000000, MSBFIRST, SPI_MODE0));
digitalWrite(TFT_DC, HIGH);
digitalWrite(TFT_CS, LOW);
for(int j=0; j<h; j++) {
for(int i=0; i<2*w; i=i+2) {
SPI.transfer(bitmap[i+1+j*2*w]);SPI.transfer(bitmap[i+j*2*w]);
// SPI.transfer(pgm_read_byte(bitmap+i+1+j*2*w));SPI.transfer(pgm_read_byte(bitmap+i+j*2*w));
}
}
digitalWrite(TFT_CS, HIGH);
SPI.endTransaction();
///
}
///////////////////////////////////////////////////////////////
Не ясно почему на уно с Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC);//
не работает.
Догадался почитать что на микросхеме сенсорного экрана написано
Нашёл библиотеку одноимённую:
Стал экспериментировать со схемами по пинам:
экран | vcc | gnd | cs | reset | d/c | mosi | sck | led | miso |
---|---|---|---|---|---|---|---|---|---|
Есп32 | 3.3v | gnd | io 5 | 3.3v | io 12 | io 23 | io 18 | 3.3v | io 19 |
Rp2040 | 3.3v | gnd | 17 | 3.3v | 20 | 19 | 18 | 3.3v | 16 |
тачскрин | T_IRQ | T_DO | T_DIN | T_CS | T_CLK |
---|---|---|---|---|---|
Есп32 | --------- | io19 | io23 | io14 | io18 |
Rp2040 | --------- | 16 | 19 | 14 | 18 |
С есп рисовалки вроде пошли, но потом после замены проводов на длинные всё сломалось - по отделности тач и экран работают, вместе нет. Всё перепробовал, но нет. А с RP2040 запустились.
// ПИКСЕЛЬНАЯ рисовалка 27 цветов
#include "Adafruit_GFX.h" // Библиотека обработчика графики
#include "Adafruit_ILI9341.h" // Программные драйвера для дисплеев ILI9341
#include <XPT2046_Touchscreen.h>// Библиотека для работы с сенсорным экраном
#include <SPI.h>
#define TFT_DC 20 // Пин подключения вывода D/C дисплея
#define TFT_CS 17 // Пин подключения вывода CS дисплея
#define CS_PIN 14
//#define TFT_RST -1 // Пин подключения вывода RESET
//#define TFT_MISO 16 // Пин подключения вывода дисплея SDO(MISO)
//#define TFT_MOSI 19 // Пин подключения вывода дисплея SDI(MOSI)
//#define TFT_CLK 18 // Пин подключения вывода дисплея SCK
//Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC, TFT_MOSI, TFT_CLK, TFT_RST, TFT_MISO); // Создаем объект дисплея и сообщаем библиотеке распиновку для работы с графикой
Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC);//
XPT2046_Touchscreen ts(CS_PIN); // Param 2 - NULL - No interrupts
uint16_t color=tft.color565(0,0,0);
int xx=0;int yy=21;//
byte flag=0;//
void setup(){
tft.begin(); // Инициализируем начало работы с графическим дисплеем
tft.setRotation(1); // Переводим дисплей в альбомную ориентацию
ts.begin();
ts.setRotation(1);
tft.fillScreen(color);panel();//начальная отрисовка зон экрана
}
void loop()
{
int x, y; // Переменные для работы с координатами нажатий
if(ts.touched()) // Пока имеются данные с сенсорного модуля
{
TS_Point p = ts.getPoint(); // Считываем с него данные
x = map(p.x,220,3720,0,319); // Считываем и преобразуем координату нажатия X
y =map(p.y,275,3830,0,240); // Считываем и преобразуем координату нажатия Y
if((x!=-1) && (y!=-1)) // Если обе координаты в положительном диапазоне (т.е. если есть нажатие)
{
x += 0; // Корректируем координату с учетом калибровочных данных
y += 0; // Корректируем координату с учетом калибровочных данных
//
//
if(y<20&&x>290){tft.fillRect(0,21,320,240,color );xx=0,yy=21;flag=0;}//стираем рисунок
if(y>20&&flag==2){tft.drawLine(x, y, xx, yy,color);xx=x;yy=y;}//рисуем отрезок выбранным цветом
if(y>20&&flag==3){xx=x;yy=y;tft.fillCircle(xx, yy,5, color );}//режим стирательной резинки или толстой кисти
if(y<20&&x>0&&x<20){flag=3;}//включаем режим стирательной резинки или толстой кисти
if(y>20&&flag==1){flag=2;xx=x;yy=y;}//начало рисования новой серии отрезков
for(int i=0;i<27;i++){
if(y<20&&x>10*i+15&&x<10*i+25){flag=1;color=tft.color565(min(180*(i%3),255),min(180*((i/3)%3),255),min(180*((i/9)%3),255));tft.fillCircle(10,10,7,color);}//выбираем цвет рисования и отображаем на индикаторе выбранного цвета
}
//
//
}
}
delay(20);//
}
////////////////////
void panel(){
for(int i=0;i<27;i++){
tft.fillRect(10*i+20,0,10,20,tft.color565(min(180*(i%3),255),min(180*((i/3)%3),255),min(180*((i/9)%3),255)));//строка кнопок - отрисовка
}
tft.drawRect(290,0,20, 20,ILI9341_RED );//кнопка стирания рисунка
tft.drawLine(290,0,310, 20,ILI9341_RED );
tft.drawLine(290,20,310, 0,ILI9341_RED );
}
Итого 4 библиотеки ставить пришлось.
для тача скорость SPI надо уменьшать до 1 мегагерца
ЗЫ посмотрел, в библиотеке уменьшают до 2 мегагерц, на ESP обязано работать на SPI0 (SPI)
PPS по пинам для ESP правильно выбрано
static const uint8_t SS = 5;
static const uint8_t MOSI = 23;
static const uint8_t MISO = 19;
static const uint8_t SCK = 18;
Я правильно пониманию, что библиотеки сами устанавливают свои скорости при совместной работе?
я так глубоко библиотеки не копал, по идее то да, а вот в реальности, можно осциллографом посмотреть
На RP2040 можно запустить на SPI1
ts.begin(SPI1); // use SPI1 rather than SPI
Но сходу не взлетело, код такой у меня, пытал на готовом девайсе - сканер WIFI
// ПИКСЕЛЬНАЯ рисовалка 27 цветов
// https://forum.arduino.ru/t/ili9341-i-sensornyj-ekran/12871/32?u=ua6em
#include "Adafruit_GFX.h" // Библиотека обработчика графики
#include "Adafruit_ILI9341.h" // Программные драйвера для дисплеев ILI9341
#include <XPT2046_Touchscreen.h>// Библиотека для работы с сенсорным экраном
#include <SPI.h>
#define TFT_CS 13 // Пин подключения вывода CS дисплея
#define TFT_RST 10 // Пин подключения вывода RST дисплея
#define TFT_DC 11 // Пин подключения вывода D/C дисплея
//#define TFT_MISO 12 // Пин подключения вывода дисплея SDO(MISO)
//#define TFT_MOSI 15 // Пин подключения вывода дисплея SDI(MOSI)
//#define TFT_CLK 14 // Пин подключения вывода дисплея SCK
//Adafruit_ILI9341 tft = Adafruit_ILI9341(&SPI1, TFT_CS, TFT_DC, TFT_RST); //via hard SPI1
// TOUCH
#define CS_PIN 22 // Пин подключения вывода CS тача
#define TIRQ_PIN 27 // Пин подключения вывода TIRQ тача
//Adafruit_ILI9341 tft = Adafruit_ILI9341(&SPI1, TFT_CS, TFT_DC, TFT_RST); //via hard SPI1 так было
Adafruit_ILI9341 tft = Adafruit_ILI9341(&SPI1, TFT_DC, TFT_CS, TFT_RST); // надо так
XPT2046_Touchscreen ts(CS_PIN,TIRQ_PIN); // Param 2 - NULL - No interrupts
//XPT2046_Touchscreen ts(CS_PIN); // Param 2 - NULL - No interrupts
//Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC, TFT_MOSI, TFT_CLK, TFT_RST, TFT_MISO); // Создаем объект дисплея и сообщаем библиотеке распиновку для работы с графикой
//Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC);//
//hard SPI для RP2040
uint16_t color=tft.color565(0,0,0);
int xx=0;int yy=21;//
byte flag=0;//
void setup(){
tft.begin(); // Инициализируем начало работы с графическим дисплеем
tft.setRotation(1); // Переводим дисплей в альбомную ориентацию
//ts.begin(); // SPI0
ts.begin(SPI1); // SPI1
ts.setRotation(1);
tft.fillScreen(color);panel(); //начальная отрисовка зон экрана
}
void loop()
{
int x, y; // Переменные для работы с координатами нажатий
if(ts.touched()) // Пока имеются данные с сенсорного модуля
{
TS_Point p = ts.getPoint(); // Считываем с него данные
x = map(p.x,220,3720,0,319); // Считываем и преобразуем координату нажатия X
y =map(p.y,275,3830,0,240); // Считываем и преобразуем координату нажатия Y
if((x!=-1) && (y!=-1)) // Если обе координаты в положительном диапазоне (т.е. если есть нажатие)
{
x += 0; // Корректируем координату с учетом калибровочных данных
y += 0; // Корректируем координату с учетом калибровочных данных
//
//
if(y<20&&x>290){tft.fillRect(0,21,320,240,color );xx=0,yy=21;flag=0;}//стираем рисунок
if(y>20&&flag==2){tft.drawLine(x, y, xx, yy,color);xx=x;yy=y;}//рисуем отрезок выбранным цветом
if(y>20&&flag==3){xx=x;yy=y;tft.fillCircle(xx, yy,5, color );}//режим стирательной резинки или толстой кисти
if(y<20&&x>0&&x<20){flag=3;}//включаем режим стирательной резинки или толстой кисти
if(y>20&&flag==1){flag=2;xx=x;yy=y;}//начало рисования новой серии отрезков
for(int i=0;i<27;i++){
if(y<20&&x>10*i+15&&x<10*i+25){flag=1;color=tft.color565(min(180*(i%3),255),min(180*((i/3)%3),255),min(180*((i/9)%3),255));tft.fillCircle(10,10,7,color);}//выбираем цвет рисования и отображаем на индикаторе выбранного цвета
}
//
//
}
}
delay(20);//
}
////////////////////
void panel(){
for(int i=0;i<27;i++){
tft.fillRect(10*i+20,0,10,20,tft.color565(min(180*(i%3),255),min(180*((i/3)%3),255),min(180*((i/9)%3),255)));//строка кнопок - отрисовка
}
tft.drawRect(290, 0, 20, 20,ILI9341_RED );//кнопка стирания рисунка
tft.drawLine(290, 0, 310, 20,ILI9341_RED );
tft.drawLine(290, 20,310, 0, ILI9341_RED );
}
ребята из Adafruit большие приколисты, в прошлый раз на эти жеж грабли наступил )))
Adafruit_ILI9341::Adafruit_ILI9341(int8_t cs, int8_t dc, int8_t rst)
: Adafruit_SPITFT(ILI9341_TFTWIDTH, ILI9341_TFTHEIGHT, cs, dc, rst) {}
Adafruit_ILI9341::Adafruit_ILI9341(SPIClass *spiClass, int8_t dc, int8_t cs,
int8_t rst)
: Adafruit_SPITFT(ILI9341_TFTWIDTH, ILI9341_TFTHEIGHT, spiClass, cs, dc,
rst) {}
терзаем вопросом (исходя из поста выше), как поступить правильно? править библиотеки на гитхабе, но тогда возможно придётся править тысячи проектов использующих эту библиотеку и SPI1
Ошибка в перепутывании местами dc и cs ? rst я вообще выкинул из объявлений, физически на 3.3В соединил.
да, это сделано только в этой библиотеке и только для SPI1, для ST7735 всё по фэншую:
class Adafruit_ST7735 : public Adafruit_ST77xx {
public:
Adafruit_ST7735(int8_t cs, int8_t dc, int8_t mosi, int8_t sclk, int8_t rst);
Adafruit_ST7735(int8_t cs, int8_t dc, int8_t rst);
#if !defined(ESP8266)
Adafruit_ST7735(SPIClass *spiClass, int8_t cs, int8_t dc, int8_t rst);
#endif // end !ESP8266
На RP2040 заработало на этом скетче, тач работает через прерывания:
// ПИКСЕЛЬНАЯ рисовалка 27 цветов
// https://forum.arduino.ru/t/ili9341-i-sensornyj-ekran/12871/32?u=ua6em
#include "Adafruit_GFX.h" // Библиотека обработчика графики
#include "Adafruit_ILI9341.h" // Программные драйвера для дисплеев ILI9341
#include <XPT2046_Touchscreen.h>// Библиотека для работы с сенсорным экраном
#include <SPI.h>
uint16_t x_min = 230;
uint16_t x_max = 3930;
uint16_t y_min = 200;
uint16_t y_max = 3830;
#define TFT_CS 13 // Пин подключения вывода CS дисплея
#define TFT_RST 10 // Пин подключения вывода RST дисплея
#define TFT_DC 11 // Пин подключения вывода D/C дисплея
//#define TFT_MISO 12 // Пин подключения вывода дисплея SDO(MISO)
//#define TFT_MOSI 15 // Пин подключения вывода дисплея SDI(MOSI)
//#define TFT_CLK 14 // Пин подключения вывода дисплея SCK
//Adafruit_ILI9341 tft = Adafruit_ILI9341(&SPI1, TFT_CS, TFT_DC, TFT_RST); //via hard SPI1
// TOUCH
#define CS_PIN 22 // Пин подключения вывода CS тача
#define TIRQ_PIN 27 // Пин подключения вывода TIRQ тача
Adafruit_ILI9341 tft = Adafruit_ILI9341(&SPI1, TFT_DC,TFT_CS, TFT_RST); //via hard SPI1
XPT2046_Touchscreen ts(CS_PIN,TIRQ_PIN); // Via interrupts
//XPT2046_Touchscreen ts(CS_PIN); // Param 2 - NULL - No interrupts
//Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC, TFT_MOSI, TFT_CLK, TFT_RST, TFT_MISO); // Создаем объект дисплея и сообщаем библиотеке распиновку для работы с графикой
//Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC);//
//hard SPI для RP2040
uint16_t color=tft.color565(0,0,0);
int xx=0;int yy=21;//
byte flag=0;//
void setup(){
tft.begin(); // Инициализируем начало работы с графическим дисплеем
tft.setRotation(1); // Переводим дисплей в альбомную ориентацию
//ts.begin(); // SPI0
ts.begin(SPI1); // SPI1
ts.setRotation(3);
tft.fillScreen(color);panel(); //начальная отрисовка зон экрана
}
void loop()
{
int x, y; // Переменные для работы с координатами нажатий
if(ts.touched()) // Пока имеются данные с сенсорного модуля
{
TS_Point p = ts.getPoint(); // Считываем с него данные
x = map(p.x,x_min,x_max,0,319); // Считываем и преобразуем координату нажатия X
y = map(p.y,y_min,y_max,0,240); // Считываем и преобразуем координату нажатия Y
if((x!=-1) && (y!=-1)) // Если обе координаты в положительном диапазоне (т.е. если есть нажатие)
{
x += 0; // Корректируем координату с учетом калибровочных данных
y += 0; // Корректируем координату с учетом калибровочных данных
//
//
if(y<20&&x>290){tft.fillRect(0,21,320,240,color );xx=0,yy=21;flag=0;}//стираем рисунок
if(y>20&&flag==2){tft.drawLine(x, y, xx, yy,color);xx=x;yy=y;}//рисуем отрезок выбранным цветом
if(y>20&&flag==3){xx=x;yy=y;tft.fillCircle(xx, yy,5, color );}//режим стирательной резинки или толстой кисти
if(y<20&&x>0&&x<20){flag=3;}//включаем режим стирательной резинки или толстой кисти
if(y>20&&flag==1){flag=2;xx=x;yy=y;}//начало рисования новой серии отрезков
for(int i=0;i<27;i++){
if(y<20&&x>10*i+15&&x<10*i+25){flag=1;color=tft.color565(min(180*(i%3),255),min(180*((i/3)%3),255),min(180*((i/9)%3),255));tft.fillCircle(10,10,7,color);}//выбираем цвет рисования и отображаем на индикаторе выбранного цвета
}
//
//
}
}
delay(20);//
}
////////////////////
void panel(){
for(int i=0;i<27;i++){
tft.fillRect(10*i+20,0,10,20,tft.color565(min(180*(i%3),255),min(180*((i/3)%3),255),min(180*((i/9)%3),255)));//строка кнопок - отрисовка
}
tft.drawRect(290, 0, 20, 20,ILI9341_RED );//кнопка стирания рисунка
tft.drawLine(290, 0, 310, 20,ILI9341_RED );
tft.drawLine(290, 20,310, 0, ILI9341_RED );
}
PS перед первым использованием видимо надо ввести процедуру калибровки тача