// Устройство №2: ESP8266 D1 mini с матрицей MAX7219
// Непрерывное подключение к серверу и отображение данных о шуме в виде эффекта "от центра к краям" без мерцания

#include <ESP8266WiFi.h>
#include <WiFiClient.h>
#include <LedControl.h>

const char* ssid = "Beeline_2G_A7F18A";       // Замените на название вашей Wi-Fi сети
const char* password = "iD2tAXJN3e";          // Замените на пароль от вашей Wi-Fi сети

const char* serverIP = "192.168.1.12";        // IP-адрес сервера (устройство №1)
const uint16_t serverPort = 5000;             // Порт сервера

// Настройки матрицы MAX7219 и пинов
const uint8_t pinDIN = D6;   // Data In (DIN) подключен к D6
const uint8_t pinCLK = D5;   // Clock (CLK) подключен к D5
const uint8_t pinCS  = D7;   // Chip Select (CS) подключен к D7

LedControl lc = LedControl(pinDIN, pinCLK, pinCS, 1); // Последний параметр - количество устройств (матриц)

WiFiClient client;

// Параметры для визуализации
const int matrixSize = 8;
byte displayBuffer[matrixSize]; // Буфер для хранения состояния матрицы

void setup() {
  Serial.begin(115200);

  Serial.println("Запуск ESP8266...");
  Serial.println("Подключение к Wi-Fi сети...");

  WiFi.mode(WIFI_STA); // Режим станции
  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED) {
    delay(100);
    Serial.print(".");
  }

  Serial.println("\nWi-Fi подключен.");
  Serial.print("IP-адрес устройства: ");
  Serial.println(WiFi.localIP());

  // Инициализация матрицы MAX7219
  lc.shutdown(0, false);        // Включаем матрицу
  lc.setIntensity(0, 8);        // Яркость от 0 (мин) до 15 (макс)
  lc.clearDisplay(0);           // Очищаем дисплей

  // Инициализация буфера дисплея
  clearDisplayBuffer();

  // Подключение к серверу
  connectToServer();
}

void loop() {
  if (client.connected()) {
    while (client.available()) {
      String input = client.readStringUntil('\n');

      int noiseLevel = input.toInt();

      // Преобразование уровня шума в количество слоёв (от 1 до 4)
      int layers = map(noiseLevel, 0, 4095, 1, 4);
      layers = constrain(layers, 1, 4);

      // Обновление визуализации
      updateDisplayBuffer(layers);

      // Отображение буфера на матрице
      showDisplay();
    }
  } else {
    // Если соединение потеряно, пытаемся переподключиться
    Serial.println("Соединение с сервером потеряно. Повторное подключение...");
    connectToServer();
  }

  // Небольшая задержка для плавности работы
  delay(20);
}

void connectToServer() {
  while (!client.connected()) {
    Serial.println("Подключение к серверу...");
    if (client.connect(serverIP, serverPort)) {
      Serial.println("Соединение с сервером установлено.");
    } else {
      Serial.println("Не удалось подключиться к серверу. Повтор через 1 секунду.");
      delay(1000);
    }
  }
}

void clearDisplayBuffer() {
  memset(displayBuffer, 0, sizeof(displayBuffer));
}

void updateDisplayBuffer(int layers) {
  // Очищаем буфер дисплея
  clearDisplayBuffer();

  // Вычисляем позиции для зажигания светодиодов в зависимости от количества слоёв
  int start = 3 - (layers - 1);
  int end = 4 + (layers - 1);

  start = constrain(start, 0, 7);
  end = constrain(end, 0, 7);

  // Обновляем буфер дисплея
  for (int x = start; x <= end; x++) {
    for (int y = start; y <= end; y++) {
      displayBuffer[y] |= (1 << x);
    }
  }
}

void showDisplay() {
  // Отображаем буфер на матрице
  for (int y = 0; y < matrixSize; y++) {
    lc.setRow(0, y, displayBuffer[y]);
  }
} давай в кодеде изменение , чтоб при отсутсвии повышенного шума центральные диоды имели малую яркость а кошда диодная матрица реагирует на звук , диоды горели с яркостью 8