st7735 160 на 128 подсветка барахлит
- Войдите на сайт для отправки комментариев
Втр, 09/08/2022 - 19:39
Пришла пара дисплеев таких

С подключением разобрался, скетчи примеров работают, с подсветкой не ясно. При включении внешнего резистора 220 ом экран один тускло, другой никак не горит. Вывод информации сопровождается мерцанием и сбоями картинки у первого. Если включать без резистора всё светит ярко и чётко. Устойчиво, почти, работает при 27 омах. Очень хорошо при питании от аккумулятора всё работает. Почему так происходит? В цепях выводов информационных стоят резисторы по 1,5 кОм. Нахрена они надо?(все ставят зачем то)
:)
Как грамотно управлять светодиодом, или может просто выбраковку прислали?
#include <Adafruit_GFX.h> // Core graphics library
#include <Adafruit_ST7735.h> // Hardware-specific library
#include <SPI.h>
// For the breakout, you can use any 2 or 3 pins
// These pins will also work for the 1.8" TFT shield
#define TFT_CS 10
#define TFT_RST 9 // you can also connect this to the Arduino reset
// in which case, set this #define pin to 0!
#define TFT_DC 8
// Option 1 (recommended): must use the hardware SPI pins
// (for UNO thats sclk = 13 and sid = 11) and pin 10 must be
// an output. This is much faster - also required if you want
// to use the microSD card (see the image drawing example)
Adafruit_ST7735 tft = Adafruit_ST7735(TFT_CS, TFT_DC, TFT_RST);
// Option 2: use any pins but a little slower!
#define TFT_SCLK 13 // set these to be whatever pins you like!
#define TFT_MOSI 11 // set these to be whatever pins you like!
//Adafruit_ST7735 tft = Adafruit_ST7735(TFT_CS, TFT_DC, TFT_MOSI, TFT_SCLK, TFT_RST);
float p = 3.1415926;
void setup(void) {
Serial.begin(9600);
Serial.print("Hello! ST7735 TFT Test");
// Use this initializer if you're using a 1.8" TFT
tft.initR(INITR_BLACKTAB); // initialize a ST7735S chip, black tab
// Use this initializer (uncomment) if you're using a 1.44" TFT
// tft.initR(INITR_144GREENTAB); // initialize a ST7735S chip, black tab
Serial.println("Initialized");
uint16_t time = millis();
tft.fillScreen(ST7735_BLACK);
time = millis() - time;
Serial.println(time, DEC);
delay(500);
// large block of text
tft.fillScreen(ST7735_BLACK);
testdrawtext("Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur adipiscing ante sed nibh tincidunt feugiat. Maecenas enim massa, fringilla sed malesuada et, malesuada sit amet turpis. Sed porttitor neque ut ante pretium vitae malesuada nunc bibendum. Nullam aliquet ultrices massa eu hendrerit. Ut sed nisi lorem. In vestibulum purus a tortor imperdiet posuere. ", ST7735_WHITE);
delay(1000);
// tft print function!
tftPrintTest();
delay(4000);
// a single pixel
tft.drawPixel(tft.width()/2, tft.height()/2, ST7735_GREEN);
delay(500);
// line draw test
testlines(ST7735_YELLOW);
delay(500);
// optimized lines
testfastlines(ST7735_RED, ST7735_BLUE);
delay(500);
testdrawrects(ST7735_GREEN);
delay(500);
testfillrects(ST7735_YELLOW, ST7735_MAGENTA);
delay(500);
tft.fillScreen(ST7735_BLACK);
testfillcircles(10, ST7735_BLUE);
testdrawcircles(10, ST7735_WHITE);
delay(500);
testroundrects();
delay(500);
testtriangles();
delay(500);
mediabuttons();
delay(500);
Serial.println("done");
delay(1000);
}
void loop() {
tft.invertDisplay(true);
delay(500);
tft.invertDisplay(false);
delay(500);
}
void testlines(uint16_t color) {
tft.fillScreen(ST7735_BLACK);
for (int16_t x=0; x < tft.width(); x+=6) {
tft.drawLine(0, 0, x, tft.height()-1, color);
}
for (int16_t y=0; y < tft.height(); y+=6) {
tft.drawLine(0, 0, tft.width()-1, y, color);
}
tft.fillScreen(ST7735_BLACK);
for (int16_t x=0; x < tft.width(); x+=6) {
tft.drawLine(tft.width()-1, 0, x, tft.height()-1, color);
}
for (int16_t y=0; y < tft.height(); y+=6) {
tft.drawLine(tft.width()-1, 0, 0, y, color);
}
tft.fillScreen(ST7735_BLACK);
for (int16_t x=0; x < tft.width(); x+=6) {
tft.drawLine(0, tft.height()-1, x, 0, color);
}
for (int16_t y=0; y < tft.height(); y+=6) {
tft.drawLine(0, tft.height()-1, tft.width()-1, y, color);
}
tft.fillScreen(ST7735_BLACK);
for (int16_t x=0; x < tft.width(); x+=6) {
tft.drawLine(tft.width()-1, tft.height()-1, x, 0, color);
}
for (int16_t y=0; y < tft.height(); y+=6) {
tft.drawLine(tft.width()-1, tft.height()-1, 0, y, color);
}
}
void testdrawtext(char *text, uint16_t color) {
tft.setCursor(0, 0);
tft.setTextColor(color);
tft.setTextWrap(true);
tft.print(text);
}
void testfastlines(uint16_t color1, uint16_t color2) {
tft.fillScreen(ST7735_BLACK);
for (int16_t y=0; y < tft.height(); y+=5) {
tft.drawFastHLine(0, y, tft.width(), color1);
}
for (int16_t x=0; x < tft.width(); x+=5) {
tft.drawFastVLine(x, 0, tft.height(), color2);
}
}
void testdrawrects(uint16_t color) {
tft.fillScreen(ST7735_BLACK);
for (int16_t x=0; x < tft.width(); x+=6) {
tft.drawRect(tft.width()/2 -x/2, tft.height()/2 -x/2 , x, x, color);
}
}
void testfillrects(uint16_t color1, uint16_t color2) {
tft.fillScreen(ST7735_BLACK);
for (int16_t x=tft.width()-1; x > 6; x-=6) {
tft.fillRect(tft.width()/2 -x/2, tft.height()/2 -x/2 , x, x, color1);
tft.drawRect(tft.width()/2 -x/2, tft.height()/2 -x/2 , x, x, color2);
}
}
void testfillcircles(uint8_t radius, uint16_t color) {
for (int16_t x=radius; x < tft.width(); x+=radius*2) {
for (int16_t y=radius; y < tft.height(); y+=radius*2) {
tft.fillCircle(x, y, radius, color);
}
}
}
void testdrawcircles(uint8_t radius, uint16_t color) {
for (int16_t x=0; x < tft.width()+radius; x+=radius*2) {
for (int16_t y=0; y < tft.height()+radius; y+=radius*2) {
tft.drawCircle(x, y, radius, color);
}
}
}
void testtriangles() {
tft.fillScreen(ST7735_BLACK);
int color = 0xF800;
int t;
int w = tft.width()/2;
int x = tft.height()-1;
int y = 0;
int z = tft.width();
for(t = 0 ; t <= 15; t++) {
tft.drawTriangle(w, y, y, x, z, x, color);
x-=4;
y+=4;
z-=4;
color+=100;
}
}
void testroundrects() {
tft.fillScreen(ST7735_BLACK);
int color = 100;
int i;
int t;
for(t = 0 ; t <= 4; t+=1) {
int x = 0;
int y = 0;
int w = tft.width()-2;
int h = tft.height()-2;
for(i = 0 ; i <= 16; i+=1) {
tft.drawRoundRect(x, y, w, h, 5, color);
x+=2;
y+=3;
w-=4;
h-=6;
color+=1100;
}
color+=100;
}
}
void tftPrintTest() {
tft.setTextWrap(false);
tft.fillScreen(ST7735_BLACK);
tft.setCursor(0, 30);
tft.setTextColor(ST7735_RED);
tft.setTextSize(1);
tft.println("Hello World!");
tft.setTextColor(ST7735_YELLOW);
tft.setTextSize(2);
tft.println("Hello World!");
tft.setTextColor(ST7735_GREEN);
tft.setTextSize(3);
tft.println("Hello World!");
tft.setTextColor(ST7735_BLUE);
tft.setTextSize(4);
tft.print(1234.567);
delay(1500);
tft.setCursor(0, 0);
tft.fillScreen(ST7735_BLACK);
tft.setTextColor(ST7735_WHITE);
tft.setTextSize(0);
tft.println("Hello World!");
tft.setTextSize(1);
tft.setTextColor(ST7735_GREEN);
tft.print(p, 6);
tft.println(" Want pi?");
tft.println(" ");
tft.print(8675309, HEX); // print 8,675,309 out in HEX!
tft.println(" Print HEX!");
tft.println(" ");
tft.setTextColor(ST7735_WHITE);
tft.println("Sketch has been");
tft.println("running for: ");
tft.setTextColor(ST7735_MAGENTA);
tft.print(millis() / 1000);
tft.setTextColor(ST7735_WHITE);
tft.print(" seconds.");
}
void mediabuttons() {
// play
tft.fillScreen(ST7735_BLACK);
tft.fillRoundRect(25, 10, 78, 60, 8, ST7735_WHITE);
tft.fillTriangle(42, 20, 42, 60, 90, 40, ST7735_RED);
delay(500);
// pause
tft.fillRoundRect(25, 90, 78, 60, 8, ST7735_WHITE);
tft.fillRoundRect(39, 98, 20, 45, 5, ST7735_GREEN);
tft.fillRoundRect(69, 98, 20, 45, 5, ST7735_GREEN);
delay(500);
// play color
tft.fillTriangle(42, 20, 42, 60, 90, 40, ST7735_BLUE);
delay(50);
// pause color
tft.fillRoundRect(39, 98, 20, 45, 5, ST7735_RED);
tft.fillRoundRect(69, 98, 20, 45, 5, ST7735_RED);
// play color
tft.fillTriangle(42, 20, 42, 60, 90, 40, ST7735_GREEN);
}
/* Arduino TFT text example This example demonstrates how to draw text on the TFT with an Arduino. The Arduino reads the value of an analog sensor attached to pin A0, and writes the value to the LCD screen, updating every quarter second. This example code is in the public domain Created 15 April 2013 by Scott Fitzgerald http://www.arduino.cc/en/Tutorial/TFTDisplayText */ #include <TFT.h> // Arduino LCD library #include <SPI.h> // pin definition for the Uno #define cs 10 #define dc 8 #define rst 9 // pin definition for the Leonardo // #define cs 7 // #define dc 0 // #define rst 1 // create an instance of the library TFT TFTscreen = TFT(cs, dc, rst); // char array to print to the screen char sensorPrintout[5]; void setup() { // Put this line at the beginning of every sketch that uses the GLCD: TFTscreen.begin(); // clear the screen with a black background TFTscreen.background(0, 0, 0); // write the static text to the screen // set the font color to white TFTscreen.stroke(255, 255, 255); // set the font size TFTscreen.setTextSize(2); // write the text to the top left corner of the screen TFTscreen.text("Sensor Value :\n ", 0, 0); // ste the font size very large for the loop TFTscreen.setTextSize(5); } void loop() { // Read the value of the sensor on A0 String sensorVal = String(analogRead(A0)); // convert the reading to a char array sensorVal.toCharArray(sensorPrintout, 5); // set the font color TFTscreen.stroke(255, 255, 255); // print the sensor value TFTscreen.text(sensorPrintout, 0, 20); // wait for a moment delay(250); // erase the text you just wrote TFTscreen.stroke(0, 0, 0); TFTscreen.text(sensorPrintout, 0, 20); }
Неясно почему верхние схемы преобладают над нижними?
1. 220 Ом для подсветки, очевидно, слишком много. Разумный диапазон 10-47 Ом.
2. Я так и не смог установить соответствия между распиновкой в нулевом сообщении и схемами в первом.
3. Самое главное, непонятно, куда именно Вы включаете резистор - ни на одной схеме его нет. Судя по тому, что нарушается работа дисплея, Вы ставите его неправильно.
4. Резисторы в цепях управления, очевидно, связаны с тем, что дисплей 3.3-вольтовый.
*. Вспомнил, что 47 Ом - это я ставил на монохромный дисплей. Для цветного, очевидно, ток должен быть втрое выше, т.е. номинал вряд ли должен превышать 20 Ом.
andriano диод подсветки один, так что номинал резистора +- одинаковый для цветного и монохромного.
ТС ШИМ подайте туда и регулируйте яркость как хотите.
andriano диод подсветки один, так что номинал резистора +- одинаковый для цветного и монохромного.
ТС ШИМ подайте туда и регулируйте яркость как хотите.
Убедительно.
2. Я так и не смог установить соответствия между распиновкой в нулевом сообщении и схемами в первом.
4. Резисторы в цепях управления, очевидно, связаны с тем, что дисплей 3.3-вольтовый.
Как всегда одни вопросы. А дисплей очень такой доступный, всего 130 рублей.
#include <TFT.h> // Arduino LCD library #include <SPI.h> // pin definition for the Uno #define cs 10 #define dc 8 #define rst 9 // create an instance of the library TFT TFTscreen = TFT(cs, dc, rst); // char array to print to the screen char sensorPrintout[5]; void setup() { // Порт управления подсветкой экрана pinMode(6,OUTPUT); analogWrite(6,100); // Put this line at the beginning of every sketch that uses the GLCD: TFTscreen.begin(); // clear the screen with a black background TFTscreen.background(0, 0, 0); // write the static text to the screen // set the font color to white TFTscreen.stroke(255, 255, 255); // set the font size TFTscreen.setTextSize(2); // write the text to the top left corner of the screen TFTscreen.text("Sensor Value :\n ", 0, 0); // ste the font size very large for the loop TFTscreen.setTextSize(5); } void loop() { // Read the value of the sensor on A0 String sensorVal = String(analogRead(A0)); // преобразуйте чтение в массив символов sensorVal.toCharArray(sensorPrintout, 5); // установите цвет шрифта TFTscreen.stroke(0, 255, 50); //выведите значение датчика TFTscreen.text(sensorPrintout, 0, 20); // delay(300); // сотрите текст, который вы только что написали TFTscreen.stroke(0, 0, 0); TFTscreen.text(sensorPrintout, 0, 20); }Зачем тогда стабилизатор ему на плате?
Почему токаограничительный резистор только 3,3 Ома?
Зачем резисторы в схеме?
Как всегда одни вопросы.
я тут намедни протупил. без резисторов включил (использовал для ESP ранее), так что теперь - был у меня один дисплей )))
ЗЫ первые потери да 6 лет...
Если экран чик один можно так сократить резисторы. Удивительно, но такой вариант схемы работает надёжно. Замерял авометром электронным, на резисторе к SDA падает 0,8-0,9В при питании от 5 В и всего 0,06 при питании от аккума (3,8В). Как то я в смущении от их пользы, но убирать не стану :)
Ну в целом ни так и не сяк. Отрисовка медленней чем на SSD1306. Но цвета красивые. Как узоры будут смотреться неизвестно.
Офф: lilik, не в службу, скинь ссылку на свою тему, где ты шары на адресных светодиодах делал ))
https://arduino.ru/forum/proekty/zalivaem-shary-k-prazdniku
Спасибо))
Отрисовка медленней чем на SSD1306.
А скорость передачи ?
И там, и там передача последовательная. Так что даже 4 Мбит/с SPI против 400 кбит/ I2C не могут изменить соотношение на обратное.
И, кстати, 1306 вполне способен работать по I2C на 2 Мбит/с. Да и с интерфейсом SPI они бывают. Так что в принципе возможности разгона у 1306 выше.
Да, в целом не шустро, но если смотреть в прищур, то даже пламя похоже на пламя.
lilik, Сколько памяти кушают скетчи?
lilik, Сколько памяти кушают скетчи?
Секундомер 38% памяти и 6% динамической, узоры 25 и 5 соответственно.
Спасибо.
Это у 328й?
Да.
lilik, Сколько памяти кушают скетчи?
Секундомер 38% памяти и 6% динамической, узоры 25 и 5 соответственно.
а можешь код секундомера выложить?
// СЕКУНДОМЕР #include <Adafruit_GFX.h> // Core graphics library #include <Adafruit_ST7735.h> // Hardware-specific library #include <SPI.h> #define TFT_CS 10 #define TFT_RST 9 #define TFT_DC 8 Adafruit_ST7735 tft = Adafruit_ST7735(TFT_CS, TFT_DC, TFT_RST); float a = 0.00; // переменная для угла поворота стрелки float aa = 0.00; // переменная для угла поворота стрелки (предыдущее значение) int str = 55; //длина стрелки в пикселях byte sek=16;// void setup(void) { // Используйте этот инициализатор, если вы используете 1,8-дюймовый TFT tft.initR(INITR_BLACKTAB); // initialize a ST7735S chip, black tab tft.fillScreen(ST7735_BLACK); tft.setRotation(1);//ориентация экрана tft.drawCircle(80,64,63,ST7735_WHITE );//обод секундомера tft.drawCircle(80,64,62,ST7735_WHITE ); tft.drawCircle(80,64,61,ST7735_WHITE ); } void loop() { // aa = a; // tft.drawLine(80, 64, 80 + cos(aa)*str, 64 + sin(aa)*str,ST7735_BLACK ); // стирание старой стрелки-отрезка tft.drawLine(80+ cos(aa+1.5)*str*0.1, 64+ sin(aa+1.5)*str*0.1, 80 + cos(aa)*str, 64 + sin(aa)*str,ST7735_BLACK ); // стирание старой стрелки tft.drawLine(80+ cos(aa-1.5)*str*0.1, 64+ sin(aa-1.5)*str*0.1, 80 + cos(aa)*str, 64 + sin(aa)*str,ST7735_BLACK ); // стирание старой стрелки a=a+PI/30; for (float i = 0.01; i < 2 * PI; i = i + PI / 30) { tft.drawLine(80 + cos(i)*str * 0.9, 64 + sin(i)*str * 0.9, 80 + cos(i)*str, 64 + sin(i)*str,ST7735_GREEN ); // риски-метки шкалы через 1 сек } for (float i = 0.01; i < 2 * PI; i = i + PI / 6) { tft.drawLine(80 + cos(i)*str * 0.75, 64 + sin(i)*str * 0.75, 80 + cos(i)*str, 64 + sin(i)*str,ST7735_WHITE ); // риски-метки шкалы через 5 сек } // tft.drawLine(80, 64, 80 + cos(a)*str, 64 + sin(a)*str,ST7735_WHITE ); // рисование новой стрелки-отрезка tft.drawLine(80+ cos(a+1.5)*str*0.1, 64+ sin(a+1.5)*str*0.1, 80 + cos(a)*str, 64 + sin(a)*str,ST7735_WHITE );// рисование новой стрелки tft.drawLine(80+ cos(a-1.5)*str*0.1, 64+ sin(a-1.5)*str*0.1, 80 + cos(a)*str, 64 + sin(a)*str,ST7735_WHITE );// рисование новой стрелки // tft.drawCircle(80,64,5,ST7735_WHITE ); tft.drawCircle(80,64,4,ST7735_WHITE ); tft.setCursor(50, 45); tft.setTextSize(1); tft.setTextColor(ST7735_GREEN); tft.println(utf8rus("СЕКУНДОМЕР")); tft.setCursor(70, 80); tft.setTextSize(2); tft.setTextColor(ST7735_GREEN); if(sek<10){tft.print("0");}tft.println(sek); sek++;if(sek>59){sek=0;} // delay(835);//подбираем опытным путём tft.fillRect(70, 80, 30, 20, ST7735_BLACK); } //////////////////////////////////////////////////////////////////////// /* Функция перекодировки русских букв из UTF-8 в Win-1251 */ String utf8rus(String source) { int i,k; String target; unsigned char n; char m[2] = { '0', '\0' }; k = source.length(); i = 0; while (i < k) { n = source[i]; i++; if (n >= 0xC0) { switch (n) { case 0xD0: { n = source[i]; i++; if (n == 0x81) { n = 0xA8; break; } if (n >= 0x90 && n <= 0xBF) n = n + 0x30; break; } case 0xD1: { n = source[i]; i++; if (n == 0x91) { n = 0xB8; break; } if (n >= 0x80 && n <= 0x8F) n = n + 0x70; break; } } } m[0] = n; target = target + String(m); } return target; } ///////////////////////////////////////////////////////////////////////////Секундомер.
С ч\б картинками разобрался, осталось научится их раскрашивать в разные цвета, имея одноцветный массив. Наверное из библиотеки функцию изымать и выдумывать зависимости цвета от счётчиков пикселей - i, j :)
секундомера стрелку (некстати) сделал накладывающейся - как настоящая.
Код секундомера для RP2040, русских шрифтов нет, увы...
// СЕКУНДОМЕР #include <Adafruit_GFX.h> // Core graphics library #include <Adafruit_ST7735.h> // Hardware-specific library for ST7735 #include <Adafruit_ST7789.h> // Hardware-specific library for ST7789 #include <SPI.h> #define SPI01 // Дисплей на SPI1, NRF24L01 на SPI0 #if defined(SPI01) // для RP2040 SPI1 #define TFT_CS 13 // GP13 - CS #define TFT_RST 14 // GP14 - RESET #define TFT_DC 15 // GP15 - A0 #define TFT_MISO 12 // GP12 - MISO (MISO, RX) #define TFT_MOSI 11 // GP11 - SDA (MOSI, TX) #define TFT_SCLK 10 // GP10 - SCK #else // для RP2040 SPI0 #define TFT_CS 5 // GP5 - CS #define TFT_RST 6 // GP6 - RESET #define TFT_DC 7 // GP7 - A0 #define TFT_MISO 4 // GP4 - MISO (MISO, RX) #define TFT_MOSI 3 // GP3 - SDA (MOSI, TX) #define TFT_SCLK 2 // GP2 - SCK #endif // For ST7735-based displays, we will use this call Adafruit_ST7735 tft = Adafruit_ST7735(TFT_CS, TFT_DC, TFT_MOSI, TFT_SCLK, TFT_RST); float a = 0.00; // переменная для угла поворота стрелки float aa = 0.00; // переменная для угла поворота стрелки (предыдущее значение) int str = 55; //длина стрелки в пикселях byte sek=16;// void setup(void) { // Используйте этот инициализатор, если вы используете 1,8-дюймовый TFT tft.initR(INITR_BLACKTAB); // initialize a ST7735S chip, black tab tft.fillScreen(ST7735_BLACK); tft.setRotation(1);//ориентация экрана tft.setSPISpeed(50000000); tft.drawCircle(80,64,63,ST7735_WHITE );//обод секундомера tft.drawCircle(80,64,62,ST7735_WHITE ); tft.drawCircle(80,64,61,ST7735_WHITE ); } void loop() { // aa = a; // tft.drawLine(80, 64, 80 + cos(aa)*str, 64 + sin(aa)*str,ST7735_BLACK ); // стирание старой стрелки-отрезка tft.drawLine(80+ cos(aa+1.5)*str*0.1, 64+ sin(aa+1.5)*str*0.1, 80 + cos(aa)*str, 64 + sin(aa)*str,ST7735_BLACK ); // стирание старой стрелки tft.drawLine(80+ cos(aa-1.5)*str*0.1, 64+ sin(aa-1.5)*str*0.1, 80 + cos(aa)*str, 64 + sin(aa)*str,ST7735_BLACK ); // стирание старой стрелки a=a+PI/30; for (float i = 0.01; i < 2 * PI; i = i + PI / 30) { tft.drawLine(80 + cos(i)*str * 0.9, 64 + sin(i)*str * 0.9, 80 + cos(i)*str, 64 + sin(i)*str,ST7735_GREEN ); // риски-метки шкалы через 1 сек } for (float i = 0.01; i < 2 * PI; i = i + PI / 6) { tft.drawLine(80 + cos(i)*str * 0.75, 64 + sin(i)*str * 0.75, 80 + cos(i)*str, 64 + sin(i)*str,ST7735_WHITE ); // риски-метки шкалы через 5 сек } // tft.drawLine(80, 64, 80 + cos(a)*str, 64 + sin(a)*str,ST7735_WHITE ); // рисование новой стрелки-отрезка tft.drawLine(80+ cos(a+1.5)*str*0.1, 64+ sin(a+1.5)*str*0.1, 80 + cos(a)*str, 64 + sin(a)*str,ST7735_WHITE );// рисование новой стрелки tft.drawLine(80+ cos(a-1.5)*str*0.1, 64+ sin(a-1.5)*str*0.1, 80 + cos(a)*str, 64 + sin(a)*str,ST7735_WHITE );// рисование новой стрелки // tft.drawCircle(80,64,5,ST7735_WHITE ); tft.drawCircle(80,64,4,ST7735_WHITE ); tft.setCursor(50, 45); tft.setTextSize(1); tft.setTextColor(ST7735_GREEN); tft.println(utf8rus("СЕКУНДОМЕР")); tft.setCursor(70, 80); tft.setTextSize(2); tft.setTextColor(ST7735_GREEN); if(sek<10){tft.print("0");}tft.println(sek); sek++;if(sek>59){sek=0;} // delay(835);//подбираем опытным путём tft.fillRect(70, 80, 30, 20, ST7735_BLACK); } //////////////////////////////////////////////////////////////////////// /* Функция перекодировки русских букв из UTF-8 в Win-1251 */ String utf8rus(String source) { int i,k; String target; unsigned char n; char m[2] = { '0', '\0' }; k = source.length(); i = 0; while (i < k) { n = source[i]; i++; if (n >= 0xC0) { switch (n) { case 0xD0: { n = source[i]; i++; if (n == 0x81) { n = 0xA8; break; } if (n >= 0x90 && n <= 0xBF) n = n + 0x30; break; } case 0xD1: { n = source[i]; i++; if (n == 0x91) { n = 0xB8; break; } if (n >= 0x80 && n <= 0x8F) n = n + 0x70; break; } } } m[0] = n; target = target + String(m); } return target; } ///////////////////////////////////////////////////////////////////////////А почему такая медленная перерисовка?
А почему такая медленная перерисовка?
пока не знаю, скорость на SPI выставлена по максимуму
Код секундомера для RP2040, русских шрифтов нет, увы...
А картинка?
Я по ходу забыл, в файлы библиотеки "...GFX" надо добавить
#ifndef FONT5X7_H #define FONT5X7_H #ifdef __AVR__ #include <avr/io.h> #include <avr/pgmspace.h> #elif defined(ESP8266) #include <pgmspace.h> #else #define PROGMEM #endif // Standard ASCII 5x7 font static const unsigned char font[] PROGMEM = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x3E, 0x55, 0x51, 0x55, 0x3E, 0x3E, 0x6B, 0x6F, 0x6B, 0x3E, 0x0C, 0x1E, 0x3C, 0x1E, 0x0C, 0x08, 0x1C, 0x3E, 0x1C, 0x08, 0x1C, 0x4A, 0x7F, 0x4A, 0x1C, 0x18, 0x5C, 0x7F, 0x5C, 0x18, 0x00, 0x1C, 0x1C, 0x1C, 0x00, 0x7F, 0x63, 0x63, 0x63, 0x7F, 0x00, 0x1C, 0x14, 0x1C, 0x00, 0x7F, 0x63, 0x6B, 0x63, 0x7F, 0x30, 0x48, 0x4D, 0x33, 0x07, 0x06, 0x29, 0x79, 0x29, 0x06, 0x20, 0x50, 0x3F, 0x02, 0x0C, 0x60, 0x7F, 0x05, 0x35, 0x3F, 0x2A, 0x1C, 0x77, 0x1C, 0x2A, 0x00, 0x7F, 0x3E, 0x1C, 0x08, 0x08, 0x1C, 0x3E, 0x7F, 0x00, 0x14, 0x22, 0x7F, 0x22, 0x14, 0x00, 0x5F, 0x00, 0x5F, 0x00, 0x06, 0x09, 0x7F, 0x01, 0x7F, 0x4A, 0x55, 0x55, 0x55, 0x29, 0x60, 0x60, 0x60, 0x60, 0x60, 0x54, 0x62, 0x7F, 0x62, 0x54, 0x08, 0x04, 0x7E, 0x04, 0x08, 0x08, 0x10, 0x3F, 0x10, 0x08, 0x08, 0x08, 0x2A, 0x1C, 0x08, 0x08, 0x1C, 0x2A, 0x08, 0x08, 0x1C, 0x10, 0x10, 0x10, 0x10, 0x1C, 0x3E, 0x08, 0x3E, 0x1C, 0x30, 0x3C, 0x3F, 0x3C, 0x30, 0x06, 0x1E, 0x7E, 0x1E, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5F, 0x00, 0x00, 0x00, 0x07, 0x00, 0x07, 0x00, 0x14, 0x7F, 0x14, 0x7F, 0x14, 0x24, 0x2A, 0x7F, 0x2A, 0x12, 0x23, 0x13, 0x08, 0x64, 0x62, 0x36, 0x49, 0x56, 0x20, 0x50, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x1C, 0x22, 0x41, 0x00, 0x00, 0x41, 0x22, 0x1C, 0x00, 0x14, 0x08, 0x3E, 0x08, 0x14, 0x08, 0x08, 0x3E, 0x08, 0x08, 0x00, 0xA0, 0x60, 0x00, 0x00, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x60, 0x60, 0x00, 0x00, 0x20, 0x10, 0x08, 0x04, 0x02, 0x3E, 0x51, 0x49, 0x45, 0x3E, 0x44, 0x42, 0x7F, 0x40, 0x40, 0x42, 0x61, 0x51, 0x49, 0x46, 0x21, 0x41, 0x45, 0x4B, 0x31, 0x18, 0x14, 0x12, 0x7F, 0x10, 0x27, 0x45, 0x45, 0x45, 0x39, 0x3C, 0x4A, 0x49, 0x49, 0x30, 0x01, 0x71, 0x09, 0x05, 0x03, 0x36, 0x49, 0x49, 0x49, 0x36, 0x06, 0x49, 0x49, 0x29, 0x1E, 0x00, 0x6C, 0x6C, 0x00, 0x00, 0x00, 0xAC, 0x6C, 0x00, 0x00, 0x08, 0x14, 0x22, 0x41, 0x00, 0x14, 0x14, 0x14, 0x14, 0x14, 0x00, 0x41, 0x22, 0x14, 0x08, 0x02, 0x01, 0x51, 0x09, 0x06, 0x3E, 0x41, 0x5D, 0x55, 0x5E, 0x7C, 0x12, 0x11, 0x12, 0x7C, 0x7F, 0x49, 0x49, 0x49, 0x36, 0x3E, 0x41, 0x41, 0x41, 0x22, 0x7F, 0x41, 0x41, 0x22, 0x1C, 0x7F, 0x49, 0x49, 0x49, 0x41, 0x7F, 0x09, 0x09, 0x09, 0x01, 0x3E, 0x41, 0x49, 0x49, 0x7A, 0x7F, 0x08, 0x08, 0x08, 0x7F, 0x00, 0x41, 0x7F, 0x41, 0x00, 0x20, 0x40, 0x41, 0x3F, 0x01, 0x7F, 0x08, 0x14, 0x22, 0x41, 0x7F, 0x40, 0x40, 0x40, 0x60, 0x7F, 0x02, 0x0C, 0x02, 0x7F, 0x7F, 0x04, 0x08, 0x10, 0x7F, 0x3E, 0x41, 0x41, 0x41, 0x3E, 0x7F, 0x09, 0x09, 0x09, 0x06, 0x3E, 0x41, 0x51, 0x21, 0x5E, 0x7F, 0x09, 0x19, 0x29, 0x46, 0x46, 0x49, 0x49, 0x49, 0x31, 0x03, 0x01, 0x7F, 0x01, 0x03, 0x3F, 0x40, 0x40, 0x40, 0x3F, 0x1F, 0x20, 0x40, 0x20, 0x1F, 0x3F, 0x40, 0x3C, 0x40, 0x3F, 0x63, 0x14, 0x08, 0x14, 0x63, 0x07, 0x08, 0x70, 0x08, 0x07, 0x61, 0x51, 0x49, 0x45, 0x43, 0x00, 0x7F, 0x41, 0x41, 0x00, 0x02, 0x04, 0x08, 0x10, 0x20, 0x00, 0x41, 0x41, 0x7F, 0x00, 0x04, 0x02, 0x01, 0x02, 0x04, 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x01, 0x02, 0x04, 0x00, 0x20, 0x54, 0x54, 0x54, 0x78, 0x7F, 0x48, 0x44, 0x44, 0x38, 0x38, 0x44, 0x44, 0x44, 0x48, 0x38, 0x44, 0x44, 0x48, 0x7F, 0x38, 0x54, 0x54, 0x54, 0x18, 0x08, 0x7E, 0x09, 0x01, 0x02, 0x08, 0x54, 0x54, 0x58, 0x3C, 0x7F, 0x08, 0x04, 0x04, 0x78, 0x00, 0x44, 0x7D, 0x40, 0x00, 0x20, 0x40, 0x44, 0x3D, 0x00, 0x7F, 0x10, 0x10, 0x28, 0x44, 0x00, 0x41, 0x7F, 0x40, 0x00, 0x7C, 0x04, 0x78, 0x04, 0x78, 0x7C, 0x08, 0x04, 0x04, 0x78, 0x38, 0x44, 0x44, 0x44, 0x38, 0x7C, 0x14, 0x14, 0x14, 0x08, 0x08, 0x14, 0x14, 0x0C, 0x7C, 0x7C, 0x08, 0x04, 0x04, 0x08, 0x48, 0x54, 0x54, 0x54, 0x24, 0x04, 0x3F, 0x44, 0x40, 0x20, 0x3C, 0x40, 0x40, 0x20, 0x7C, 0x1C, 0x20, 0x40, 0x20, 0x1C, 0x3C, 0x40, 0x38, 0x40, 0x3C, 0x44, 0x28, 0x10, 0x28, 0x44, 0x0C, 0x50, 0x50, 0x50, 0x3C, 0x44, 0x64, 0x54, 0x4C, 0x44, 0x00, 0x08, 0x36, 0x41, 0x00, 0x00, 0x00, 0x7F, 0x00, 0x00, 0x00, 0x41, 0x36, 0x08, 0x00, 0x02, 0x01, 0x02, 0x04, 0x02, 0x70, 0x48, 0x44, 0x48, 0x70, 0x00, 0x0E, 0x11, 0x0E, 0x00, 0x00, 0x12, 0x1F, 0x10, 0x00, 0x00, 0x12, 0x19, 0x16, 0x00, 0x00, 0x11, 0x15, 0x0B, 0x00, 0x00, 0x07, 0x04, 0x1F, 0x00, 0x00, 0x17, 0x15, 0x09, 0x00, 0x00, 0x0E, 0x15, 0x09, 0x00, 0x00, 0x01, 0x1D, 0x03, 0x00, 0x00, 0x0A, 0x15, 0x0A, 0x00, 0x00, 0x12, 0x15, 0x0E, 0x00, 0x00, 0x04, 0x04, 0x04, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x3E, 0x00, 0x00, 0x00, 0x00, 0x3E, 0x3E, 0x00, 0x00, 0x00, 0x3E, 0x3E, 0x00, 0x3E, 0x00, 0x3E, 0x3E, 0x00, 0x3E, 0x3E, 0x80, 0x80, 0x80, 0x80, 0x80, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xD0, 0xD0, 0xD0, 0xD0, 0xD0, 0xD8, 0xD8, 0xD8, 0xD8, 0xD8, 0xDA, 0xDA, 0xDA, 0xDA, 0xDA, 0xDB, 0xDB, 0xDB, 0xDB, 0xDB, 0x40, 0x00, 0x40, 0x00, 0x40, 0x60, 0x00, 0x40, 0x00, 0x40, 0x60, 0x00, 0x70, 0x00, 0x40, 0x60, 0x00, 0x70, 0x00, 0x78, 0x7C, 0x00, 0x40, 0x00, 0x40, 0x7C, 0x00, 0x7E, 0x00, 0x40, 0x7C, 0x00, 0x7E, 0x00, 0x7F, 0x1C, 0x77, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x7F, 0x00, 0x1C, 0x77, 0x41, 0x5D, 0x5D, 0x41, 0x41, 0x41, 0x5D, 0x5D, 0x5D, 0x5D, 0x41, 0x5D, 0x5D, 0x5D, 0x5D, 0x41, 0x7F, 0x00, 0x22, 0x1C, 0x14, 0x1C, 0x22, 0x00, 0x08, 0x1C, 0x08, 0x00, 0x00, 0x00, 0x77, 0x00, 0x00, 0x46, 0x5D, 0x55, 0x5D, 0x31, 0x7C, 0x55, 0x54, 0x55, 0x44, 0x08, 0x08, 0x2A, 0x08, 0x08, 0x00, 0x14, 0x08, 0x14, 0x00, 0x08, 0x14, 0x22, 0x08, 0x14, 0x7F, 0x41, 0x71, 0x31, 0x1F, 0x03, 0x05, 0x7F, 0x05, 0x03, 0x22, 0x14, 0x7F, 0x55, 0x22, 0x02, 0x55, 0x7D, 0x05, 0x02, 0x06, 0x09, 0x09, 0x06, 0x00, 0x44, 0x44, 0x5F, 0x44, 0x44, 0x1C, 0x14, 0x1C, 0x22, 0x7F, 0x20, 0x3E, 0x61, 0x3E, 0x20, 0x20, 0x50, 0x3F, 0x02, 0x0C, 0x80, 0x7C, 0x20, 0x3C, 0x40, 0x44, 0x3C, 0x04, 0x7C, 0x44, 0x00, 0x00, 0x08, 0x00, 0x00, 0x38, 0x55, 0x54, 0x55, 0x18, 0x7E, 0x08, 0x10, 0x7F, 0x01, 0x08, 0x10, 0x08, 0x04, 0x02, 0x14, 0x08, 0x22, 0x14, 0x08, 0x0E, 0x06, 0x0A, 0x10, 0x20, 0x20, 0x10, 0x0A, 0x06, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x30, 0x28, 0x04, 0x02, 0x02, 0x04, 0x28, 0x30, 0x38, 0x7E, 0x11, 0x11, 0x11, 0x7E, 0x7F, 0x49, 0x49, 0x49, 0x31, 0x7F, 0x49, 0x49, 0x49, 0x36, 0x7F, 0x01, 0x01, 0x01, 0x03, 0xC0, 0x7F, 0x41, 0x7F, 0xC0, 0x7F, 0x49, 0x49, 0x49, 0x41, 0x77, 0x08, 0x7F, 0x08, 0x77, 0x41, 0x49, 0x49, 0x49, 0x36, 0x7F, 0x10, 0x08, 0x04, 0x7F, 0x7C, 0x21, 0x12, 0x09, 0x7C, 0x7F, 0x08, 0x14, 0x22, 0x41, 0x40, 0x3E, 0x01, 0x01, 0x7F, 0x7F, 0x02, 0x0C, 0x02, 0x7F, 0x7F, 0x08, 0x08, 0x08, 0x7F, 0x3E, 0x41, 0x41, 0x41, 0x3E, 0x7F, 0x01, 0x01, 0x01, 0x7F, 0x7F, 0x09, 0x09, 0x09, 0x06, 0x3E, 0x41, 0x41, 0x41, 0x22, 0x01, 0x01, 0x7F, 0x01, 0x01, 0x07, 0x48, 0x48, 0x48, 0x3F, 0x0E, 0x11, 0x7F, 0x11, 0x0E, 0x63, 0x14, 0x08, 0x14, 0x63, 0x7F, 0x40, 0x40, 0x7F, 0xC0, 0x07, 0x08, 0x08, 0x08, 0x7F, 0x7F, 0x40, 0x7F, 0x40, 0x7F, 0x7F, 0x40, 0x7F, 0x40, 0xFF, 0x01, 0x7F, 0x48, 0x48, 0x30, 0x7F, 0x48, 0x48, 0x30, 0x7F, 0x7F, 0x48, 0x48, 0x48, 0x30, 0x22, 0x41, 0x49, 0x49, 0x3E, 0x7F, 0x08, 0x3E, 0x41, 0x3E, 0x46, 0x29, 0x19, 0x09, 0x7F, 0x20, 0x54, 0x54, 0x54, 0x78, 0x3C, 0x4A, 0x4A, 0x49, 0x31, 0x7C, 0x54, 0x54, 0x54, 0x28, 0x7C, 0x04, 0x04, 0x04, 0x0C, 0xC0, 0x78, 0x44, 0x7C, 0xC0, 0x38, 0x54, 0x54, 0x54, 0x18, 0x6C, 0x10, 0x7C, 0x10, 0x6C, 0x44, 0x54, 0x54, 0x54, 0x28, 0x7C, 0x20, 0x10, 0x08, 0x7C, 0x7C, 0x40, 0x26, 0x10, 0x7C, 0x7C, 0x10, 0x10, 0x28, 0x44, 0x40, 0x38, 0x04, 0x04, 0x7C, 0x7C, 0x08, 0x10, 0x08, 0x7C, 0x7C, 0x10, 0x10, 0x10, 0x7C, 0x38, 0x44, 0x44, 0x44, 0x38, 0x7C, 0x04, 0x04, 0x04, 0x7C, 0x7C, 0x14, 0x14, 0x14, 0x08, 0x38, 0x44, 0x44, 0x44, 0x48, 0x04, 0x04, 0x7C, 0x04, 0x04, 0x0C, 0x50, 0x50, 0x50, 0x3C, 0x18, 0x24, 0xFC, 0x24, 0x18, 0x44, 0x28, 0x10, 0x28, 0x44, 0x7C, 0x40, 0x40, 0x7C, 0xC0, 0x0C, 0x10, 0x10, 0x10, 0x7C, 0x7C, 0x40, 0x7C, 0x40, 0x7C, 0x7C, 0x40, 0x7C, 0x40, 0xFC, 0x04, 0x7C, 0x50, 0x50, 0x20, 0x7C, 0x50, 0x50, 0x20, 0x7C, 0x7C, 0x50, 0x50, 0x50, 0x20, 0x28, 0x44, 0x54, 0x54, 0x38, 0x7C, 0x10, 0x38, 0x44, 0x38, 0x48, 0x34, 0x14, 0x14, 0x7C}; #endif // FONT5X7_Hglcdfont.c файл называется.
Новая версия, ещё более тормознутая отрисовка стрелки.
// СЕКУНДОМЕР #include <Adafruit_GFX.h> // Core graphics library #include <Adafruit_ST7735.h> // Hardware-specific library #include <SPI.h> #define TFT_CS 10 #define TFT_RST 9 #define TFT_DC 8 Adafruit_ST7735 tft = Adafruit_ST7735(TFT_CS, TFT_DC, TFT_RST); float a = 0.00; // переменная для угла поворота стрелки float aa = 0.00; // переменная для угла поворота стрелки (предыдущее значение) int str = 55; //длина стрелки в пикселях byte sek=16;// void setup(void) { // Используйте этот инициализатор, если вы используете 1,8-дюймовый TFT tft.initR(INITR_BLACKTAB); // initialize a ST7735S chip, black tab tft.fillScreen(ST7735_BLACK); tft.setRotation(1);//ориентация экрана tft.drawCircle(80,64,63,ST7735_WHITE );//обод секундомера tft.drawCircle(80,64,62,ST7735_WHITE ); tft.drawCircle(80,64,61,ST7735_WHITE ); } void loop() { // aa = a; // tft.setCursor(50, 45); tft.setTextSize(1); tft.setTextColor(ST7735_GREEN); tft.println(utf8rus("СЕКУНДОМЕР")); tft.setCursor(70, 80); tft.setTextSize(2); tft.setTextColor(ST7735_GREEN); if(sek<10){tft.print("0");}tft.println(sek); // tft.fillTriangle(80+ cos(aa+1.5)*str*0.1, 64+ sin(aa+1.5)*str*0.1, 80 + cos(aa)*str, 64 + sin(aa)*str,80+ cos(aa-1.5)*str*0.1, 64+ sin(aa-1.5)*str*0.1,ST7735_BLACK );// стирание старой стрелки a=a+PI/30; tft.fillCircle(80,64,7,ST7735_WHITE ); for (float i = 0.01; i < 2 * PI; i = i + PI / 30) { tft.drawLine(80 + cos(i)*str * 0.90, 64 + sin(i)*str * 0.90, 80 + cos(i)*str, 64 + sin(i)*str,ST7735_GREEN ); // риски-метки шкалы через 1 сек } for (float i = 0.01; i < 2 * PI; i = i + PI / 6) { tft.drawLine(80 + cos(i)*str * 0.75, 64 + sin(i)*str * 0.75, 80 + cos(i)*str, 64 + sin(i)*str,ST7735_WHITE ); // риски-метки шкалы через 5 сек } tft.fillTriangle(80+ cos(a+1.5)*str*0.1, 64+ sin(a+1.5)*str*0.1, 80 + cos(a)*str, 64 + sin(a)*str,80+ cos(a-1.5)*str*0.1, 64+ sin(a-1.5)*str*0.1,ST7735_WHITE );// рисование новой стрелки tft.fillCircle(80,64,3,ST7735_BLACK ); sek++;if(sek>59){sek=0;} // delay(835);//подбираем опытным путём tft.fillRect(70, 80, 30, 20, ST7735_BLACK); } //////////////////////////////////////////////////////////////////////// /* Функция перекодировки русских букв из UTF-8 в Win-1251 */ String utf8rus(String source) { int i,k; String target; unsigned char n; char m[2] = { '0', '\0' }; k = source.length(); i = 0; while (i < k) { n = source[i]; i++; if (n >= 0xC0) { switch (n) { case 0xD0: { n = source[i]; i++; if (n == 0x81) { n = 0xA8; break; } if (n >= 0x90 && n <= 0xBF) n = n + 0x30; break; } case 0xD1: { n = source[i]; i++; if (n == 0x91) { n = 0xB8; break; } if (n >= 0x80 && n <= 0x8F) n = n + 0x70; break; } } } m[0] = n; target = target + String(m); } return target; } ///////////////////////////////////////////////////////////////////////////А почему такая медленная перерисовка?
пока не знаю, скорость на SPI выставлена по максимуму
Давай считать: Для одного пикселя нужно записать 16 бит, что при 4МГц будет 4 мкс, что соответствует 64 тактам при 16 МГц. Ну еще преобразование 1 бита 16 - это 8-10 инструкций, пусть будет еще 16 тактов. Итого 80 тактов или 5 мкс.
На экране 160*128=20к пикселей, по 5 мкс на каждый - 100 мс. Т.е. должно быть порядка 10 fps. Мы видим явно меньше, вопрос - почему?
andriano он же через библиотеку выводит ... - дели скорость на 100 :-)
Не 10 кадров в секунду, а 10 секунда на кадр ...
andriano он же через библиотеку выводит ... - дели скорость на 100 :-)
Не 10 кадров в секунду, а 10 секунда на кадр ...
Вот поэтому я никогда и не пользуюсь стандартными библиотеками для экрана, а предпочитаю писать сам.
lilik, покажи тот фрагмент, который выводит на экран первый рисунок из сообщения №25.
lilik На какой частоте работает плата ? Если на 16, то fosc/2 - это 8, а не 4 ...
Жаль что нет буфера как на UART - ожидание окончания вывода даёт паузы между байтами ...
Спасибо! Вторая половина кодовой таблицы с выбором языка оказывается только ручками )))
Что-то я на этом тормознулся, хотя с DOS был жеж более чем в теме... Осень...
Да, я добавил в ваш код установку скорости SPI, отрабатывает ли должным образом
надо разбираться, но если ставить скорость 60000000 то дисплей не АЛЛЁ )))
lilik, покажи тот фрагмент, который выводит на экран первый рисунок из сообщения №25.
// РИСУНОК #include <Adafruit_GFX.h> // Core graphics library #include <Adafruit_ST7735.h> // Hardware-specific library #include <SPI.h> #define TFT_CS 10 #define TFT_RST 9 #define TFT_DC 8 Adafruit_ST7735 tft = Adafruit_ST7735(TFT_CS, TFT_DC, TFT_RST); extern const unsigned char ris_1[]; extern const unsigned char ris_2[]; void setup(void) { // Используйте этот инициализатор, если вы используете 1,8-дюймовый TFT tft.initR(INITR_BLACKTAB); // initialize a ST7735S chip, black tab tft.fillScreen(ST7735_BLACK); tft.setRotation(0);//ориентация экрана } void loop() { tft.drawBitmap(0,0,ris_1, 128,160,tft.Color565(255,255,255),0); tft.drawBitmap(0,0,ris_2, 128,160,tft.Color565(255,255,255),0); }Да, я добавил в ваш код установку скорости SPI, отрабатывает ли должным образом...
Скетч не компилируется.
lilik На какой частоте работает плата ? Если на 16, то fosc/2 - это 8, а не 4 ...
Жаль что нет буфера как на UART - ожидание окончания вывода даёт паузы между байтами ...
Плата UNO китайская с CH340.
50 МГц ??? У вас Uno, а не RP2040 !!!
50 МГц ??? У вас Uno, а не RP2040 !!!
Да!, но не компилируется не из-за чисел :)
Вот так компилируется и работает, но число 16000000 (и любые другие) ни на что не влияют.
// РИСУНОК #include <Adafruit_GFX.h> // Core graphics library #include <Adafruit_ST7735.h> // Hardware-specific library #include <SPI.h> #define TFT_CS 10 #define TFT_RST 9 #define TFT_DC 8 Adafruit_ST7735 tft = Adafruit_ST7735(TFT_CS, TFT_DC, TFT_RST); extern const unsigned char ris_1[]; extern const unsigned char ris_2[]; void setup(void) { // Используйте этот инициализатор, если вы используете 1,8-дюймовый TFT tft.initR(INITR_BLACKTAB); // initialize a ST7735S chip, black tab tft.fillScreen(ST7735_BLACK); tft.setRotation(0);//ориентация экрана SPI.begin(); SPI.beginTransaction(SPISettings(16000000, MSBFIRST, SPI_MODE0)); } void loop() { tft.drawBitmap(0,0,ris_1, 128,160,tft.Color565(255,255,255),0); tft.drawBitmap(0,0,ris_2, 128,160,tft.Color565(255,255,255),0); }lilik, покажи тот фрагмент, который выводит на экран первый рисунок из сообщения №25.
Ну а раз так - сообщения №32-33.
На UNO 16 МНц частота SPI не может быть выше 8 МНц
SPI.setClockDivider(SPI_CLOCK_DIV2);
Ну и кроме того, по моим наблюдениям, 8МГц на AVR практически не отличается от 4МГц.
Да и вообще, с реализацией SPI на Arduino нужно как следует разбираться: если для AVR я установил лишь факт, описанный выше (т.е. относительное значение), то для stm32 получил абсолютное: на практике скорость передачи 1/7 от теоретического значения.
Ну и кроме того, по моим наблюдениям, 8МГц на AVR практически не отличается от 4МГц.
Да и вообще, с реализацией SPI на Arduino нужно как следует разбираться: если для AVR я установил лишь факт, описанный выше (т.е. относительное значение), то для stm32 получил абсолютное: на практике скорость передачи 1/7 от теоретического значения.
а как померить реальную скорость?
Есть такая функция - millis().
Ну и, кроме того, у "железячников" должен быть осциллограф (или логический анализатор).
На UNO 16 МНц частота SPI не может быть выше 8 МНц
SPI.setClockDivider(SPI_CLOCK_DIV2);
Подставил в скетч, так же медленно как и было. Мне вот что интересно - все функции рисования картинок приводят к функции рисования одной точки. Сегодня мне интересно из одноцветной картинки делать разноцветную. Вот пример трансформации библиотечной функции в самописную.
// РИСУНОК #include <Adafruit_GFX.h> // Core graphics library #include <Adafruit_ST7735.h> // Hardware-specific library #include <SPI.h> #define TFT_CS 10 #define TFT_RST 9 #define TFT_DC 8 Adafruit_ST7735 tft = Adafruit_ST7735(TFT_CS, TFT_DC, TFT_RST); extern const unsigned char ris_1[]; extern const unsigned char ris_2[]; void setup(void) { // Используйте этот инициализатор, если вы используете 1,8-дюймовый TFT tft.initR(INITR_BLACKTAB); // initialize a ST7735S chip, black tab tft.fillScreen(ST7735_BLACK); tft.setRotation(0);//ориентация экрана } void loop() { drawBitmap_(0,0,ris_1, 128,160); delay(200);// } //////////////////////////////////////////////////////// void drawBitmap_(int16_t x, int16_t y, const uint8_t *bitmap, int16_t w, int16_t h) { int16_t i, j, byteWidth = (w + 7) / 8; uint8_t byte; for(j=0; j<h; j++) { for(i=0; i<w; i++) { if(i & 7) byte <<= 1; else byte = pgm_read_byte(bitmap + j * byteWidth + i / 8); if(byte & 0x80) { //tft.drawPixel(x+i, y+j,tft.Color565(255,255,255) ); if(j>h/2-5&&i<=w/2-5){tft.drawPixel(x+i, y+j,tft.Color565(0,255,0) );} if(j<=h/2-5&&i>w/2-5){tft.drawPixel(x+i, y+j,tft.Color565(255,0,255) );} if(j>h/2-5&&i>w/2-5){tft.drawPixel(x+i, y+j,tft.Color565(0,150,255) );} if(i*i+j*j<10010&&j<=w){tft.drawPixel(x+i, y+j,tft.Color565(255,0,0) );} } } } } //////////////////////////////////////////////////////////Она переделывает одну картинку в другую.
Может дело в попиксельном выводе данных?
пока вы не переделаете вывод пикселей картинки напрямую дисплею в память, скорости нормальной не получите.
Да, выводить попиксельно - это неправильно.
В контроллерах цветных дисплеев (во всех, с которыми мне приходилось работать) специально для увеличения скорости вывода пикселей используется функция, задающая прямоугольник, в который осуществляется вывод. Например, для вывода символа в знакоместо 10*16 задается прямоугольная область такого размера, а потом просто поочередно передаются цвета точек, которые последовательно заполняют эту область.
Т.е. на вывод 160 точек в примере выше мы сначала задаем команду 6-16 байт, а потом цвета всех 160 точек, т.е. еще 320 байт. Т.е. из примерно 330 байт 320 передают информацию о цвете точек.
При попиксельном выводе все то же самое, только на 3-16 байт служебной информации (задающей координаты точки) приходится только 2 байта на цвет (единственной точки).
В случае картинки и невозможности уместить ее в памяти целиком, целесообразно выводить построчно: т.е. задали строку 128*1 пискель, посчитали в буфер (256 байт) и вывели на экран. Потом - следующую.
пока вы не переделаете вывод пикселей картинки напрямую дисплею в память, скорости нормальной не получите.
В примерах, что я опытничаю, внутри библиотек две функции рисования точки. Какая работает мне не ясно.
void Adafruit_ST7735::drawPixel(int16_t x, int16_t y, uint16_t color) { if((x < 0) ||(x >= _width) || (y < 0) || (y >= _height)) return; setAddrWindow(x,y,x+1,y+1); #if defined (SPI_HAS_TRANSACTION) if (hwSPI) SPI.beginTransaction(mySPISettings); #endif DC_HIGH(); CS_LOW(); spiwrite(color >> 8); spiwrite(color); CS_HIGH(); #if defined (SPI_HAS_TRANSACTION) if (hwSPI) SPI.endTransaction(); #endif }void GFXcanvas1::drawPixel(int16_t x, int16_t y, uint16_t color) { // Bitmask tables of 0x80>>X and ~(0x80>>X), because X>>Y is slow on AVR static const uint8_t PROGMEM GFXsetBit[] = { 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01 }, GFXclrBit[] = { 0x7F, 0xBF, 0xDF, 0xEF, 0xF7, 0xFB, 0xFD, 0xFE }; if(buffer) { if((x < 0) || (y < 0) || (x >= _width) || (y >= _height)) return; int16_t t; switch(rotation) { case 1: t = x; x = WIDTH - 1 - y; y = t; break; case 2: x = WIDTH - 1 - x; y = HEIGHT - 1 - y; break; case 3: t = x; x = y; y = HEIGHT - 1 - t; break; }Кстати такой блок нашёл, он на скорость влиет?
inline void Adafruit_ST7735::CS_HIGH(void) { #if defined(USE_FAST_IO) *csport |= cspinmask; #else digitalWrite(_cs, HIGH); #endif } inline void Adafruit_ST7735::CS_LOW(void) { #if defined(USE_FAST_IO) *csport &= ~cspinmask; #else digitalWrite(_cs, LOW); #endif } inline void Adafruit_ST7735::DC_HIGH(void) { #if defined(USE_FAST_IO) *dcport |= dcpinmask; #else digitalWrite(_dc, HIGH); #endif } inline void Adafruit_ST7735::DC_LOW(void) { #if defined(USE_FAST_IO) *dcport &= ~dcpinmask; #else digitalWrite(_dc, LOW); #endif }пока вы не переделаете вывод пикселей картинки напрямую дисплею в память, скорости нормальной не получите.
В примерах, что я опытничаю, внутри библиотек две функции рисования точки. Какая работает мне не ясно.
void Adafruit_ST7735::drawPixel(int16_t x, int16_t y, uint16_t color) { if((x < 0) ||(x >= _width) || (y < 0) || (y >= _height)) return; setAddrWindow(x,y,x+1,y+1); #if defined (SPI_HAS_TRANSACTION) if (hwSPI) SPI.beginTransaction(mySPISettings); #endif DC_HIGH(); CS_LOW(); spiwrite(color >> 8); spiwrite(color); CS_HIGH(); #if defined (SPI_HAS_TRANSACTION) if (hwSPI) SPI.endTransaction(); #endif }ну вот же она, задается координаты вывода, как выше писали. Формируете буфер данных для вывода, и по SPI шлете все это дисплею.
вот из проекта для ili9341, суть та же. (только это для STM + DMA)
void f3spitft::tftSetAddrWindow(unsigned short x0, unsigned short y0, unsigned short x1, unsigned short y1) { static unsigned char pos_data[4]; // column address set tftSendCommand(0x2A); // CASET while (this->spiBUSY()); pos_data[0] = (x0 >> 8) & 0xFF; pos_data[1] = x0 & 0xFF; pos_data[2] = (x1 >> 8) & 0xFF; pos_data[3] = x1 & 0xFF; tftWriteData((unsigned char *)&pos_data, 4); while (this->spiBUSY()); // row address set tftSendCommand(0x2B); // RASET while (this->spiBUSY()); pos_data[0] = (y0 >> 8) & 0xFF; pos_data[1] = y0 & 0xFF; pos_data[2] = (y1 >> 8) & 0xFF; pos_data[3] = y1 & 0xFF; tftWriteData((unsigned char *)&pos_data, 4); while (this->spiBUSY()); // write to RAM tftSendCommand(0x2C); // RAMWR while (this->spiBUSY()); } void f3spitft::tftPrintBuffer(unsigned short x1, unsigned short y1, unsigned short x2, unsigned short y2, unsigned char * inData) { if((x1 >= tftWIDTH) || (y1 >= tftHEIGHT) || (x2 >= tftWIDTH) || (y2 >= tftHEIGHT)) return; if((x1 >= tftWIDTH) || (y1 >= tftHEIGHT) || (x2 >= tftWIDTH) || (y2 >= tftHEIGHT)) return; if(x1>x2) swap(x1,x2); if(y1>y2) swap(y1,y2); unsigned short sizeData = (x2-x1+1)*(y2-y1+1); tftSetAddrWindow(x1, y1, x2, y2); tftSetPinDC(1); tftSetPinCS(0); // говорим slave устройству что начинаем работать inWork = 1; // флаг начала работы DMA1_Channel3->CCR &= ~DMA_CCR_EN; // отключаем любое действие канала если идет передача DMA1_Channel3->CPAR = (unsigned long)(&SPI1->DR); //заносим адрес регистра DR в CPAR DMA1_Channel3->CMAR = (unsigned long)(unsigned char *)inData; //заносим адрес данных в регистр CMAR DMA1_Channel3->CNDTR = sizeData; //количество передаваемых данных // 16 битных слов, т е пикселей DMA1_Channel3->CCR &= ~DMA_CCR_MEM2MEM; //режим MEM2MEM отключен DMA1_Channel3->CCR &= ~DMA_CCR_PL; //приоритет низкий DMA1_Channel3->CCR &= ~DMA_CCR_MSIZE; //разрядность данных в памяти 16 бит // 01: 16-bits DMA1_Channel3->CCR |= DMA_CCR_MSIZE_0; //разрядность данных в памяти 16 бит // 01: 16-bits DMA1_Channel3->CCR &= ~DMA_CCR_PSIZE; //разрядность регистра данных 16 бит в шину SPI DMA1_Channel3->CCR |= DMA_CCR_PSIZE_0; //разрядность регистра данных 16 бит в шину SPI DMA1_Channel3->CCR |= DMA_CCR_MINC; // включить инкремент адреса памяти DMA1_Channel3->CCR &= ~DMA_CCR_PINC; //Инкремент адреса периферии отключен DMA1_Channel3->CCR &= ~DMA_CCR_CIRC; //кольцевой режим отключен DMA1_Channel3->CCR |= DMA_CCR_DIR; //1 - из памяти в периферию SPI1->CR2 |= SPI_CR2_TXDMAEN; // разрешить отправку через DMA DMA1_Channel3->CCR |= DMA_CCR_EN; // включаем передачу данных } void f3spitft::tftShowBackground(unsigned char * inPic) { // выводим фоновую карптинку двумя частями в половину экрана tftPrintBuffer(0, 0, tftWIDTH-1, tftHEIGHT/2-1, inPic); while (this->spiBUSY()); tftPrintBuffer(0, tftHEIGHT/2, tftWIDTH-1, tftHEIGHT-1, inPic+tftWIDTH*tftHEIGHT); while (this->spiBUSY()); }