#include <FastLED.h>
#define WIDTH 16 //Ширина матрицы
#define HEIGHT 16 //Высота матрицы
#define LED_PIN 13 //Пин подключения матрицы на ардуино
#define BUTTON_PIN 2 //Пин подключения кнопки на ардуино
#define NUM_LEDS (WIDTH * HEIGHT) //Общее количество светодиодов
#define BRIGHTNESS 255 //Яркость (0-255)
#define INTENSITY 45 //Интенсивность (0-50)
#define MAX_CIRCLES 3 //Максимальное количество окружностей
float MAX_R = sqrt(WIDTH * WIDTH + HEIGHT * HEIGHT) + 1;
char MODE = 1; //1 - цвет от радиуса, 2 - цвет от пикселя
CRGB leds[NUM_LEDS]; //Массив для светодиодов
char circles[MAX_CIRCLES][3] = {0}; //Инициализация окружностей {x, y, r}
char lenPush = 0; //Длина нажатия
void setup() {
FastLED.addLeds<WS2811, LED_PIN, GRB>(leds, NUM_LEDS);
FastLED.setBrightness(BRIGHTNESS);
pinMode(BUTTON_PIN, INPUT_PULLUP);
Serial.begin(9600);
randomSeed(analogRead(0));
}
void DrawCircle(char x0, char y0, char radius) {
char x = 0;
char y = radius;
char delta = 1 - 2 * radius;
char error = 0;
char res;
if (MODE == 1)
res = radius * 10;
while(y >= 0) {
if (MODE == 2)
res = ((x + WIDTH) * (y + HEIGHT));
if (x0 + x >= 0 && x0 + x < WIDTH && y0 + y >= 0 && y0 + y < HEIGHT)
leds[XY(x0 + x, y0 + y)].setHue(res);
if (x0 + x >= 0 && x0 + x < WIDTH && y0 - y >= 0 && y0 - y < HEIGHT)
leds[XY(x0 + x, y0 - y)].setHue(res);
if (x0 - x >= 0 && x0 - x < WIDTH && y0 + y >= 0 && y0 + y < HEIGHT)
leds[XY(x0 - x, y0 + y)].setHue(res);
if (x0 - x >= 0 && x0 - x < WIDTH && y0 - y >= 0 && y0 - y < HEIGHT)
leds[XY(x0 - x, y0 - y)].setHue(res);
error = 2 * (delta + y) - 1;
if(delta < 0 && error <= 0) {
++x;
delta += 2 * x + 1;
continue;
}
if(delta >= 0 && error > 0) {
--y;
delta += 1 - 2 * y;
continue;
}
++x;
delta += 2 * (x - y);
--y;
}
}
void NextStep() { //Функция обновления состояния доски
for (char i = 0; i < HEIGHT; i++) { //Очистка светодиодов
for (char j = 0; j < WIDTH; j++) {
leds[XY(i, j)] = CRGB::Black;
}
}
if (random(50 - INTENSITY) == 0) { //Случайная точка центра окружности
for (char i = 0; i < MAX_CIRCLES; i++) {
if (circles[i][2] == 0) {
circles[i][0] = random(WIDTH);
circles[i][1] = random(HEIGHT);
circles[i][2] = MAX_R;
break;
}
}
}
float x1, y1, step;
char x, y, r;
for (char i = 0; i < MAX_CIRCLES; i++) {
if (circles[i][2] != 0) {
DrawCircle(circles[i][0], circles[i][1], MAX_R - circles[i][2]);
circles[i][2] -= 1;
}
}
}
int XY(char x, char y) { //Функция преобразования координат
return ((WIDTH - x) * WIDTH - (HEIGHT - y));
}
void SetNextMode() { //Смена режима
for (char i = 0; i < HEIGHT; i++) {
for (char j = 0; j < WIDTH; j++) {
leds[XY(i, j)] = CRGB::Black;
}
}
for (char i = 0; i < MAX_CIRCLES; i++) {
circles[i][0] = 0;
circles[i][1] = 0;
circles[i][2] = 0;
}
if (MODE == 1)
MODE = 2;
else if (MODE == 2)
MODE = 1;
}
void loop() {
if (digitalRead(BUTTON_PIN) == LOW) {
lenPush += 1;
}
else if (digitalRead(BUTTON_PIN) != LOW && lenPush != 0) {
if (lenPush < 16)
SetNextMode();
lenPush = 0;
}
FastLED.show();
delay(100);
NextStep(); //Переход к следующему поколению
}