#include <TFT_eSPI.h>
#include <SPI.h>
#include <SD.h>
TFT_eSPI tft = TFT_eSPI();
// Пины SD-карты
#define SD_CS 5
#define SD_SCLK 18
#define SD_MOSI 23
#define SD_MISO 19
// Цвета
#define DARK_YELLOW 0x7BE0 // Темно-желтый фон
#define CIRCLE_COLOR TFT_RED // Красный круг
#define OUTLINE_COLOR TFT_BLUE // Синий контур
#define TRACE_COLOR TFT_GREEN // Зеленый след
// Размер круга 3x3
#define CIRCLE_RADIUS 1 // Радиус 1 пиксель (круг 3x3)
// Переменные
int ballX = 0, ballY = 0;
int prevBallX = 0, prevBallY = 0;
int targetX = 0, targetY = 0;
float currentX = 0, currentY = 0;
float speed = 1.2;
int pointCount = 0;
File dataFile;
// Смещение (настройте под ваши координаты)
int offsetX = 0;
int offsetY = 0;
void setup() {
Serial.begin(115200);
// Инициализация дисплея
tft.init();
tft.setRotation(0);
// Подсветка
pinMode(TFT_BL, OUTPUT);
ledcSetup(0, 5000, 8);
ledcAttachPin(TFT_BL, 0);
ledcWrite(0, 255);
// Фон
tft.fillScreen(DARK_YELLOW);
// SD карта
SPI.begin(SD_SCLK, SD_MISO, SD_MOSI, SD_CS);
if (!SD.begin(SD_CS)) {
Serial.println("SD card FAIL");
while (true);
}
// Открываем файл
dataFile = SD.open("/trace(2).txt", FILE_READ);
if (!dataFile) {
Serial.println("File not found");
while (true);
}
// Пропускаем заголовок
String firstLine = dataFile.readStringUntil('\n');
Serial.print("Skipped: ");
Serial.println(firstLine);
// Первая точка
if (readNextPoint()) {
currentX = targetX;
currentY = targetY;
ballX = (int)currentX;
ballY = (int)currentY;
drawCircle3x3(ballX, ballY);
Serial.println("Ready!");
}
}
bool readNextPoint() {
if (!dataFile.available()) {
Serial.println("End of file");
dataFile.close();
return false;
}
String line = dataFile.readStringUntil('\n');
line.trim();
if (line.length() == 0) return readNextPoint();
int commaIndex = line.indexOf(',');
if (commaIndex == -1) return readNextPoint();
String xStr = line.substring(0, commaIndex);
String yStr = line.substring(commaIndex + 1);
int rawX = xStr.toInt();
int rawY = yStr.toInt();
// Применяем смещение
targetX = rawX + offsetX;
targetY = rawY + offsetY;
// Ограничиваем границы экрана
targetX = constrain(targetX, 2, TFT_WIDTH - 3);
targetY = constrain(targetY, 2, TFT_HEIGHT - 3);
pointCount++;
return true;
}
// Круг 3x3 с синим контуром
void drawCircle3x3(int x, int y) {
// Синий контур (пиксели по краям)
tft.drawPixel(x-1, y-1, OUTLINE_COLOR); // левый верх
tft.drawPixel(x+1, y-1, OUTLINE_COLOR); // правый верх
tft.drawPixel(x-1, y+1, OUTLINE_COLOR); // левый низ
tft.drawPixel(x+1, y+1, OUTLINE_COLOR); // правый низ
tft.drawPixel(x, y-1, OUTLINE_COLOR); // верх
tft.drawPixel(x-1, y, OUTLINE_COLOR); // лево
tft.drawPixel(x+1, y, OUTLINE_COLOR); // право
tft.drawPixel(x, y+1, OUTLINE_COLOR); // низ
// Красная внутренность (центр)
tft.drawPixel(x, y, CIRCLE_COLOR); // центр
}
// Зеленый след
void drawTraceLine(int x1, int y1, int x2, int y2) {
tft.drawLine(x1, y1, x2, y2, TRACE_COLOR);
}
void loop() {
// Сохраняем старую позицию
prevBallX = ballX;
prevBallY = ballY;
// Плавное движение к цели
float dx = targetX - currentX;
float dy = targetY - currentY;
float distance = sqrt(dx*dx + dy*dy);
if (distance < speed) {
// Достигли точки
currentX = targetX;
currentY = targetY;
// Читаем следующую точку
if (!readNextPoint()) {
// Конец файла
Serial.println("Finished!");
// Мигание 3 раза
for (int i = 0; i < 3; i++) {
tft.drawPixel(ballX, ballY, TFT_WHITE);
delay(200);
drawCircle3x3(ballX, ballY);
delay(200);
}
while(true) delay(1000);
}
} else {
// Двигаемся к цели
currentX += (dx / distance) * speed;
currentY += (dy / distance) * speed;
}
// Обновляем координаты шарика
ballX = (int)currentX;
ballY = (int)currentY;
// Рисуем след
if ((ballX != prevBallX || ballY != prevBallY) && pointCount > 1) {
drawTraceLine(prevBallX, prevBallY, ballX, ballY);
}
// Рисуем круг 3x3
drawCircle3x3(ballX, ballY);
delay(15); // Скорость анимации
}
вот версия 0.2 шарика который рисует на виртуальном столе)))
программу конвертации и печати G кодом так и не сделал, столкнулся еще с такой проблемой что некоторые фото программа видит с пятнами….по этому пошел к гайверу на сайт и сделал там рисунок, закинул на sd карту(если уж не фото или анимацию из фото выводить) и вроде рисует,(до конца ждать не стал) можно делать любые рисунки в принципе… и с заполнением, но экран только маленький, 128 на 160 что то маловато… а еще наверное стол сможете собрать, и рисовать на песке магнитом, переделав этот проект https://alexgyver.ru/magicgyver/ сделаете 300 рисунков и будите любоваться))) все таки sd карта мощь!))) а как там у гайвера это управляется не вникал, может даже что то сделал удобное…















