# Синхронизация устройств

- [Общие понятия](#Общие-понятия)
- [Внешние эффекты Jinx!](#Внешние-эффекты-jinx)
- [Настройка синхронизации](#Настройка-синхронизации)
- [Технические аспекты](#Технические-аспекты)
- [Возможные проблемы](#Возможные-проблемы)
- [Настройка  ***"Jinx!"*** как источника эффектов](https://github.com/vvip-68/GyverPanelWiFi/wiki/Настройка-ПО-управления-эффектами-%22Jinx!%22-как-источника-синхронизации-устройств-в-группе).  

## Общие понятия

Прошивка поддерживает синхронизацию эффектов между устройствами. Может быть создано до 10 групп устройств.
Количество устройств в группе - не ограничено. Все синхронизированные устройства должны находиться в одной локальной сети.
Маршрутизатор должен обеспечивать корректную передачу многоадресных UDP пакетов в локальной сети - режим ***multicast***.
Настройку передачи multicast-пакетов в вашем роутере смотрите в документации на роутер.

![Сеть](https://github.com/vvip-68/GyverPanelWiFi/blob/master/wiki/E131/Network.jpg)

Устройства, объединенные в группу должны содержать одно **главное устройство** - источник (***MASTER***), остальные устройства группы являются **ведомыми** и должны быть настроены для работы в режиме приемник (***SLAVE***).

Прошивка поддерживает до 10 групп устройств - "Группа 0" .. "Группа 9", устройства в каждой группе работают синхронно, группы независимы.

### Режимы работы устройств

Каждое устройство может быть настроено в приложении-компаньоне **"WiFi Panel Setup"** для работы в одном из трех режимов:
- **Автономный режим** - устройство отключено от синхронизации, работает самостоятельно.
- **Источник** (мастер) - задает синхронизацию ведомым устройствам. Ведомые устройства воспроизводят те же эффекты, которые в настоящий момент отображаются на устройстве - источнике. Группа должна содержать не более одного устройства-источника.
- **Приемник** (ведомый) - принимает данные от главного устройства группы, повторяет эффекты, которые в настоящий момент отображает источник - мастер. Количество устройств-приемников в группе не ограничено. 

### Уровни синхронизации

Для корректной работы устройств в группе источник и приемник должны быть настроены на *одинаковые уровни* синхронизации.  
Существуют три уровня синхронизации устройств:
 - **Физическая** синхронизация
 - **Логическая** синхронизация
 - Синхронизация на уровне **команд**

#### Физический уровень

Физический уровень синхронизации является самым быстрым, поскольку полученные от источника пакеты данных не требуют дополнительной обработки и передаются "как есть" на матрицу устройства приемника. Этот режим синхронизации рекомендуется для устройств с большими матрицами, так как требуют минимальное время на обработку принятых данных.

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

Несоблюдение этих требований нарушит отображение эффектов - картинка будет искажена/рассинхронизирована. Максимальное количество диодов в матрице для этого режима - 1190. Для увеличения количества диодов (для слишком больших матриц) требуется корректировка кода в скетче. 

Физический уровень синхронизации устройств обеспечивает **абсолютную** синхронизацию устройств. Эффекты на всех устройствах группы будут выглядеть абсолютно синхронно, поскольку устройство-мастер передает устройствам-приемникам "картинку" со своей матрицы.

#### Логический уровень

Логический уровень синхронизации определяет отображение картинки эффекта с позиции (X,Y) = (0,0) - левый верхний угол картинки, направление следования "пикселей" картинки - слева направо по X, затем сверху вниз по Y. Логический уровень синхронизации требует дополнительных затрат на обработку пакетов принятых от мастера, зато нивелирует требование одинаковости угла подключения  и направления из угла матрицы для устройств в группе. Размеры матрицы (высота и ширина) по прежнему должны быть такими же как на устройстве - источнике.

Несоблюдение требования одинакового размера матриц нарушит отображение эффектов - картинка будет искажена/рассинхронизирована. Максимальное количество диодов в матрице для этого режима - 1190. Для увеличения количества диодов (для слишком больших матриц) требуется корректировка кода в скетче. 

Логический уровень синхронизации устройств обеспечивает **абсолютную** синхронизацию устройств. Эффекты на всех устройствах группы будут выглядеть абсолютно синхронно, поскольку устройство-мастер передает устройствам-приемникам "картинку" со своей матрицы.

#### Командный уровень

Командный уровень синхронизации хорошо работает для устройств группы, если размеры их матриц, угол подключения и направление цепочки светодиодов из угла не совпадают. Этот режим не позволяет добиться абсолютной синхронизации устройств, поскольку от ведущего устройства к приемникам передается не "картинка" эффекта, а команды - "включить эффект N", "установить яркость в значение X", "отобразить бегущую строку с текстом xxx" и подобные.

Часть эффектов имеют свои "подрежимы" - например эффект "радуга" имеет разновидности "Вертикальная", "Горизонтальная", "Диагональная", "Вращающаяся", "Случайный выбор". Эффекты "Анимация" или "SD-карта" - набор различных анимаций и роликов в качестве "подрежимов". Устройство приемник, получив от главного устройства команду "Включить эффект N" включит сам эффект, но "подрежимы" включенного эффекта совпадать не будут. Особенности технической реализации командного режима не позволяют синхронизировать варианты эффектов на всех устройствах группы.

![Сравнение](https://github.com/vvip-68/GyverPanelWiFi/blob/master/wiki/E131/Texts.png)


## Внешние эффекты Jinx!

Одним из вариантов синхронизации устройств в группе является ***внешняя синхронизация***. В этом режиме в группе нет устройства-источника, все устройства настроены на работу в режиме **"приемник"** (SLAVE). В качестве источника эффектов для отображения на всех устройствах группы используется одна из программ управления световым оборудованием и создания эффектов, поддерживающих протокол SACN E1.31 (DMX-512 over Ethernet) - [***"Jinx!***](http://www.live-leds.de/), ***"Glediator"***,  [***"Wixen lights"***](http://www.vixenlights.com), [***"XLights"***](http://xlights.org/) и подобные.

![Сеть](https://github.com/vvip-68/GyverPanelWiFi/blob/master/wiki/E131/Network-Jinx!.jpg)

Настройка внешнего источника синхронизации на примере программы управления световым оборудованием ***"Jinx!"*** описана в этой [статье](https://github.com/vvip-68/GyverPanelWiFi/wiki/Настройка-ПО-управления-эффектами-%22Jinx!%22-как-источника-синхронизации-устройств-в-группе).

## Настройка синхронизации

Задание роли для конкретного устройства производится в приложении-компаньоне ***"WiFi Panel Setup"***. Скачайте и установите приложение из архива проекта из папки ***Android***. Создайте учетную запись устройства, задайте имя и укажите его IP. Порт оставьте по умолчанию. Нажмите кнопку "Подключить".

![Настройка](https://github.com/vvip-68/GyverPanelWiFi/blob/master/wiki/E131/setup1.png)
![Настройка](https://github.com/vvip-68/GyverPanelWiFi/blob/master/wiki/E131/setup2.png) 

Перейдите к разделу "Настройки синхронизации".

![Настройка](https://github.com/vvip-68/GyverPanelWiFi/blob/master/wiki/E131/setup3.png) 

Выберите нужный *режим работы* устройства - ***Автономный***, ***"Источник"*** или ***"Приемник"***.  
При выборе режима *"Источник"* или *"Приемник"* станут доступными опции настройки *режима синхронизации*. Выберите нужный.  
Установите в комбобоксе *группу синхронизации*. Этот параметр должен совпадать для всех устройств группы.
Сохраните настройки - нажмите кнопку ***"Сохранить"***. Устройство перейдет в работу в соответствующем настройкам режиме.

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

## Технические аспекты

### Общие сведения о протоколе E1.31

В техническом плане синхронизация устройств основана на протоколе управлением световым оборудованием **E1.31** (***SACN DMX-512 over Ethernet***), разработанным компанией [ESTA](https://tsp.esta.org/tsp/index.html). Спецификация протокола описана в этом [документе](https://tsp.esta.org/tsp/documents/docs/ANSI_E1-31-2018.pdf). Передача данных от источнику к приемнику в данном проекте осуществляется путем отправки многоадресных (*multicast*) пакетов по протоколу UDP, содержащих данные синхронизации - части картинки с матрицы Мастер-устройства или команды управления.

По спецификации **DMX-512** пакет данных управления цифровым оборудованием содержит 512 байт (каналов) управляющей информации. Применительно к матрице, это означает, что в одном пакете могут быть переданы RGB цвета 170 диодов матрицы. Каждый цвет содержит компоненты RGB, занимающие по одному байту. Таким образом, данные пакета позволяют разместить RGB-цвета для 512 / 3 = 170 светодиодов. Размер полезной загрузки пакета - 170 * 3 = 510 байт.

Фабричная матрица содержит 16x16 = 256 светодиодов. Следовательно, для того, чтобы передать полную картинку с матрицы-источника на матрицу приемника требуется более 512 информационных каналов, а именно 256 * 3 = 768 каналов, или два потока по 510 (1) и 268 (2) каналов (170 и 86 светодиодов) соответственно.

Протокол DMX-512 вводит понятие **Вселенная** (*Universe*) - совокупность потоков данных, каждый из которых содержит 512 каналов. Передача каждого такого потока (каждая вселенная) требует выделения отдельного IP адреса. Для передачи многоадресных пакетов для совокупности вселенных выделяется диапазон адресов 239.255.0.0 .. 239.255.255.255. Часть из этого диапазона адресов зарезервирована для служебных целей и не может быть использована (смотри [спецификацию](https://tsp.esta.org/tsp/documents/docs/ANSI_E1-31-2018.pdf) протокола. В общем случае данные для управления световым оборудованием могут содержать до 64000 вселенных по 512 каналов в каждой. На практике же (и в данной прошивке) для передачи данных используется 10 групп, каждая из которых содержит по 7 вселенных. Таким образом, каждая группа может управлять матрицей, состоящей из 7 * 170 = 1190 светодиодов.
```
Ограничение 10 групп 7 вселенных введено из соображений достаточности для большинства проектов 
и при необходимости может быть расширено путем внесения исправлений в код скетча (файл *e131.ino*).
```
Нумерация вселенных начинается с 1. Таким образом, распределение Multicast IP адресов вселенных приведено в следующей таблице:
| Группа | Адреса вселенных |
|--------|------------------|
| **Группа 0** | 239.255.0.1  - 239.255.0.7 |
| **Группа 1** | 239.255.0.8  - 239.255.0.14 |
| **Группа 2** | 239.255.0.15 - 239.255.0.21 |
| **Группа 3** | 239.255.0.22 - 239.255.0.28 |
| **Группа 4** | 239.255.0.29 - 239.255.0.35 |
| **Группа 5** | 239.255.0.36 - 239.255.0.42 |
| **Группа 6** | 239.255.0.43 - 239.255.0.49 |
| **Группа 7** | 239.255.0.50 - 239.255.0.56 |
| **Группа 8** | 239.255.0.57 - 239.255.0.63 |
| **Группа 9** | 239.255.0.64 - 239.255.0.70 |

UDP порт для каждого адреса по стандарту E1.31 используется **5568**

### Реализация в скетче

Для включения поддержки синхронизации устройств найдите в проекте файл *a_def_haed.h*, в нем блок определения параметров оборудования и включите использование синхронизации устройств **`#define USE_E131 1`**:
```
...
#define USE_WEATHER 1           // 1 - использовать получение информации о текущей погоде; 0 - не использовать 
#define USE_E131 1              // 1 - использовать протокол E1.31 для синхронизации устройств
#define BIG_FONT 0              // 0 - шрифт 5x8, 1 - шрифт  10x16; 2 - шрифт 8x13
...
```
После компиляции скетча и загрузки прошивки в проект - настройте роль каждого устройства в группе - один источник на группу, остальные устройства в группе - приемники.

### Как это работает

Для уровня синхронизации ***"Физический"*** после того как изображение эффекта сформировано, выполнено наложение на эффект часов / текста / погоды, непосредственно перед отправкой изображения на диоды матрицы вызывается функция ***sendE131Screen()***. Функция выполняет перебор всех светодиодов в цикле от **0 до NUM_LED-1**, извлекает три байта цвета для каждого светодиода в цепочке в порядке их физического подключения и помещает их в область данных сетевого пакета E1.31. После заполнения пакета первой вселенной группы данными RGB-цвета первых 170 диодов, пакет отправляется в сеть многоадресной рассылкой по адресу соответствующему multicast-адресу первой вселенной группы. Затем формируется новый пакет для следующей вселенной, происходит заполнение данных цветами следующих 170 диодов и отправка пакета в сеть. Это повторяется до достижения последнего светодиода в матрице. Последний пакет может быть не полным, если общее количество светодиодов не кратно 170. После того как отправка данных в сеть устройствам получателям завершена, картинка выводится на матрицу устройства-источника - `FastLED.show()`.

Для уровня синхронизации ***"Логический"*** выполняется похожая последовательность действий, за исключением того, что светодиоды матрицы опрашиваются не в порядке физического следования от *0 до NUM_LED-1*, а сканируя "развертку" изображения начиная с верхнего левого угла матрицы по столбцам (***координата X***), затем по строкам (***координата Y***). Формирование пакетов данных для вселенных группы ничем не отличается от алгоритма для уровня синхронизации *"Физический"*.

На стороне приемника из каждого полученного пакета извлекаются данные RGB-цвета светодиодов, определяется номер диода в цепочке (уровень *"Физический"* или координаты X,Y (уровень *"Логический"*) и отправляются на матрицу.

Несколько иначе обстоят дела для уровня синхронизации ***"Командный"***. В этом случае пакет E1.31 в области данных содержит не триады RGB-цветов светодиодов, а команды, которые должен выполнить приемник при их получении от устройства-источника. Отправка команд мастером выполняется в ключевые моменты алгоритма скетча, например: при смене эффекта, при начале и и завершении отображения текста бегущей строки, при изменении яркости матрицы или параметров эффекта и при других событиях. 

Чтобы отличить пакет с командой от пакета с данными - в первые два байта области данных командного пакета помещается сигнатура - 0xAA, 0x55. Следующие байты данных в командном пакете содержат *код (ID) команды* и ее параметры.

Описание команд и их параметров приведены в следующей таблице:

| № байта | значение |
|---------|----------|
| **[1]** | 0xAA - сигнатура, байт 1 |
| **[2]** | 0x55 - сигнатура, байт 2 |
| **[3]** | ID команды |
|     --- | **Команды** |
| **[3]** | **0** - ***Вкл/выкл устройства*** |
| **[4]** | = x - 0 - выключить 1 - включить |
|     --- |  |
| **[3]** | **1** - ***Установить текущую яркость*** |
| **[4]** | x - Значение яркости |
|     --- |  |
| **[3]** | **1** - ***Установить текущую яркость специальных эффектов*** |
| **[4]** | x - Значение яркости |
|     --- |  |
| **[3]** | **3** - ***Включить эффект*** |
| **[4]** | x - ID эффекта |
| **[5]** | x - скорость эффекта |
| **[6]** | x - контраст эффекта |
| **[7]** | x - спец.параметр №1 |
| **[8]** | x - спец.параметр №2 |
| **[9]**  | r  - значение компоненты R цвета globalColor |
| **[10]** | g  - значение компоненты G цвета globalColor |
| **[11]** | b  - значение компоненты B цвета globalColor |
| **[12]** | W  - ширина матрицы Мастера |
| **[13]** | H  - высота матрицы Мастера |
|     --- |  |
| **[3]** | **4** - ***Включить указанный специальный эффект*** |
| **[4]** | x - ID специального эффекта |
|     --- |  |
| **[3]** | **5** - ***Включить отображение текста, переданного в параметре*** |
| **[4]** | x - char* null-terminated текст |
|     --- |  |
| **[3]** | **6** - ***Остановить отображение бегущей строки, если оно выполняется*** |
|     --- |  |
| **[3]** | **7** - ***Установить время*** |
| **[4]** | x - год (без века) -  20xx |
| **[5]** | x - месяц |
| **[6]** | x - день |
| **[7]** | x - часы |
| **[8]** | x - минуты |
| **[9]** | x - секунды |
|     --- |  |
| **[3]** | **8** - ***Установить скорость эффекта*** |
| **[4]** | x - скорость |
|     --- |  |
| **[3]** | **9** - ***Установить контрастность эффекта*** |
| **[4]** | x - контрастность |
|     --- |  |
| **[3]** | **10** - ***Установить параметр 1 эффекта*** |
| **[4]** | x  - значение |
|     --- |  |
| **[3]** | **11** - ***Установить параметр 2 эффекта*** |
| **[4]** | x  - значение |
|     --- |  |
| **[3]** | **12** - ***Установить globalColor*** |
| **[4]** | r  - значение компоненты цвета R |
| **[5]** | g  - значение компоненты цвета G |
| **[6]** | b  - значение компоненты цвета B |
|     --- |  |
| **[3]** | **13** - ***Ширина и высота панели Мастера*** |
| **[4]** | W  - ширина |
| **[5]** | H  - высота |

## Возможные проблемы

- На устаревших роутерах типа DIR-615 замечены неполадки на устройствах-приемниках, работающих в режиме ***SLAVE***  
  - **Проявление**: изображение эффекта с MASTER на устройствах SLAVE отображается не полностью, не на всей матрице, а только на первых 170 диодах. На остальной части матрицы диоды не светятся.  
  - **Причина**: роутер отдает устройствам только первый многоадресный пакет из кадра, остальные пакеты роутером устройству-приемнику не передаются.  
  - **Решение**: обычно решить проблему помогает перезагрузка роутера. Если проблема возникает достаточно часто - рекомендуется замена роутера на более современный.

- Современные роутеры типа TPLink серии Archer имеют ошибку в прошивке.
  - **Проявление**: после выключения питания ведомых устройств роутер перестает отвечать. Пинг на роутер не проходит, Web-страница настройки роутера не открывается. Компьютеры в сети сообщают, что интернет не доступен.
  - **Причина**: ошибка в прошивке роутера.
  - **Решение**: адекватного решения в настоящий момент не существует. Ожидается обновление прошивки роутера. Восстановить доступ в интернет и доступность роутера помогает его перезагрузка. Впрочем, если роутер не трогать, он восстановится самостоятельно через 5-7 минут. Включение питания  устройств-приемников обратно также восстанавливает работоспособность роутера и доступность интернета в течение 20-30 секунд.

