#1 2025-03-31 20:30:17

renoshnik
Учасник
Зареєстрований: 2017-04-03
Повідомлень: 1,057

рисуем график данных на TFT-дисплее

Старался все рассказать в видео.

#include <TFT_ST7735.h> 			// Библиотека для работы с экраном
#include <SPI.h>
// Параметры подключения
#define CS_PIN 10
#define DC_PIN 9
#define RST_PIN 8
TFT_ST7735 tft = TFT_ST7735();

// Глобальные переменные
int activeFunction = 1;  			// Выбор функции: 1 или 2
// ФУНКЦИЯ 1: Отображение данных при изменении (исключение повторов)
// ФУНКЦИЯ 2: Отображение данных с заданным интервалом времени
float previousVoltage = -1; 		// Предыдущее значение напряжения
unsigned long lastUpdateTime = 0;	// Время последнего обновления графика
unsigned long startTime; 			// Время начала работы программы
const int updateInterval = 100;		// Интервал времени для функции 2 (в миллисекундах)
// Начало координат в нижнем левом углу
  int originX = 0;      			// Начало координат по X (левый край экрана)
  int endX = 158;       			// Окончание координат по X (правый край экрана)
  int originY = 125;    			// Начало координат по Y (нижний край экрана)
  int endY = 0;    					// Окончание координат по Y (верхний край экрана)  
  int x = originX; 					// Текущее положение по оси X для Ф2
  int prev_X = originX;				// Предыдущее значение для отрисовки линии
  int prev_Y = originY;				// Предыдущее значение для отрисовки линии	
  unsigned long totalSeconds = 0; 	// Для преобразования миллисекунды в секунды
  unsigned long hours = 0;         	// Для вычисления часов
  unsigned long minutes = 0; 		// Для вычисления минут
  unsigned long seconds = 0;		// Для вычисления секунд
// Работаем с отображением напряжения (для демонстрации)
  int analogValue = 0;
  float voltage = 0.0;										// Текущее значение напряжения
  const float Vref = 4.76;
  const float R1 = 10000.0; 								// Верхний резистор, в Омах
  const float R2 = 4700.0;  								// Нижний резистор, в Омах
  const float dividerFactor = (R1 + R2) / R2;
  const float pip_Volt = (Vref * dividerFactor) / originY;	// значение одного пикселя
  const float Vmax = Vref * dividerFactor;					// значение максимального напряжения
  boolean real_time = true;


// Инициализация экрана
void setup(void) {
  tft.init();               // Инициализация экрана
  tft.setRotation(3);       // Установка ориентации экрана
  tft.fillScreen(TFT_NAVY); // Установка начального цвета фона
  drawAxes();               // Построение осей координат
}

// Основной цикл
void loop() {
  if (activeFunction == 1) {
    readAnalogAndDrawGraphNoRepeat();  		// Функция 1
  } else if (activeFunction == 2) {
    readAnalogAndDrawGraphWithInterval();	// Функция 2
  }
}

// ФУНКЦИЯ ОТРИСОВКИ БАЗОВОГО ЭКРАНА
void drawAxes() {
  tft.drawLine(originX, originY, endX, originY, TFT_WHITE); 		// Горизонтальная ось
  tft.drawLine(originX, originY, originX, endY, TFT_WHITE); 		// Вертикальная ось
  tft.drawLine(endX, originY, endX - 3, originY - 3, TFT_WHITE);	// Стрелка по X
  tft.drawLine(originX, endY, originX + 3, endY + 3, TFT_WHITE); 	// Стрелка по Y
  
  tft.setTextColor(TFT_CYAN);
  tft.setTextSize(1);
  tft.setCursor(134, 115);
  tft.print("Time");
  tft.setCursor(5, 1);
  tft.print(Vmax); tft.print("/"); tft.print(pip_Volt);
}

// ФУНКЦИЯ 1: Считывание напряжения, исключение повторов
void readAnalogAndDrawGraphNoRepeat() {
	delay (250);		//	для теста  !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
	analogValue = analogRead(A0); // Чтение аналогового значения
	// Перевод в Вольты
	voltage = analogValue * (Vref / 1023.0) * dividerFactor;
	// Вывод цифрового значения напряжения
    tft.setTextColor(TFT_WHITE, TFT_NAVY);
    tft.setTextSize(1);
    tft.setCursor(110, 5);
	if (voltage < 10) tft.print("0"); tft.print(voltage, 2); tft.print(" V");
	// Вывод цифрового значения времени с начала работы программы
    tft.setCursor(110, 15);
 	real_time = true;
	displayFormattedTime();		// Функция формата времени

	float temp_V = voltage - previousVoltage;
	temp_V = abs(temp_V);
	
    // =======>	Построение графика	
	if (temp_V > pip_Volt) {
	previousVoltage = voltage; // Обновляем предыдущее значение		
    int y = map(voltage*100, 0, Vmax*100, originY, endY); // Масштабирование в пиксели
	//tft.drawPixel(x, y, TFT_GREEN);	// Отрисовка пикселями    
	tft.drawLine(prev_X, prev_Y, x, y, TFT_GREEN);		// Отрисовка линиями
    // Сохраняем текущие координаты как предыдущие для следующей линии
    prev_X = x;
    prev_Y = y;
	// Увеличиваем X для следующего пикселя
		x++;	
    // Вывод цифрового значения времени с момента изменения значения напряжения
    tft.setCursor(110, 25);
	real_time = false;
    displayFormattedTime();		// Функция формата времени
    lastUpdateTime = millis(); 	// Обновляем время
	// Если дошли до правого края экрана, обнуляем X и очищаем график
	if (x >= endX) { x = originX; prev_X = originX; prev_Y = originY;
    tft.fillRect(0, 0, endX, originY, TFT_NAVY); // Очищаем область графика
    drawAxes(); // Повторно рисуем оси
	}
  }
}

// ФУНКЦИЯ 2: Считывание напряжения с интервалом времени
void readAnalogAndDrawGraphWithInterval() {
	
    // =======>	Построение графика	
  if (millis() - lastUpdateTime > updateInterval) {
    analogValue = analogRead(A0); // Чтение аналогового значения
	// Перевод в Вольты
	voltage = analogValue * (Vref / 1023.0) * dividerFactor;
    previousVoltage = voltage; // Обновляем предыдущее значение
    int y = map(voltage*100, 0, Vmax*100, originY, endY); // Масштабирование в пиксели
	//tft.drawPixel(x, y, TFT_GREEN);	// Отрисовка пикселями    
	tft.drawLine(prev_X, prev_Y, x, y, TFT_GREEN);		// Отрисовка линиями
    // Сохраняем текущие координаты как предыдущие для следующей линии
    prev_X = x;
    prev_Y = y;
	// Увеличиваем X для следующего пикселя
		x++;					
    // Вывод цифрового значения времени с начала работы программы
    tft.setTextColor(TFT_WHITE, TFT_NAVY);
    tft.setTextSize(1);
    tft.setCursor(110, 5);
    if (voltage < 10) tft.print("0"); tft.print(voltage, 2); tft.print(" V");
    tft.setCursor(110, 15);
	real_time = true;
	displayFormattedTime();		// Функция формата времени
	lastUpdateTime = millis(); 	// Обновляем время
	// Если дошли до правого края экрана, обнуляем X и очищаем график
	if (x >= endX) { x = originX; prev_X = originX; prev_Y = originY;
    tft.fillRect(0, 0, endX, originY, TFT_NAVY); // Очищаем область графика
    drawAxes(); // Повторно рисуем оси
	}
  }
}

void displayFormattedTime() {
  // Преобразуем миллисекунды в секунды
  if (!real_time) totalSeconds = ((millis() - lastUpdateTime) / 1000);
  if (real_time) totalSeconds = millis() / 1000; 		
  hours = totalSeconds / 3600;         	// Вычисляем часы
  minutes = (totalSeconds % 3600) / 60;	// Минуты
  seconds = totalSeconds % 60;         	// Секунды
  if (hours < 10) tft.print("0"); tft.print(hours); tft.print(":");
  if (minutes < 10) tft.print("0"); tft.print(minutes); tft.print(":");
  if (seconds < 10) tft.print("0"); tft.print(seconds);
}

//======================================================//
/* 
TFT_BLACK   	// Черный
TFT_BLUE    	// Синий
TFT_RED     	// Красный
TFT_GREEN   	// Зеленый
TFT_CYAN    	// Циан (бирюзовый)
TFT_MAGENTA 	// Пурпурный
TFT_YELLOW  	// Желтый
TFT_WHITE   	// Белый
TFT_DARKGREEN	// Темно-зеленый
TFT_NAVY    	// Темно-синий
TFT_GREY    	// Серый
TFT_ORANGE  	// Оранжевый
TFT_VIOLET  	// Лиловый (фиолетовый)

1.	tft.init(): 					Инициализация дисплея.
2.	tft.fillScreen(color): 			Заполнение экрана указанным цветом.
3.	drawPixel(x, y, color): 		Рисование пикселя в заданной координате (x, y) с указанным цветом.
4.	drawLine(x0, y0, x1, y1, color):Рисование линии между точками (x0, y0) и (x1, y1).
5.	drawRect(x, y, w, h, color): 	Рисование прямоугольника с верхним левым углом (x, y), шириной w и высотой h.
6.	fillRect(x, y, w, h, color): 	Заполнение прямоугольника указанным цветом.
7.	drawCircle(x, y, r, color):		Рисование окружности с центром (x, y) и радиусом r.
8.	fillCircle(x, y, r, color): 	Заполнение окружности указанным цветом.
9.	setCursor(x, y): 				Установка курсора для вывода текста.
10.	setTextColor(color): 			Установка цвета текста.
11.	setTextSize(size): 				Установка размера текста.
12.	print(text): 					Вывод текста на экран.
13.	println(text): 					Вывод текста с переходом на новую строку.
 */

Неактивний

#2 2025-03-31 21:17:47

jokeer
Гість

Re: рисуем график данных на TFT-дисплее

А тепер непогано було б цей графік згладити. Сплайном наприклад.

#3 2025-03-31 22:10:04

renoshnik
Учасник
Зареєстрований: 2017-04-03
Повідомлень: 1,057

Re: рисуем график данных на TFT-дисплее

jokeer пише:

А тепер непогано було б цей графік згладити. Сплайном наприклад.

смішно .. smile smile smile

Неактивний

#4 2025-03-31 23:13:38

jokeer
Гість

Re: рисуем график данных на TFT-дисплее

ну, рваний графік це не дуже красиво wink

#5 2025-04-01 00:01:22

dimich
Учасник
Зареєстрований: 2023-12-01
Повідомлень: 377

Re: рисуем график данных на TFT-дисплее

На відео наче б то суцільні темні лінії. Тільки незрозуміло, чи то TFT_GREEN такий темний (звідки тоді яскраві кінцеві точки?), чи то воно тільки кінцеві точки малює (звідки тоді суцільні темні лінії?).
Навіщо там сплайни? Щоб графік виглядав красиво, потрібно або малювати лінії алгоритмом Ву (якщо доступні градації яскравості), або взагалі малювати строго вертикальні лінії, тобто щоб початкова та кінцева точки мали однакову координату X. Тільки тоді початкову точку потрібно розраховувати на основі попередньої кінцевої.

Неактивний

#6 2025-04-01 09:47:26

renoshnik
Учасник
Зареєстрований: 2017-04-03
Повідомлень: 1,057

Re: рисуем график данных на TFT-дисплее

jokeer пише:

ну, рваний графік це не дуже красиво wink

Який в біса сплайн на екрані 158/125 ??? Це десяток значінь всього відобразити, а решта сплайн-малюкок, який в цьому сенс ???

Неактивний

#7 2025-04-01 09:50:55

renoshnik
Учасник
Зареєстрований: 2017-04-03
Повідомлень: 1,057

Re: рисуем график данных на TFT-дисплее

dimich пише:

На відео наче б то суцільні темні лінії. Тільки незрозуміло, чи то TFT_GREEN такий темний (звідки тоді яскраві кінцеві точки?), чи то воно тільки кінцеві точки малює (звідки тоді суцільні темні лінії?).

Сам не розумію чому так,    іноді лінії мають рандомний колір хоча колір заданий зелений ...
  tft.drawLine(prev_X, prev_Y, x, y, TFT_GREEN);        // Отрисовка линиями

Неактивний

#8 2025-04-01 12:01:23

jokeer
Гість

Re: рисуем график данных на TFT-дисплее

Ну це ваш проект, вам видніше що графік показує wink
Що до кольору ліній - подивіться всередині тієї ліби, може там магія того ж Брезенхейма некоректно працює з кольором.

#9 2025-04-01 13:12:14

renoshnik
Учасник
Зареєстрований: 2017-04-03
Повідомлень: 1,057

Re: рисуем график данных на TFT-дисплее

jokeer пише:

Ну це ваш проект, вам видніше що графік показує wink
Що до кольору ліній - подивіться всередині тієї ліби, може там магія того ж Брезенхейма некоректно працює з кольором.

До чого тут видніше чи ні ?  Тут справа в доцільності (в даному випадку) дій. З такою роздільною здатністю екрану у любому проекті застосовувати сплайн немає сенсу.
Для більшого екрану я згоден, що зі сплайном буде красивіше.

В лібі поки нічого підозрілого не знайшов...

Неактивний

#10 2025-04-01 22:13:55

jokeer
Гість

Re: рисуем график данных на TFT-дисплее

Я б ввімкнув debug, якщо він там є, вивів би якусь мінімальну картинку з неправильним кольором і подивився що воно насправді виводить на екран.

#11 2025-04-01 22:58:08

dimich
Учасник
Зареєстрований: 2023-12-01
Повідомлень: 377

Re: рисуем график данных на TFT-дисплее

renoshnik пише:

В лібі поки нічого підозрілого не знайшов...

Ця ліба? Там два варіанта реалізації drawLine(), з FAST_LINE і без.

Якщо у вас 158x125, то

   int endX = 158;       			// Окончание координат по X (правый край экрана)
   int originY = 125;    			// Начало координат по Y (нижний край экрана)

мало би бути

   int endX = 157;
   int originY = 124;

хіба ні?

Остання редакція dimich (2025-04-01 23:00:57)

Неактивний

#12 2025-04-01 23:29:54

renoshnik
Учасник
Зареєстрований: 2017-04-03
Повідомлень: 1,057

Re: рисуем график данных на TFT-дисплее

dimich пише:
renoshnik пише:

В лібі поки нічого підозрілого не знайшов...

Ця ліба? Там два варіанта реалізації drawLine(), з FAST_LINE і без.

Якщо у вас 158x125, то

   int endX = 158;       			// Окончание координат по X (правый край экрана)
   int originY = 125;    			// Начало координат по Y (нижний край экрана)

мало би бути

   int endX = 157;
   int originY = 124;

хіба ні?


Так FAST_LINE застосовується для прямих ліній, дійсно так правильніше було малювати осі координат...

    tft.drawFastHLine(0, y, w, color1);
    tft.drawFastVLine(x, 0, h, color2);

Що до розміру екрану, то кінцеві точки я визначив візуально підбором, бо параметрів екрану я не знав.

Неактивний

#13 2025-04-02 00:35:38

dimich
Учасник
Зареєстрований: 2023-12-01
Повідомлень: 377

Re: рисуем график данных на TFT-дисплее

renoshnik пише:

Так FAST_LINE застосовується для прямих ліній, дійсно так правильніше було малювати осі координат...

Я маю на увазі, що в залежності від значення макроса FAST_LINE під час компіляції використовується або одна, або інша реалізація TFT_ST7735::drawLine().

renoshnik пише:

Що до розміру екрану, то кінцеві точки я визначив візуально підбором, бо параметрів екрану я не знав.

Там розмір екрана задається параметрами конструктора:

  TFT_ST7735(int16_t _W = ST7735_TFTWIDTH, int16_t _H = ST7735_TFTHEIGHT);

і за замовчуванням це 128x160.

Враховуючи всю ту "магію" з MADCTL та іншими параметрами, а також зоопарком варіантів модулів з клонами ST7735, при некоректній ініціалізації можуть невірно розраховуватись адреси пікселів, які попадають в середину пікселя, що виглядає як спотворення кольорів.
Я би для початку повиводив прості тестові зображення, щоб побачити закономірність.

Неактивний

#14 2025-04-02 09:58:25

renoshnik
Учасник
Зареєстрований: 2017-04-03
Повідомлень: 1,057

Re: рисуем график данных на TFT-дисплее

dimich пише:
renoshnik пише:

Так FAST_LINE застосовується для прямих ліній, дійсно так правильніше було малювати осі координат...

Я маю на увазі, що в залежності від значення макроса FAST_LINE під час компіляції використовується або одна, або інша реалізація TFT_ST7735::drawLine().

renoshnik пише:

Що до розміру екрану, то кінцеві точки я визначив візуально підбором, бо параметрів екрану я не знав.

Там розмір екрана задається параметрами конструктора:

  TFT_ST7735(int16_t _W = ST7735_TFTWIDTH, int16_t _H = ST7735_TFTHEIGHT);

і за замовчуванням це 128x160.

Враховуючи всю ту "магію" з MADCTL та іншими параметрами, а також зоопарком варіантів модулів з клонами ST7735, при некоректній ініціалізації можуть невірно розраховуватись адреси пікселів, які попадають в середину пікселя, що виглядає як спотворення кольорів.
Я би для початку повиводив прості тестові зображення, щоб побачити закономірність.

З розміром екрану розібрався.

  tft.drawFastHLine(0, originY, tft.width(), TFT_WHITE); // Горизонтальная линия вправо
  tft.drawFastVLine(originX, 0, tft.height(), TFT_WHITE);	// Вертикальная линия вверх
//  tft.drawLine(endX, originY, endX - 3, originY - 3, TFT_WHITE);	// Стрелка по X
//  tft.drawLine(originX, endY, originX + 3, endY + 3, TFT_WHITE); 	// Стрелка по Y

FAST використовується тільки для горизонтальних і вертикальних ліній у графіку мені не вдалося використати FAST hmm

***  може проблеми з кольором через орієнтацію екрану hmm

  tft.setRotation(3);       // Установка ориентации экрана

Неактивний

#15 2025-04-02 10:31:43

dimich
Учасник
Зареєстрований: 2023-12-01
Повідомлень: 377

Re: рисуем график данных на TFT-дисплее

renoshnik пише:

FAST використовується тільки для горизонтальних і вертикальних ліній у графіку мені не вдалося використати FAST hmm

Там же в коді все написано. Якщо макрос FAST_LINE визначений, то звичайна drawLine() використовує оптимізований алгорим, який вертикальні та горизонтальні сегменти більше двох пікселів малює за допомогою Fast Line, тому працює швидше. Але код функції на 116 байтів більший. Якщо FAST_LINE не визначений, то drawLine() використовує класичну реалізацію алгоритму Брезенхема, яка повільніша, але менша за розміром.

renoshnik пише:

***  може проблеми з кольором через орієнтацію екрану hmm

Все може бути. Якщо ця конфігурація впливає на обчислення адреси (хоч програмно, хоч апаратно в самому контроллері), то теж може. Потрібно повиводити тестові зображення. Спочатку просто пікселі різних кольорів. З парними та непарними координатами. Якщо все ок, тоді лінії, теж різних кольорів, з парними і непарними координатами початку та кінця. Потім, по результатам, дивитись в реалізацію бібліотеки та документацію на контроллер.

Неактивний

#16 2025-04-02 12:54:17

jokeer
Гість

Re: рисуем график данных на TFT-дисплее

Дебажити чужу лібу це цікаве зайняття. Я б запропонував або дуже уважно подивитися на приклади до неї, якщо вони є, і працюють коректно - шукати різницю. Або пошукати, може є інші рішення.

#17 2025-04-02 13:11:49

renoshnik
Учасник
Зареєстрований: 2017-04-03
Повідомлень: 1,057

Re: рисуем график данных на TFT-дисплее

Для тесту запустив таку програмку

#include <TFT_ST7735.h> // Библиотека для работы с экраном
#include <SPI.h>
// Параметры подключения (замените на ваши пины)
#define CS_PIN 10
#define DC_PIN 9
#define RST_PIN 8
TFT_ST7735 tft = TFT_ST7735(); // Инициализация экрана

void setup(void) {
  tft.init();             // Инициализация экрана
  tft.setRotation(3);     // Установка ориентации экрана
  tft.fillScreen(TFT_NAVY);     // Установка начального цвета фона
  drawAxes();             // Построение осей координат
}

void loop() {
 delay(50);
 tft.drawLine(75, 0, 75, 75, TFT_GREEN); // цвет изменяется 
 delay(50);
 tft.drawLine(55, 120, 55, 20, TFT_GREEN); // цвет изменяется 
 delay(50);
 tft.drawFastVLine(25, 0, 90, TFT_GREEN); // стабильный цвет
 delay(50);
 drawAxes();               // Построение осей координат
}
//  ФУНКЦИЯ ОТРИСОВКИ БАЗОВОГО ЭКРАНА
void drawAxes() {
  // Начало координат в нижнем левом углу
  int originX = 1;      // Начало координат по X (левый край экрана)
  int endX = 158;       // Окончание координат по X (правый край экрана)
  int originY = 125;    // Начало координат по Y (нижний край экрана)
  int endY = 0;       // Окончание координат по Y (верхний край экрана)  
  // Рисуем оси X и Y
  tft.drawFastHLine(0, originY, tft.width(), TFT_WHITE); // Горизонтальная линия вправо
  tft.drawFastVLine(originX, 0, tft.height(), TFT_WHITE); // Вертикальная линия вверх
  // Добавляем стрелки на концах осей
  tft.drawLine(endX, originY, endX - 3, originY - 3, TFT_WHITE);  // Стрелка вправо
  tft.drawLine(originX, endY, originX + 3, endY + 3, TFT_WHITE);    // Стрелка вверх
  // Подписи осей
  tft.setTextColor(TFT_CYAN);
  tft.setTextSize(1);
  tft.setCursor(139, 115);  // Подпись оси X
  unsigned long _x = tft.width();
  tft.print(_x);
unsigned long _y = tft.height();  
  tft.setCursor(5, 1);    // Подпись оси Y
  tft.print(_y);
}

tft.drawLine(75, 0, 75, 75, TFT_GREEN); // цвет изменяется
tft.drawLine(55, 120, 55, 20, TFT_GREEN); // цвет изменяется
tft.drawFastVLine(25, 0, 90, TFT_GREEN); // стабильный цвет

якщо за коментувати рядок    tft.setRotation(3);     // Установка ориентации экрана

результат не змінюється  hmm  hmm  hmm

Остання редакція renoshnik (2025-04-02 13:14:13)

Неактивний

#18 2025-04-02 13:24:05

renoshnik
Учасник
Зареєстрований: 2017-04-03
Повідомлень: 1,057

Re: рисуем график данных на TFT-дисплее

В прикладах бібліотеки взяв скетч аналогового годинника

/*
  An example analogue clock using a TFT LCD screen to show the time
 use of some of the drawing commands with the ST7735 library.
 For a more accurate clock, it would be better to use the RTClib library.
 But this is just a demo. 
 
 This examples uses the hardware SPI only. Non-hardware SPI
 is just too slow (~8 times slower!)
 
 Gilchrist 6/2/2014 1.0
 Updated by Bodmer
 */

#include <TFT_ST7735.h> // Graphics and font library for ST7735 driver chip
#include <SPI.h>

TFT_ST7735 tft = TFT_ST7735();  // Invoke library, pins defined in User_Setup.h

#define ST7735_GREY 0xBDF7

float sx = 0, sy = 1, mx = 1, my = 0, hx = -1, hy = 0;    // Saved H, M, S x & y multipliers
float sdeg=0, mdeg=0, hdeg=0;
uint16_t osx=64, osy=64, omx=64, omy=64, ohx=64, ohy=64;  // Saved H, M, S x & y coords
uint16_t x0=0, x1=0, y0=0, y1=0;
uint32_t targetTime = 0;                    // for next 1 second timeout

static uint8_t conv2d(const char* p) {
  uint8_t v = 0;
  if ('0' <= *p && *p <= '9')
    v = *p - '0';
  return 10 * v + *++p - '0';
}

uint8_t hh=conv2d(__TIME__), mm=conv2d(__TIME__+3), ss=conv2d(__TIME__+6);  // Get H, M, S from compile time

boolean initial = 1;

void setup(void) {
  tft.init();
  tft.setRotation(0);
  tft.fillScreen(ST7735_GREY);
  tft.setTextColor(ST7735_GREEN, ST7735_GREY);  // Adding a black background colour erases previous text automatically
  
  // Draw clock face
  tft.fillCircle(64, 64, 61, ST7735_BLUE);
  tft.fillCircle(64, 64, 57, ST7735_BLACK);

  // Draw 12 lines
  for(int i = 0; i<360; i+= 30) {
    sx = cos((i-90)*0.0174532925);
    sy = sin((i-90)*0.0174532925);
    x0 = sx*57+64;
    y0 = sy*57+64;
    x1 = sx*50+64;
    y1 = sy*50+64;

    tft.drawLine(x0, y0, x1, y1, ST7735_BLUE);
  }

  // Draw 60 dots
  for(int i = 0; i<360; i+= 6) {
    sx = cos((i-90)*0.0174532925);
    sy = sin((i-90)*0.0174532925);
    x0 = sx*53+64;
    y0 = sy*53+64;
    
    tft.drawPixel(x0, y0, ST7735_BLUE);
    if(i==0 || i==180) tft.fillCircle(x0, y0, 1, ST7735_CYAN);
    if(i==0 || i==180) tft.fillCircle(x0+1, y0, 1, ST7735_CYAN);
    if(i==90 || i==270) tft.fillCircle(x0, y0, 1, ST7735_CYAN);
    if(i==90 || i==270) tft.fillCircle(x0+1, y0, 1, ST7735_CYAN);
  }

  tft.fillCircle(65, 65, 3, ST7735_RED);

  // Draw text at position 64,125 using fonts 4
  // Only font numbers 2,4,6,7 are valid. Font 6 only contains characters [space] 0 1 2 3 4 5 6 7 8 9 : . a p m
  // Font 7 is a 7 segment font and only contains characters [space] 0 1 2 3 4 5 6 7 8 9 : .
  tft.drawCentreString("Time flies",64,130,4);

  targetTime = millis() + 1000; 
}

void loop() {
  if (targetTime < millis()) {
    targetTime = millis()+1000;
    ss++;              // Advance second
    if (ss==60) {
      ss=0;
      mm++;            // Advance minute
      if(mm>59) {
        mm=0;
        hh++;          // Advance hour
        if (hh>23) {
          hh=0;
        }
      }
    }

    // Pre-compute hand degrees, x & y coords for a fast screen update
    sdeg = ss*6;                  // 0-59 -> 0-354
    mdeg = mm*6+sdeg*0.01666667;  // 0-59 -> 0-360 - includes seconds
    hdeg = hh*30+mdeg*0.0833333;  // 0-11 -> 0-360 - includes minutes and seconds
    hx = cos((hdeg-90)*0.0174532925);    
    hy = sin((hdeg-90)*0.0174532925);
    mx = cos((mdeg-90)*0.0174532925);    
    my = sin((mdeg-90)*0.0174532925);
    sx = cos((sdeg-90)*0.0174532925);    
    sy = sin((sdeg-90)*0.0174532925);

    if (ss==0 || initial) {
      initial = 0;
      // Erase hour and minute hand positions every minute
      tft.drawLine(ohx, ohy, 65, 65, ST7735_BLACK);
      ohx = hx*33+65;    
      ohy = hy*33+65;
      tft.drawLine(omx, omy, 65, 65, ST7735_BLACK);
      omx = mx*44+65;    
      omy = my*44+65;
    }

      // Redraw new hand positions, hour and minute hands not erased here to avoid flicker
      tft.drawLine(osx, osy, 65, 65, ST7735_BLACK);
      tft.drawLine(ohx, ohy, 65, 65, ST7735_WHITE);
      tft.drawLine(omx, omy, 65, 65, ST7735_WHITE);
      osx = sx*47+65;    
      osy = sy*47+65;
      tft.drawLine(osx, osy, 65, 65, ST7735_RED);

    tft.fillCircle(65, 65, 3, ST7735_RED);
  }
}

секундна стрілка рандомно залишає артифакти жовтого кольору ....

можливо дійсно то якість самого екрану така ...

Неактивний

#19 2025-04-02 14:54:50

jokeR
Учасник
Зареєстрований: 2024-12-12
Повідомлень: 63

Re: рисуем график данных на TFT-дисплее

https://github.com/adafruit/Adafruit-ST7735-Library/ не хочете розглянути?

Неактивний

#20 2025-04-02 17:52:44

renoshnik
Учасник
Зареєстрований: 2017-04-03
Повідомлень: 1,057

Re: рисуем график данных на TFT-дисплее

jokeR пише:

https://github.com/adafruit/Adafruit-ST7735-Library/ не хочете розглянути?

Дякую, графік тепер без зауважень ...  smile  smile  smile

Неактивний

#21 2025-04-02 18:13:59

jokeer
Гість

Re: рисуем график данных на TFT-дисплее

В мене до графіка зауважень і не було wink тут таке.. якщо чужий код працює якось не так, то або копати даташіти, або спробувати іншу реалізацію.

#22 2025-04-02 19:18:24

renoshnik
Учасник
Зареєстрований: 2017-04-03
Повідомлень: 1,057

Re: рисуем график данных на TFT-дисплее

jokeer пише:

В мене до графіка зауважень і не було wink тут таке.. якщо чужий код працює якось не так, то або копати даташіти, або спробувати іншу реалізацію.

то я ще не відвик від служби..  smile

маю на увазі, що графік з цією лібою малюється одним кольором без змін ...
стара ліба пішла в смітник ...

Неактивний

#23 2025-04-06 11:50:18

vladxxx
Учасник
Зареєстрований: 2025-04-06
Повідомлень: 2

Re: рисуем график данных на TFT-дисплее

Хлопци !!! У кого завалился лишний системные и монитор? Help. Если что помогу с проектами на stm .Я бомж с Луганска. Работаю в mikroc, kubeide.

Неактивний

Швидке повідомлення

Введіть повідомлення і натисніть Надіслати

Підвал форуму