/*
Скетч к проекту "Адресная матрица"
Гайд по постройке матрицы: https://alexgyver.ru/matrix_guide/
Страница проекта (схемы, описания): https://alexgyver.ru/GyverMatrixBT/
Подробное описание прошивки: https://alexgyver.ru/gyvermatrixos-guide/
Исходники на GitHub: https://github.com/AlexGyver/GyverMatrixBT/
Нравится, как написан код? Поддержи автора! https://alexgyver.ru/support_alex/
Автор: AlexGyver Technologies, 2018
https://AlexGyver.ru/
*/
// GyverMatrixOS
// Версия прошивки 1.71, совместима с приложением GyverMatrixBT версии 1.8 и выше
// ************************ МАТРИЦА *************************
// если прошивка не лезет в Arduino NANO - отключай режимы! Строка 53 и ниже
#define BRIGHTNESS 200 // // 150 // стандартная маскимальная яркость (0-255)
#define CURRENT_LIMIT 2000 // лимит по току в миллиамперах, автоматически управляет яркостью (пожалей свой блок питания!) 0 - выключить лимит
#define WIDTH 11 // ширина матрицы
#define HEIGHT 11 // высота матрицы
#define MATRIX_TYPE 0 // тип матрицы: 0 - зигзаг, 1 - последовательная
#define CONNECTION_ANGLE 0 // угол подключения: 0 - левый нижний, 1 - левый верхний, 2 - правый верхний, 3 - правый нижний
#define STRIP_DIRECTION 1 // направление ленты из угла: 0 - вправо, 1 - вверх, 2 - влево, 3 - вниз
// при неправильной настрйоке матрицы вы получите предупреждение "Wrong matrix parameters! Set to default"
// шпаргалка по настройке матрицы здесь! https://alexgyver.ru/matrix_guide/
#define MCU_TYPE 0 // микроконтроллер:
// 0 - AVR (Arduino NANO/MEGA/UNO)
// 1 - ESP8266 (NodeMCU, Wemos D1)
// 2 - STM32 (Blue Pill)
// ***************************** НАСТРОЙКИ *****************************
// ----- настройка ИК пульта
#define REMOTE_TYPE 1 // 0 - без пульта, 1 - пульт от WAVGAT, 2 - пульт от KEYES, 3 - кастомный пульт
// система может работать С ЛЮБЫМ ИК ПУЛЬТОМ (практически). Коды для своего пульта можно задать начиная со строки 160 в прошивке. Коды пультов определяются скетчем IRtest_2.0, читай инструкцию
// ----- настройки параметров
#define KEEP_SETTINGS 1 // хранить ВСЕ настройки в энергонезависимой памяти
#define KEEP_STATE 1 // сохранять в памяти состояние вкл/выкл системы (с пульта)
#define RESET_SETTINGS 0 // сброс настроек в EEPROM памяти (поставить 1, прошиться, поставить обратно 0, прошиться. Всё)
#define SETTINGS_LOG 0 // вывод всех настроек из EEPROM в порт при запуске
// ----- настройки ленты
#define NUM_LEDS WIDTH * HEIGHT /////NUM_LEDS 60 // количество светодиодов (данная версия поддерживает до 410 штук)
#define CURRENT_LIMIT 3000 // лимит по току в МИЛЛИАМПЕРАХ, автоматически управляет яркостью (пожалей свой блок питания!) 0 - выключить лимит
///////byte BRIGHTNESS = 200; // яркость по умолчанию (0 - 255)
// ----- пины подключения
#define SOUND_R A2 // аналоговый пин вход аудио, правый канал
#define SOUND_L A1 // аналоговый пин вход аудио, левый канал
#define SOUND_R_FREQ A3 // аналоговый пин вход аудио для режима с частотами (через кондер)
#define BTN_PIN 3 // кнопка переключения режимов (PIN --- КНОПКА --- GND)
#if defined(__AVR_ATmega32U4__) // Пины для Arduino Pro Micro (смотри схему для Pro Micro на странице проекта!!!)
#define MLED_PIN 17 // пин светодиода режимов на ProMicro, т.к. обычный не выведен.
#define MLED_ON LOW
#define LED_PIN 9 // пин DI светодиодной ленты на ProMicro, т.к. обычный не выведен.
#else // Пины для других плат Arduino (по умолчанию)
#define MLED_PIN 13 // пин светодиода режимов
#define MLED_ON HIGH
#define LED_PIN 12 // пин DI светодиодной ленты
#endif
#define POT_GND A0 // пин земля для потенциометра
#define IR_PIN 2 // пин ИК приёмника
// ----- настройки радуги
float RAINBOW_STEP = 5.00; // шаг изменения цвета радуги
// ----- отрисовка
#define MODE 0 // режим при запуске
#define MAIN_LOOP 5 // период основного цикла отрисовки (по умолчанию 5)
// ----- сигнал
#define MONO 1 // 1 - только один канал (ПРАВЫЙ!!!!! SOUND_R!!!!!), 0 - два канала
#define EXP 1.4 // степень усиления сигнала (для более "резкой" работы) (по умолчанию 1.4)
#define POTENT 0 // 1 - используем потенциометр, 0 - используется внутренний источник опорного напряжения 1.1 В
byte EMPTY_BRIGHT = 30; // яркость "не горящих" светодиодов (0 - 255)
#define EMPTY_COLOR HUE_PURPLE // цвет "не горящих" светодиодов. Будет чёрный, если яркость 0
// ----- нижний порог шумов
uint16_t LOW_PASS = 100; // нижний порог шумов режим VU, ручная настройка
uint16_t SPEKTR_LOW_PASS = 40; // нижний порог шумов режим спектра, ручная настройка
#define AUTO_LOW_PASS 0 // разрешить настройку нижнего порога шумов при запуске (по умолч. 0)
#define EEPROM_LOW_PASS 1 // порог шумов хранится в энергонезависимой памяти (по умолч. 1)
#define LOW_PASS_ADD 13 // "добавочная" величина к нижнему порогу, для надёжности (режим VU)
#define LOW_PASS_FREQ_ADD 3 // "добавочная" величина к нижнему порогу, для надёжности (режим частот)
// ----- режим шкала громкости
float SMOOTH = 0.3; // коэффициент плавности анимации VU (по умолчанию 0.5)
#define MAX_COEF 1.8 // коэффициент громкости (максимальное равно срднему * этот коэф) (по умолчанию 1.8)
// ----- режим цветомузыки
float SMOOTH_FREQ = 0.8; // коэффициент плавности анимации частот (по умолчанию 0.8)
float MAX_COEF_FREQ = 1.2; // коэффициент порога для "вспышки" цветомузыки (по умолчанию 1.5)
#define SMOOTH_STEP 20 // шаг уменьшения яркости в режиме цветомузыки (чем больше, тем быстрее гаснет)
#define LOW_COLOR HUE_RED // цвет низких частот
#define MID_COLOR HUE_GREEN // цвет средних
#define HIGH_COLOR HUE_YELLOW // цвет высоких
// ----- режим стробоскопа
uint16_t STROBE_PERIOD = 140; // период вспышек, миллисекунды
#define STROBE_DUTY 20 // скважность вспышек (1 - 99) - отношение времени вспышки ко времени темноты
#define STROBE_COLOR HUE_YELLOW // цвет стробоскопа
#define STROBE_SAT 0 // насыщенность. Если 0 - цвет будет БЕЛЫЙ при любом цвете (0 - 255)
byte STROBE_SMOOTH = 200; // скорость нарастания/угасания вспышки (0 - 255)
// ----- режим подсветки
byte LIGHT_COLOR = 0; // начальный цвет подсветки
byte LIGHT_SAT = 255; // начальная насыщенность подсветки
byte COLOR_SPEED = 100;
int RAINBOW_PERIOD = 1;
float RAINBOW_STEP_2 = 0.5;
// ----- режим бегущих частот
byte RUNNING_SPEED = 11;
// ----- режим анализатора спектра
byte HUE_START = 0;
byte HUE_STEP = 5;
#define LIGHT_SMOOTH 2
/*
Цвета для HSV
HUE_RED
HUE_ORANGE
HUE_YELLOW
HUE_GREEN
HUE_AQUA
HUE_BLUE
HUE_PURPLE
HUE_PINK
*/
// ------------------------------ ДЛЯ РАЗРАБОТЧИКОВ --------------------------------
#define MODE_AMOUNT 9 // количество режимов
#define STRIPE NUM_LEDS / 5
float freq_to_stripe = NUM_LEDS / 40; // /2 так как симметрия, и /20 так как 20 частот
#define FHT_N 64 // ширина спектра х2
#define LOG_OUT 1
#include "FHT.h" // преобразование Хартли
#include "EEPROMex.h"
#define FASTLED_ALLOW_INTERRUPTS 1
#include "FastLED.h"
CRGB leds[NUM_LEDS];
#include "GyverButton.h"
GButton butt1(BTN_PIN);
#include "IRLremote.h"
CHashIR IRLremote;
uint32_t IRdata;
// градиент-палитра от зелёного к красному
DEFINE_GRADIENT_PALETTE(soundlevel_gp) {
0, 0, 255, 0, // green
100, 255, 255, 0, // yellow
150, 255, 100, 0, // orange
200, 255, 50, 0, // red
255, 255, 0, 0 // red
};
CRGBPalette32 myPal = soundlevel_gp;
int Rlenght, Llenght;
float RsoundLevel, RsoundLevel_f;
float LsoundLevel, LsoundLevel_f;
float averageLevel = 50;
int maxLevel = 100;
int MAX_CH = NUM_LEDS / 2;
int hue;
unsigned long main_timer, hue_timer, strobe_timer, running_timer, color_timer, rainbow_timer, eeprom_timer;
float averK = 0.006;
byte count;
float index = (float)255 / MAX_CH; // коэффициент перевода для палитры
boolean lowFlag;
byte low_pass;
int RcurrentLevel, LcurrentLevel;
int colorMusic[3];
float colorMusic_f[3], colorMusic_aver[3];
boolean colorMusicFlash[3], strobeUp_flag, strobeDwn_flag;
byte this_mode = MODE;
int thisBright[3], strobe_bright = 0;
unsigned int light_time = STROBE_PERIOD * STROBE_DUTY / 100;
volatile boolean ir_flag;
boolean settings_mode, ONstate = true;
int8_t freq_strobe_mode, light_mode;
int freq_max;
float freq_max_f, rainbow_steps;
int freq_f[32];
int this_color;
boolean running_flag[3], eeprom_flag;
#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
// гирлянда ******************** ЭФФЕКТЫ И РЕЖИМЫ ********************
#define D_TEXT_SPEED 100 // скорость бегущего текста по умолчанию (мс)
#define D_EFFECT_SPEED 80 // скорость эффектов по умолчанию (мс)
#define D_GAME_SPEED 250 // скорость игр по умолчанию (мс)
#define D_GIF_SPEED 80 // скорость гифок (мс)
#define DEMO_GAME_SPEED 60 // скорость игр в демо режиме (мс)
boolean AUTOPLAY = 1; // 0 выкл / 1 вкл автоматическую смену режимов
#define AUTOPLAY_PERIOD 10 // время между авто сменой режимов (секунды)
#define IDLE_TIME 1 // время бездействия кнопок или Bluetooth (в секундах) после которого запускается автосмена режимов и демо в играх
// о поддерживаемых цветах читай тут https://alexgyver.ru/gyvermatrixos-guide/
#define GLOBAL_COLOR_1 CRGB::Green // основной цвет №1 для игр
#define GLOBAL_COLOR_2 CRGB::Orange // основной цвет №2 для игр
#define SCORE_SIZE 0 // размер символов счёта в игре. 0 - маленький для 8х8 (шрифт 3х5), 1 - большой (шрифт 5х7)
#define FONT_TYPE 1 // (0 / 1) два вида маленького шрифта в выводе игрового счёта
// ************** ОТКЛЮЧЕНИЕ КОМПОНЕНТОВ СИСТЕМЫ (для экономии памяти) *************
#define USE_BUTTONS 0 // использовать физические кнопки управления играми (0 нет, 1 да)
#define BT_MODE 0 // использовать блютус (0 нет, 1 да)
#define USE_NOISE_EFFECTS 1 // крутые полноэкранные эффекты (0 нет, 1 да) СИЛЬНО ЖРУТ ПАМЯТЬ!!!11
#define USE_FONTS 1 // использовать буквы (бегущая строка) (0 нет, 1 да)
#define USE_CLOCK 0 // использовать часы (0 нет, 1 да)
// игры
#define USE_SNAKE 0 // игра змейка (0 нет, 1 да)
#define USE_TETRIS 0 // игра тетрис (0 нет, 1 да)
#define USE_MAZE 0 // игра лабиринт (0 нет, 1 да)
#define USE_RUNNER 0 // игра бегалка-прыгалка (0 нет, 1 да)
#define USE_FLAPPY 0 // игра flappy bird
#define USE_ARKAN 0 // игра арканоид
// ****************** ПИНЫ ПОДКЛЮЧЕНИЯ *******************
// Arduino (Nano, Mega)
#if (MCU_TYPE == 0)
#define LED_PIN 7 // пин ленты
#define BUTT_UP 3 // кнопка вверх
#define BUTT_DOWN 5 // кнопка вниз
#define BUTT_LEFT 2 // кнопка влево
#define BUTT_RIGHT 4 // кнопка вправо
#define BUTT_SET 6 // кнопка выбор/игра
// пины подписаны согласно pinout платы, а не надписям на пинах!
// esp8266 - плату выбирал Wemos D1 R1
#elif (MCU_TYPE == 1)
#define LED_PIN 2 // пин ленты
#define BUTT_UP 14 // кнопка вверх
#define BUTT_DOWN 13 // кнопка вниз
#define BUTT_LEFT 16 // кнопка влево
#define BUTT_RIGHT 12 // кнопка вправо
#define BUTT_SET 15 // кнопка выбор/игра
// STM32 (BluePill) - плату выбирал STM32F103C
#elif (MCU_TYPE == 2)
#define LED_PIN PB12 // пин ленты
#define BUTT_UP PA1 // кнопка вверх
#define BUTT_DOWN PA3 // кнопка вниз
#define BUTT_LEFT PA0 // кнопка влево
#define BUTT_RIGHT PA2 // кнопка вправо
#define BUTT_SET PA4 // кнопка выбор/игра
#endif
// ******************************** ДЛЯ РАЗРАБОТЧИКОВ ********************************
#define DEBUG 0
#define NUM_LEDS WIDTH * HEIGHT
//#include "FastLED.h"
// //CRGB leds[NUM_LEDS];
String runningText = "";
static const byte maxDim = max(WIDTH, HEIGHT);
byte buttons = 4; // 0 - верх, 1 - право, 2 - низ, 3 - лево, 4 - не нажата
int globalBrightness = BRIGHTNESS;
byte globalSpeed = 200;
uint32_t globalColor = 0x00ff00; // цвет при запуске зелёный
byte breathBrightness;
boolean loadingFlag = true;
byte frameNum;
int gameSpeed = DEMO_GAME_SPEED;
boolean gameDemo = true;
boolean idleState = true; // флаг холостого режима работы
boolean BTcontrol = false; // флаг контроля с блютус. Если false - управление с кнопок
int8_t thisMode = 0;
boolean controlFlag = false;
boolean gamemodeFlag = false;
boolean mazeMode = false;
int effects_speed = D_EFFECT_SPEED;
int8_t hrs = 10, mins = 25, secs;
boolean dotFlag;
byte modeCode; // 0 бегущая, 1 часы, 2 игры, 3 нойс маднесс и далее, 21 гифка или картинка
boolean fullTextFlag = false;
#define autoplayTime ((long)AUTOPLAY_PERIOD * 1000)
uint32_t autoplayTimer;
#include "timerMinim.h"
timerMinim effectTimer(D_EFFECT_SPEED);
timerMinim gameTimer(DEMO_GAME_SPEED);
timerMinim scrollTimer(D_TEXT_SPEED);
timerMinim idleTimer((long)IDLE_TIME * 1000);
timerMinim changeTimer(70);
timerMinim halfsecTimer(500);
#if (USE_CLOCK == 1 && (MCU_TYPE == 0 || MCU_TYPE == 1))
#include <Wire.h>
#include "RTClib.h"
RTC_DS3231 rtc;
// RTC_DS1307 rtc;
#endif
void setup() {
#if (BT_MODE == 1)
Serial.begin(9600);
#endif
#if (USE_CLOCK == 1 && (MCU_TYPE == 0 || MCU_TYPE == 1))
rtc.begin();
if (rtc.lostPower()) {
rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
}
DateTime now = rtc.now();
secs = now.second();
mins = now.minute();
hrs = now.hour();
#endif
// настройки ленты
FastLED.addLeds<WS2812, LED_PIN, RGB>(leds, NUM_LEDS).setCorrection( TypicalLEDStrip );
FastLED.setBrightness(BRIGHTNESS);
if (CURRENT_LIMIT > 0) FastLED.setMaxPowerInVoltsAndMilliamps(5, CURRENT_LIMIT);
FastLED.clear();
FastLED.show();
// randomSeed(analogRead(0) + analogRead(1)); // пинаем генератор случайных чисел
}
void loop() {
customRoutine();
// bluetoothRoutine();
}