Протокол DMX-512. Тестер сигнала и димер.

Автор: | 25.07.2017

Статья была написана для сайта Паяльник. Оригинал: http://cxem.net/sound/light/light114.php. Дополнена прошивкой для Atmega48/88/168/328.

Стал глубже погружаться в мир театрального света и стало интересно, как же оно работает.

Световое оборудование сейчас управляется по DMX-512. Этот протокол работает на сетях RS-485. DMX-512 крайне простая штука. Представляет собой до 512 байт с данными о значении канала, передаваемых последовательно. И все. На самом деле вовсе не обязательно отправлять все 512 байт, но если нужно сказать, что изменилось значение на, допустим, 27 канале, то необходимо отправить значения не только измененного канала, но и все предыдущие. Остальные 485 каналов отправлять вовсе не нужно.

Для устройства я выбрал ATmega8, но, забегая вперед, скажу, что по объему памяти она бы поместилась и на Tiny13. Вот только Tiny13 не умеет тактироваться от кварца да и аппаратного UART в нем нет. Подошла бы Tiny2313, но разница в цене настолько мала, что можно и раскошелиться на более крутое железо.

Минимальная схема устройства состоит из: преобразователя UART в RS-485 (например max485), микроконтроллера, кварцевого резонатора, пары конденсаторов и резистора.

Минимальная схема

Теперь прошивка. Первым делом инициализируем USART на скорости 250 000.

#define USART_BAUDRATE 250000
#define UBRR_VALUE (F_CPU/16/USART_BAUDRATE-1)
 
void USART_Init()
{
    // Set baud rate
    UBRRH = (uint8_t)(UBRR_VALUE>>8);
    UBRRL = (uint8_t)UBRR_VALUE;
    /* Set frame format: 8data, 2stop bit */
    UCSRC = (1<<URSEL)|(1<<USBS)|(3<<UCSZ0);
    //enable reception
    UCSRB |= (1<<RXEN);
    // разрешаем прерывание по приему байта
    UCSRB |= (1<<RXCIE);
}

Работать будем на прерываниях. Создаем глобальный массив под интересующие данные. Для этого нужно задать сколько каналов интересуют и начальный адрес. Начальный адрес должен легко изменяться. Способов несколько: энкондер, кнопки, DIP переключатели… Тут уж на Ваш выбор. Глобальный массив позволяет задавать данные в прерывании и использовать эти данные в основном цикле программы.

#define COUNT_CHANNELS 4
unsigned char data[COUNT_CHANNELS];
 
unsigned int DMX_Current_Channel = 0;
unsigned int DMX_Start_Channel = 0;

Самой сложной задачей является разделение посылок между собой. Для этих целей предусмотрен интервал тишины. Линия опускается в 0, что является старт-битом. Далее микроконтроллер ждет данные и 2 стоп-бита. Последних он так и не дожидается, что генерирует ошибку «Frame Error». Микроконтроллер выставляет флаг, который позволяет определить начало нового пакета.

ISR(USART_RXC_vect)
{
    unsigned char UART_Status = UCSRA;
    unsigned char UART_Data = UDR;
    // Обнаружена ошибка (Frame error)
    if (UART_Status & (1<<FE)){
        DMX_Current_Channel = 0;
        DMX_Break = 1;
    } else if (DMX_Break == 1){
        int index = DMX_Current_Channel - DMX_Start_Channel - 1;
        if ((index >= 0) && (index < COUNT_CHANNELS)){
            data[index] = UART_Data;
        }
        DMX_Current_Channel++;
    }
}

Дополнительное условие (DMX_Break == 1) является костылем и предотвращает установку ложных значений при включении устройства посреди передачи.

В результате мы имеем массив, где лежат значения на интересующих нас каналах. Что с ними делать — придумайте сами. Например LED прожектор или даже, при наличии пары сервоприводов, полноценная голова! Тут только стоит проявить фантазию!

К статье оригинальной статье были приложены два варианта устройств. Первый — тестер линии с отображением данных первого канала на семисегментных индикаторах (3 цифры). Практической пользы от такого устройства мало, но для обучения можно и собрать на макетной плате. Второе же устройство куда полезнее. В нем я использовал выводы с ШИМ, данные для которых поступают по DMX-512. Его можно использовать для оцифровки старых аналоговых диммеров, управляемых сигналом 0-10 Вольт (добавив операционный усилитель), или же для сборки собственных приборов.

Исходный код и прошивки для Atmega8

После оцифровывал старенький димер, но там было уже 6 каналов, а Atmega8 имеет всего 4 аппаратных ШИМ. Перенес код под Atmega48/88/168/328. Прошивка не совсем соответствует схеме устройства, так как при разводке платы все выводы DIP переключателя перепутались.

Схема конвертора DMX-512 в 6 каналов 0-10 ВольтИсходный код и прошивка 6-канального димера на Atmega48/88/168/328

 

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *