Протокол 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

 

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

  1. agus

    hi. thanks for the post, im realy interesting for usb dmx controller the one you build.

    may i know, how we use it togather with freestyler or qlc.

    what driver we use it. in those program.

    thank you.

     

     

    1. walhi Автор записи

      I use the driver that comes with the Arduino IDE. It must be selected manually, since the driver was created for another device. But everything will work perfectly. The main plus of the driver from Arduino is that it is signed. You do not need any manipulations with disabling the mandatory verification of the digital signature of the driver.

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

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