#include <SPI.h>
#include <Adafruit_GFX.h>
#include <Adafruit_ILI9341.h>
// --- ПИНЫ ДИСПЛЕЯ (SPI) ---
#define TFT_CS 10
#define TFT_DC 8
#define TFT_RST 9
// --- ПИН PIR ДАТЧИКА ---
#define PIR_PIN 3
// Создаем объект дисплея
Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC, TFT_RST);
// --- ПЕРЕМЕННЫЕ ДЛЯ КВАДРАТА ---
float x = 115, y = 115; // Начальная позиция (центр экрана)
float speedX = 1.5, speedY = 1.8; // Скорость
int squareSize = 10; // Размер квадрата 10x10
int squareColor = ILI9341_RED; // Текущий цвет квадрата
// --- ПЕРЕМЕННЫЕ ДЛЯ ФОНА ---
int bgColor = ILI9341_BLACK; // Начальный цвет фона
// --- СПИСОК ЦВЕТОВ ДЛЯ КВАДРАТА ---
int colors[] = {
ILI9341_RED,
ILI9341_GREEN,
ILI9341_BLUE,
ILI9341_YELLOW,
ILI9341_CYAN,
ILI9341_MAGENTA,
ILI9341_ORANGE,
ILI9341_PINK
};
int colorCount = 8;
// --- ПЕРЕМЕННАЯ ДЛЯ PIR (защита от ложных срабатываний) ---
int lastPirState = LOW;
void setup() {
// 1. Запускаем дисплей
tft.begin();
tft.setRotation(1); // Горизонтальная ориентация (ширина 320, высота 240)
tft.fillScreen(bgColor);
// 2. Настраиваем пин PIR датчика
pinMode(PIR_PIN, INPUT);
}
void loop() {
// ========== ЧАСТЬ 1: ОБРАБОТКА PIR ДАТЧИКА (меняем фон) ==========
int pirState = digitalRead(PIR_PIN);
// Если датчик сработал (HIGH) и раньше был LOW (только в момент срабатывания)
if (pirState == HIGH && lastPirState == LOW) {
// Меняем цвет фона по кругу
if (bgColor == ILI9341_BLACK) bgColor = ILI9341_BLUE;
else if (bgColor == ILI9341_BLUE) bgColor = ILI9341_DARKGREEN;
else if (bgColor == ILI9341_DARKGREEN) bgColor = ILI9341_PURPLE;
else if (bgColor == ILI9341_PURPLE) bgColor = ILI9341_MAROON;
else bgColor = ILI9341_BLACK;
tft.fillScreen(bgColor);
delay(200); // Небольшая задержка, чтобы датчик не срабатывал несколько раз подряд
}
lastPirState = pirState;
// ========== ЧАСТЬ 2: ФИЗИКА ДВИЖЕНИЯ КВАДРАТА ==========
// 2.1 Стираем старый квадрат (заливаем цветом фона)
tft.fillRect((int)x, (int)y, squareSize, squareSize, bgColor);
// 2.2 Обновляем координаты
x += speedX;
y += speedY;
// 2.3 Проверка столкновения со стенами (отскок и смена цвета)
bool colorChanged = false; // Флаг: цвет уже поменяли в этом кадре
// Проверка по вертикали (верхняя и нижняя стены)
if (y <= 0 || (y + squareSize) >= tft.height()) {
speedY = -speedY; // Разворачиваем скорость
if (!colorChanged) {
squareColor = colors[random(0, colorCount)]; // Меняем цвет
colorChanged = true;
}
// Корректируем позицию, чтобы квадрат не вылезал за края
y = constrain(y, 0, tft.height() - squareSize);
}
// Проверка по горизонтали (левая и правая стены)
if (x <= 0 || (x + squareSize) >= tft.width()) {
speedX = -speedX; // Разворачиваем скорость
if (!colorChanged) {
squareColor = colors[random(0, colorCount)]; // Меняем цвет
colorChanged = true;
}
// Корректируем позицию
x = constrain(x, 0, tft.width() - squareSize);
}
// 2.4 Рисуем квадрат в НОВОМ месте и НОВЫМ цветом
tft.fillRect((int)x, (int)y, squareSize, squareSize, squareColor);
// 2.5 Задержка для плавности (частота кадров)
delay(10);
}