Главная страница
Навигация по странице:

  • 2.4 Разработка функциональной схемы САР

  • 2.5 Выбор аппаратных и аппаратно-программных технических средств автоматизации

  • 2.6 Разработка алгоритма и программы

  • курсач. Разработать алгоритм и программу рассмотреть вопросы охраны труда и окружающей среды


    Скачать 416.5 Kb.
    НазваниеРазработать алгоритм и программу рассмотреть вопросы охраны труда и окружающей среды
    Анкоркурсач
    Дата29.04.2022
    Размер416.5 Kb.
    Формат файлаdoc
    Имя файлакурсач.doc
    ТипДокументы
    #504753
    страница2 из 3
    1   2   3
    2.3 Разработка структурной схемы системы автоматизации

    Для реализации устройства бегущая строка требуется, прежде всего, отображение информации для визуального восприятия, что будет производиться с помощью контроллера Uno. Способ индикации текста на табло динамический, т.е. в определенные моменты времени будет индицироваться один из рядов светодиодов, позиции зажженных столбцов светодиодов будут определяться регистрами сдвига, подключенными по одному каждому из знакомест. Между собой регистры сдвига подключаются последовательно, выход предыдущего на вход последующего, ко входу первого подключен управляющий вывод микроконтроллера, к каждому из регистров параллельно подключен тактовый сигнал, заведенный от второго управляющего вывода микроконтроллера. На рисунке 1 представлена структурная схема.


    Рисунок 1 Структурная схема

    Контроль над формированием текста на табло блока индикации производится управляющим устройством (УУ), основной частью которого является микроконтроллер. Блок УУ будет попеременно зажигать каждый ряд и в то же время заносить нужную информацию в регистры сдвига, таким образом, формируя картинку, в частном случае заданный текст. Текст будет храниться в оперативной памяти (ОЗУ) микроконтроллера в виде кода символов в кодировке ASCII, по прочтении символа из ОЗУ вектор выполнения программы будет смещаться на соответствующую строку таблицы символов записанной в памяти программ, и по данным этой строки сформируется символ на табло. Для реализации эффекта бегущей строки указатель на начало строки в ОЗУ, будет увеличиваться на 1 (инкрементироваться) каждые 0,5 с, таким образом, будет осуществляться посимвольный сдвиг читаемого текста из памяти, а на табло будет заметен его бег. Для создания эффекта цикличного бега текста вводится метка конца текста, при обнаружении которой микроконтроллер будет обнулять указатель на начало строки. интерфейс рекламный микроконтроллер компьютер

    Связь с компьютером осуществляется по USB, для корректного преобразования уровней сигнала с микроконтроллера на COM-порт ПК предусмотрен блок связи (БС). Данные в виде символов в кодировке ASCII поступают с ПК, принятые данные, записываются в ОЗУ, по окончании их записи формируется метка конца текста.

    Для питания схемы используется блок питания (БП), который понижает входное напряжение с 220В до 5В, а также преобразует переменное напряжение 50/60 Гц в постоянное.

    2.4 Разработка функциональной схемы САР

    Светодиодная матрица представляет собой набор из светодиодов, соединенных по строкам и столбцам. Аноды светодиодов образуют строковые сигналы управления, а катоды - сигналы столбцов. Информация загружается в микроконтроллер, который управляет всем устройством. Верхними ключами строк контроллер управляет непосредственно с выходов своих 8-битных портов. Текст, выводимый бегущей строкой, а также все параметры этого текста, спецэффекты, хранятся в контроллере.

    На рисунке 2 представлена функциональная схема устройства



    Рисунок 2 - Функциональная схема устройства

    Настройка работы бегущей строки, запись текста, параметров осуществляются с ПК через USB. Стандартный COM-порт ПК имеет всего 8 сигналов, из которых используется всего 2: TxD - передача данных и RxD - прием данных. Обмен данными осуществляется в полудуплексном режиме, по протоколу Modbus ASCII.

    Модуль времени представляет собой интегральную микросхему типа DS3231. Данные выдаются в цифровом виде. Этот уникальный интерфейс позволяет передавать команды и данные в обоих направлениях всего по одному проводу, а также запитывать сам датчик от этого же провода. Разумеется, для подключения датчика требуется также "земляной" провод. Более того, специальная система адресации и связанных с этими командами позволяет посадить на общую шину неограниченное число датчиков, благодаря наличию у каждого датчика уникального, неповторяющегося, 64-битного адреса, записываемого при их производстве. В данном устройстве подключение нескольких датчиков не требуется, поэтому эта возможность не используется. Корректность передаваемых по интерфейсу информации проверяется специальным 8-битным циклическим кодом CRC8.

    Питание табло осуществляется от внешнего источника постоянного тока. +5В вырабатывает напряжение, необходимое для работы цифровых микросхем. Для питания светодиодной матрицы используется блок питания, к выходу которого подключаются ключи строк и столбцов. Это позволяет исключить использование токоограничительных резисторов в цепях столбцов и повысить яркость изображения за счет быстрого переключения между строками. Вместе с резисторами светодиоды создавали бы RC-цепь с ограниченным временем нарастания тока, что при динамической развертке изображения крайне нежелательно.

    2.5 Выбор аппаратных и аппаратно-программных технических средств автоматизации

    Программирование Arduino осуществляется в специальной среде разработки Arduino IDE. Данное ПО является открытым и доступно для таких операционных систем как Windows, Mac OS, и GNU/Linux.

    На рисунке 3 представлена программа Arduino.



    Рисунок 3 Программа Arduino

    В начале программирования необходимо подключить аппаратную платформу к ПК, в среде разработки выбрать порт и платформу. ArduinoMicro является аналогом платформы Arduino Leonardo, поэтому выбрать нужно эту платформу. Выбор платформы влияет на: параметры (напр.: скорость ЦП и скорость передачи данных), используемые при компиляции и загрузке скетчей и на настройки записи загрузчика (Bootloader) микроконтроллера. Некоторые характеристики платформ различаются только по последнему параметру (загрузка Bootloader), таким образом, даже при удачной загрузке с соответствующим выбором может потребоваться проверка различия перед записью загрузчика. В начале программы, как и в программах на C задаются переменные. Программа (скетч) состоит из двух функций, setup() и loop().

    Функция setup() вызывается только один раз, после подачи питания или сброса платы, когда стартует скетч. Используется для инициализации переменных, определения режимов работы выводов, запуска используемых библиотек и т.д. В ней, с помощью функции pinMode задаем режим работы пина платы как входа.

    Функция loop() выполняется в цикле. В ней, с помощью функции digitalRead считываются значения состояния входа 4 платы (HIGH или LOW), и с помощью конструкции if..else выполняет действия, в зависимости от состояния входа. Если на вход подается высокий уровень (кнопка нажата), с помощью Serial.println на порт посылается строка символов, за которой следует перенос строки и устанавливается десятисекундный перерыв в работе программы. Если же на входе низкий уровень, программа не выполняет ничего и цикл повторяется.

    После написания программы ее необходимо скомпилировать и загрузить на устройство с помощью среды разработки Arduino.

    Выбор микроконтроллера.

    Плата Arduino Uno в ее основе лежит чип ATmega в последней ревизии Ардуино Uno R3 это ATmega328. Платформа имеет 14 цифровых вход/выходов (6 из которых могут использоваться как выходы ШИМ), 6 аналоговых входов, кварцевый генератор 16 МГц, разъем USB, силовой разъем, разъем ICSP и кнопку перезагрузки. Для работы необходимо подключить платформу к компьютеру посредством кабеля USB, либо подать питание при помощи адаптера AC/DC или батареи.

    Arduino Uno может получать питание через подключение USB или от внешнего источника питания. Источник питания выбирается автоматически.

    Внешнее питание (не USB) может подаваться через преобразователь напряжения AC/DC (блок питания) или аккумуляторной батареей. Преобразователь напряжения подключается посредством разъема 2.1 мм с центральным положительным полюсом. Провода от батареи подключаются к выводам Gnd и Vin разъема питания.

    Платформа может работать при внешнем питании от 6 В до 20 В. При напряжении питания ниже 7 В, вывод 5V может выдавать менее 5 В, при этом платформа может работать нестабильно. При использовании напряжения выше 12 В регулятор напряжения может перегреться и повредить плату. Рекомендуемый диапазон от 7 В до 12 В.

    Модуль часов реального времени.

    Модуль DS3231 подключается к плате Arduino по интерфейсу I2C, используются выводы SDA и SCL.

    Для программирования будем использовать библиотеки DS1307 и Time.

    Часы ведут отсчет в единицах, которые удобны обычному человеку минуты, часы, дни недели и другие, в отличие от обычных счетчиков и тактовых генераторов, которые считывают «тики». В Ардуино имеется специальная функция millis(), которая также может считывать различные временные интервалы.

    Напряжение питания микросхемы может находиться в пределах 2.3…5.5В, имеются две линии питания, для внешнего источника (линия Vcc), а также для батареи (Vbat). Напряжение внешнего источника постоянно отслеживается, при падении ниже порога Vpf=2,5В, происходит переключение на линию батареи.

    Адресная светодиодная лента.

    Представляет собой ленту из адресных диодов, один такой светодиод состоит из RGB светодиода и контроллера. Да, внутри светодиода уже находится контроллер с тремя транзисторными выходами! Внутри каждого! Благодаря такой начинке у нас есть возможность управлять цветом (то бишь яркостью r g b) любого светодиода в ленте и создавать потрясающие эффекты. Адресная лента может иметь 3-4 контакта для подключения, два из них всегда питание (5V и GND например), и остальные (один или два) логические, для управления.

    Команды в ленте передаются от диода к диоду. У ленты есть начало и конец, направление движение команд на некоторых моделях указано стрелочками. Для примера рассмотрим ws2812b, у нее три контакта. Два на питание, а вот третий в начале ленты называется DI (digital input), а в конце DO (digital output). Лента принимает команды в контакт DI! Контакт DO нужен для подключения дополнительных кусков ленты или соединения матриц.
    2.6 Разработка алгоритма и программы

    Отображаемая на табло информация о состоянии каждого светодиода хранится в ОЗУ, в специальной области, которую назовем видеопамятью. Управление светодиодами - отдельная сложная задача, которой подчинена практически вся схема устройства. Она использует видеопамять как входной массив данных, и отображает состояние этой памяти на матрицу светодиодов. Заполнением видеопамяти необходимыми значениями занимается другая функция, которая в принципе отвечает за работу бегущей строки.

    Бегущая строка представляет собой текст, движущийся справа налево с заданной скоростью. По достижении конца текста вывод строки прекращается. Текст бегущей строки хранится в энергонезависимой FLASH-памяти, с которой контроллер связывается по SPI-интерфейсу. Предельный размер строки составляет 6912 символов; оставшаяся из 8 Кбайт память используется как ПЗУ знакогенератора, т.е. для хранения растрового шрифта. Фактическая длина строки хранится в специальном параметре, который записывается в память EEPROM контроллера.

    Во FLASH-памяти текст записан в обычном виде, в ASCII-кодировке. При выводе очередного символа на экран из памяти считывается его код. Затем с помощью функции знакогенератора определяется начертание символа, состоящее из 5 байт. После этого последовательно, друг за другом с определенной скоростью, в видеопамять сдвигаются эти 5 байтов, после которых идет пустой байт (0x00), служащий разделителем между символами.

    Когда весь символ появится на экране, из памяти будет считан код следующего символа и т.д. до конца текста. Таким образом становится понятно, что для работы алгоритма вывода бегущей строки достаточно иметь всего 2 счетчика: счетчик текущего номера (адреса) символа в строке, и счетчик номера столбца при сдвиге изображения этого символа.

    Перед каждым запуском строки оба счетчика инициализируются, т.е. обнуляются. Увеличение счетчика текущего символа происходит только после того, как будут сдвинуты все 6 байт изображения предыдущего символа. По достижении конца текста вывод символов прекращается, однако сдвиг изображения продолжается до тех пор, пока за левым краем экрана не исчезнет последний символ строки. Это реализуется проверкой соответствующих условий. В сильно упрощенном виде весь процесс показан на листе 9 Графического приложения. На самом деле, при выводе бегущей строки участвуют сразу несколько параллельных задач, таких как обслуживание прерывания от системного таймера, отсчитывающего интервалы времени 1 мс, и задача подсчета интервала сдвига изображения на 1 столбец влево, и др.

    Скетч:

    #define BRIGHTNESS 100 // стандартная маскимальная яркость (0-255)

    #define CURRENT_LIMIT 2000 // лимит по току в миллиамперах, автоматически управляет яркостью (пожалей свой блок питания!) 0 - выключить лимит

    #define WIDTH 40 // ширина матрицы

    #define HEIGHT 8 // высота матрицы

    #define SEGMENTS 1 // диодов в одном "пикселе" (для создания матрицы из кусков ленты)

    #define COLOR_ORDER GRB // порядок цветов на ленте. Если цвет отображается некорректно - меняйте. Начать можно с RGB

    #define MATRIX_TYPE 0 // тип матрицы: 0 - зигзаг, 1 - параллельная

    #define CONNECTION_ANGLE 0 // угол подключения: 0 - левый нижний, 1 - левый верхний, 2 - правый верхний, 3 - правый нижний

    #define STRIP_DIRECTION 0 // направление ленты из угла: 0 - вправо, 1 - вверх, 2 - влево, 3 - вниз

    #define MCU_TYPE 0 // микроконтроллер:

    // 0 - AVR (Arduino NANO/MEGA/UNO)

    // 1 - ESP8266 (NodeMCU, Wemos D1)

    // 2 - STM32 (Blue Pill)

    // ******************** ЭФФЕКТЫ И РЕЖИМЫ ********************

    #define D_TEXT_SPEED 60 // скорость бегущего текста по умолчанию (мс)

    #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 вкл автоматическую смену режимов (откл. можно со смартфона)

    int AUTOPLAY_PERIOD = 15; // время между авто сменой режимов (секунды)

    #define IDLE_TIME 10 // время бездействия кнопок или 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 1 // использовать физические кнопки управления играми (0 нет, 1 да)

    #define BT_MODE 0 // использовать блютус (0 нет, 1 да)

    #define USE_NOISE_EFFECTS 0 // крутые полноэкранные эффекты (0 нет, 1 да) СИЛЬНО ЖРУТ ПАМЯТЬ!!!11

    #define USE_FONTS 1 // использовать буквы (бегущая строка) (0 нет, 1 да)

    #define USE_CLOCK 1 // использовать часы (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 4 // пинленты

    #define BUTT_UP 6 // кнопкавверх

    #define BUTT_DOWN 5 // кнопкавниз

    #define BUTT_LEFT 2 // кнопкавлево

    #define BUTT_RIGHT 3 // кнопкавправо

    #define BUTT_SET 7 // кнопкавыбор/игра

    // пины подписаны согласно pinout платы, а не надписям на пинах!

    // esp8266 - плату выбирал Wemos D1 R1

    #elif (MCU_TYPE == 1)

    #define LED_PIN 2 // пинленты

    #define BUTT_UP 14 // кнопкавверх

    #define BUTT_DOWN 13 // кнопкавниз

    #define BUTT_LEFT 0 // кнопкавлево

    #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 * SEGMENTS

    #define RUNNING_STRING 0

    #define CLOCK_MODE 1

    #define GAME_MODE 2

    #define MADNESS_NOISE 3

    #define CLOUD_NOISE 4

    #define LAVA_NOISE 5

    #define PLASMA_NOISE 6

    #define RAINBOW_NOISE 7

    #define RAINBOWSTRIPE_NOISE 8

    #define ZEBRA_NOISE 9

    #define FOREST_NOISE 10

    #define OCEAN_NOISE 11

    #define SNOW_ROUTINE 12

    #define SPARKLES_ROUTINE 13

    #define MATRIX_ROUTINE 14

    #define STARFALL_ROUTINE 15

    #define BALL_ROUTINE 16

    #define BALLS_ROUTINE 17

    #define RAINBOW_ROUTINE 18

    #define RAINBOWDIAGONAL_ROUTINE 19

    #define FIRE_ROUTINE 20

    #define IMAGE_MODE 21

    #if (MCU_TYPE == 1)

    #define FASTLED_INTERRUPT_RETRY_COUNT 0

    #define FASTLED_ALLOW_INTERRUPTS 0

    #include

    #endif

    #include

    #include

    CRGB leds[NUM_LEDS];

    String runningText = "";

    #define BT_RX 3

    #define BT_TX 2

    SoftwareSerial btSerial(BT_TX, BT_RX); // RX, TX

    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;

    boolean clockSet = false;

    #if (USE_FONTS == 1)

    #include "fonts.h"

    #endif

    uint32_t 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

    #include "RTClib.h"

    RTC_DS3231 rtc;

    // RTC_DS1307 rtc;

    #endif

    void setup() {

    #if (BT_MODE == 1)

    Serial.begin(9600);

    #endif

    #if (MCU_TYPE == 1)

    WiFi.setSleepMode(WIFI_NONE_SLEEP);

    #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(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();

    }

    Настройка режимов и эффектов

    // ************************ НАСТРОЙКИ ************************

    #define SMOOTH_CHANGE 1 // плавная смена режимов через чёрный

    #define SHOW_FULL_TEXT 1 // не переключать режим, пока текст не покажется весь

    #define SHOW_TEXT_ONCE 1 // показывать бегущий текст только 1 раз

    /*

    Режимы:

    clockRoutine(); // часы на чёрном фоне

    Эффекты:

    sparklesRoutine(); // случайные цветные гаснущие вспышки

    snowRoutine(); // снег

    matrixRoutine(); // "матрица"

    starfallRoutine(); // звездопад (кометы)

    ballRoutine(); // квадратик

    ballsRoutine(); // шарики

    rainbowRoutine(); // радуга во всю матрицу горизонтальная

    rainbowDiagonalRoutine(); // радуга во всю матрицу диагональная

    fireRoutine(); // огонь

    Крутые эффекты "шума":

    madnessNoise(); // цветной шум во всю матрицу

    cloudNoise(); // облака

    lavaNoise(); // лава

    plasmaNoise(); // плазма

    rainbowNoise(); // радужные переливы

    rainbowStripeNoise(); // полосатые радужные переливы

    zebraNoise(); // зебра

    forestNoise(); // шумящий лес

    oceanNoise(); // морская вода

    Игры:

    snakeRoutine(); // змейка

    tetrisRoutine(); // тетрис

    mazeRoutine(); // лабиринт

    runnerRoutine(); // бегалкапрыгалка

    flappyRoutine(); // flappy bird

    arkanoidRoutine(); // арканоид

    Бегущаястрока:

    fillString("Ваштекст", цвет); // цветвида 0x00ff25 или CRGB::Red ипроч. цвета

    fillString("Ваш текст", 1); // радужный перелив текста

    fillString("Ваш текст", 2); // каждая буква случайным цветом!

    Рисунки и анимации:

    loadImage(<название массива>); // основная функция вывода картинки

    imageRoutine1(); // пример использования

    animation1(); // пример анимации

    */

    // ********** СВОЙ СПИСОК РЕЖИМОВ ************

    // список можно менять, соблюдая его структуру. Можно удалять и добавлять эффекты, ставить их в

    // любой последовательности или вообще оставить ОДИН. Удалив остальные case и break. Cтруктура оч простая:

    // case <номер>: <эффект>;

    // break;

    // не забудьте указать количество режимов для корректного переключения с последнего на первый

    #define MODES_AMOUNT 9 // количество кастомных режимов (которые переключаются сами или кнопкой)

    void customModes() {

    switch (thisMode) {

    case 0: clockRoutine();

    break;

    case 1: fillString("ОПКАТП-16", 1);

    break;

    case 2: rainbowRoutine();

    break;

    case 3: ballsRoutine();

    break;

    case 4: fireRoutine();

    break;

    case 5: sparklesRoutine(); // случайныецветныегаснущиевспышки

    break;

    case 6: snowRoutine(); // снег

    break;

    case 7: starfallRoutine(); // звездопад (кометы)

    break;

    case 8: ballRoutine();

    break;

    }

    }

    // функция загрузки картинки в матрицу. должна быть здесь, иначе не работает =)

    void loadImage(uint16_t (*frame)[WIDTH]) {

    for (byte i = 0; i < WIDTH; i++)

    for (byte j = 0; j < HEIGHT; j++)

    drawPixelXY(i, j, gammaCorrection(expandColor((pgm_read_word(&(frame[HEIGHT - j - 1][i]))))));

    // да, тут происходит лютенький п@здец, а именно:

    // 1) pgm_read_word - восстанавливаем из PROGMEM (флэш памяти) цвет пикселя в 16 битном формате по его координатам

    // 2) expandColor - расширяем цвет до 24 бит (спасибо adafruit)

    // 3) gammaCorrection - проводим коррекцию цвета для более корректного отображения

    }

    timerMinim gifTimer(D_GIF_SPEED);

    void animation1() {

    if (gifTimer.isReady()) {

    frameNum++;

    if (frameNum >= sizeof(framesArray)) frameNum = 0;

    loadImage(framesArray[frameNum]);

    }

    }

    */

    // **************** ОСНОВНОЙЦИКЛРЕЖИМОВ ***************

    #if (SMOOTH_CHANGE == 1)

    byte fadeMode = 4;

    boolean modeDir;

    #endif

    static void nextMode() {

    #if (SMOOTH_CHANGE == 1)

    fadeMode = 0;

    modeDir = true;

    #else

    nextModeHandler();

    #endif

    }

    static void prevMode() {

    #if (SMOOTH_CHANGE == 1)

    fadeMode = 0;

    modeDir = false;

    #else

    prevModeHandler();

    #endif

    }

    void nextModeHandler() {

    thisMode++;

    if (thisMode >= MODES_AMOUNT) thisMode = 0;

    loadingFlag = true;

    gamemodeFlag = false;

    FastLED.clear();

    FastLED.show();

    }

    void prevModeHandler() {

    thisMode--;

    if (thisMode < 0) thisMode = MODES_AMOUNT - 1;

    loadingFlag = true;

    gamemodeFlag = false;

    FastLED.clear();

    FastLED.show();

    }

    int fadeBrightness;

    #if (SMOOTH_CHANGE == 1)

    void modeFader() {

    if (fadeMode == 0) {

    fadeMode = 1;

    } else if (fadeMode == 1) {

    if (changeTimer.isReady()) {

    fadeBrightness -= 40;

    if (fadeBrightness < 0) {

    fadeBrightness = 0;

    fadeMode = 2;

    }

    FastLED.setBrightness(fadeBrightness);

    }

    } else if (fadeMode == 2) {

    fadeMode = 3;

    if (modeDir) nextModeHandler();

    else prevModeHandler();

    } else if (fadeMode == 3) {

    if (changeTimer.isReady()) {

    fadeBrightness += 40;

    if (fadeBrightness > globalBrightness) {

    fadeBrightness = globalBrightness;

    fadeMode = 4;

    }

    FastLED.setBrightness(fadeBrightness);

    }

    }

    }

    #endif

    boolean loadFlag2;

    void customRoutine() {

    if (!BTcontrol) {

    if (!gamemodeFlag) {

    if (effectTimer.isReady()) {

    #if (OVERLAY_CLOCK == 1 && USE_CLOCK == 1)

    if (overlayAllowed()) {

    if (!loadingFlag && !gamemodeFlag && needUnwrap() && modeCode != 0) clockOverlayUnwrap(CLOCK_X, CLOCK_Y);

    if (loadingFlag) loadFlag2 = true;

    }

    #endif

    customModes();

    #if (OVERLAY_CLOCK == 1 && USE_CLOCK == 1)

    if (overlayAllowed()) {

    if (!gamemodeFlag && modeCode != 0) clockOverlayWrap(CLOCK_X, CLOCK_Y);

    if (loadFlag2) {

    setOverlayColors();

    loadFlag2 = false;

    }

    }

    #endif

    loadingFlag = false;

    FastLED.show();

    }

    } else {

    customModes();

    }

    btnsModeChange();

    #if (SMOOTH_CHANGE == 1)

    modeFader();

    #endif

    }

    if (idleState) {

    if (fullTextFlag && SHOW_TEXT_ONCE) {

    fullTextFlag = false;

    autoplayTimer = millis();

    nextMode();

    }

    if (millis() - autoplayTimer > autoplayTime && AUTOPLAY) { // таймерсменырежима

    if (modeCode == 0 && SHOW_FULL_TEXT) { // режимтекста

    if (fullTextFlag) {

    fullTextFlag = false;

    autoplayTimer = millis();

    nextMode();

    }

    } else {

    autoplayTimer = millis();

    nextMode();

    }

    }

    } else {

    if (idleTimer.isReady()) { // таймерхолостогорежима

    idleState = true;

    autoplayTimer = millis();

    gameDemo = true;

    gameSpeed = DEMO_GAME_SPEED;

    gameTimer.setInterval(gameSpeed);

    loadingFlag = true;

    BTcontrol = false;

    FastLED.clear();

    FastLED.show();

    }

    }

    }

    void timeSet(boolean type, boolean dir) { // type: 0-часы, 1-минуты, dir: 0-уменьшить, 1-увеличить

    if (type) {

    if (dir) hrs++;

    else hrs--;

    } else {

    if (dir) mins++;

    else mins--;

    if (mins > 59) {

    mins = 0;

    hrs++;

    }

    if (mins < 0) {

    mins = 59;

    hrs--;

    }

    }

    if (hrs > 23) hrs = 0;

    if (hrs < 0) hrs = 23;

    }

    void btnsModeChange() {

    #if (USE_BUTTONS == 1)

    if (bt_set.clicked()) {

    if (gamemodeFlag) gameDemo = !gameDemo;

    if (gameDemo) {

    gameSpeed = DEMO_GAME_SPEED;

    gameTimer.setInterval(gameSpeed);

    AUTOPLAY = true;

    } else {

    gameSpeed = D_GAME_SPEED;

    gameTimer.setInterval(gameSpeed);

    AUTOPLAY = false;

    }

    }

    if (bt_set.holded()) {

    if (modeCode == 2)

    mazeMode = !mazeMode;

    if (modeCode == 1) { // входвнастройкучасов

    clockSet = !clockSet;

    AUTOPLAY = false;

    secs = 0;

    #if (USE_CLOCK == 1)

    if (!clockSet) rtc.adjust(DateTime(2014, 1, 21, hrs, mins, 0)); // установкановоговременив RTC

    #endif

    }

    }

    // timeSettype: 0-часы, 1-минуты, dir: 0-уменьшить, 1-увеличить

    if (gameDemo) {

    if (bt_right.clicked()) {

    if (!clockSet) {

    autoplayTimer = millis();

    nextMode();

    } else {

    timeSet(1, 1);

    }

    }

    if (bt_left.clicked()) {

    if (!clockSet) {

    autoplayTimer = millis();

    prevMode();

    } else {

    timeSet(1, 0);

    }

    }

    if (bt_up.clicked()) {

    if (!clockSet) {

    AUTOPLAY = true;

    autoplayTimer = millis();

    } else {

    timeSet(0, 1);

    }

    }

    if (bt_down.clicked()) {

    if (!clockSet) {

    AUTOPLAY = false;

    } else {

    timeSet(0, 0);

    }

    }

    if (bt_right.holding())

    if (changeTimer.isReady()) {

    if (!clockSet) {

    effects_speed -= 2;

    if (effects_speed < 30) effects_speed = 30;

    effectTimer.setInterval(effects_speed);

    } else {

    timeSet(1, 1);

    }

    }

    if (bt_left.holding())

    if (changeTimer.isReady()) {

    if (!clockSet) {

    effects_speed += 2;

    if (effects_speed > 300) effects_speed = 300;

    effectTimer.setInterval(effects_speed);

    } else {

    timeSet(1, 0);

    }

    }

    if (bt_up.holding())

    if (changeTimer.isReady()) {

    if (!clockSet) {

    globalBrightness += 2;

    if (globalBrightness > 255) globalBrightness = 255;

    fadeBrightness = globalBrightness;

    FastLED.setBrightness(globalBrightness);

    } else {

    timeSet(0, 1);

    }

    }

    if (bt_down.holding())

    if (changeTimer.isReady()) {

    if (!clockSet) {

    globalBrightness -= 2;

    if (globalBrightness < 0) globalBrightness = 0;

    fadeBrightness = globalBrightness;

    FastLED.setBrightness(globalBrightness);

    } else {

    timeSet(0, 0);

    }

    }

    }

    #endif

    }

    1   2   3


    написать администратору сайта