Статья была написана для сайта Паяльник. Оригинал: 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.
[pastacode lang=»c» manual=»%23define%20USART_BAUDRATE%20250000%0A%23define%20UBRR_VALUE%20(F_CPU%2F16%2FUSART_BAUDRATE-1)%0A%20%0Avoid%20USART_Init()%0A%7B%0A%20%20%20%20%2F%2F%20Set%20baud%20rate%0A%20%20%20%20UBRRH%20%3D%20(uint8_t)(UBRR_VALUE%3E%3E8)%3B%0A%20%20%20%20UBRRL%20%3D%20(uint8_t)UBRR_VALUE%3B%0A%20%20%20%20%2F*%20Set%20frame%20format%3A%208data%2C%202stop%20bit%20*%2F%0A%20%20%20%20UCSRC%20%3D%20(1%3C%3CURSEL)%7C(1%3C%3CUSBS)%7C(3%3C%3CUCSZ0)%3B%0A%20%20%20%20%2F%2Fenable%20reception%0A%20%20%20%20UCSRB%20%7C%3D%20(1%3C%3CRXEN)%3B%0A%20%20%20%20%2F%2F%20%D1%80%D0%B0%D0%B7%D1%80%D0%B5%D1%88%D0%B0%D0%B5%D0%BC%20%D0%BF%D1%80%D0%B5%D1%80%D1%8B%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5%20%D0%BF%D0%BE%20%D0%BF%D1%80%D0%B8%D0%B5%D0%BC%D1%83%20%D0%B1%D0%B0%D0%B9%D1%82%D0%B0%0A%20%20%20%20UCSRB%20%7C%3D%20(1%3C%3CRXCIE)%3B%0A%7D» message=»» highlight=»» provider=»manual»/]
Работать будем на прерываниях. Создаем глобальный массив под интересующие данные. Для этого нужно задать сколько каналов интересуют и начальный адрес. Начальный адрес должен легко изменяться. Способов несколько: энкондер, кнопки, DIP переключатели… Тут уж на Ваш выбор. Глобальный массив позволяет задавать данные в прерывании и использовать эти данные в основном цикле программы.
[pastacode lang=»c» manual=»%23define%20COUNT_CHANNELS%204%0Aunsigned%20char%20data%5BCOUNT_CHANNELS%5D%3B%0A%20%0Aunsigned%20int%20DMX_Current_Channel%20%3D%200%3B%0Aunsigned%20int%20DMX_Start_Channel%20%3D%200%3B» message=»» highlight=»» provider=»manual»/]
Самой сложной задачей является разделение посылок между собой. Для этих целей предусмотрен интервал тишины. Линия опускается в 0, что является старт-битом. Далее микроконтроллер ждет данные и 2 стоп-бита. Последних он так и не дожидается, что генерирует ошибку «Frame Error». Микроконтроллер выставляет флаг, который позволяет определить начало нового пакета.
[pastacode lang=»c» manual=»ISR(USART_RXC_vect)%0A%7B%0A%20%20%20%20unsigned%20char%20UART_Status%20%3D%20UCSRA%3B%0A%20%20%20%20unsigned%20char%20UART_Data%20%3D%20UDR%3B%0A%20%20%20%20%2F%2F%20%D0%9E%D0%B1%D0%BD%D0%B0%D1%80%D1%83%D0%B6%D0%B5%D0%BD%D0%B0%20%D0%BE%D1%88%D0%B8%D0%B1%D0%BA%D0%B0%20(Frame%20error)%0A%20%20%20%20if%20(UART_Status%20%26%20(1%3C%3CFE))%7B%0A%20%20%20%20%20%20%20%20DMX_Current_Channel%20%3D%200%3B%0A%20%20%20%20%20%20%20%20DMX_Break%20%3D%201%3B%0A%20%20%20%20%7D%20else%20if%20(DMX_Break%20%3D%3D%201)%7B%0A%20%20%20%20%20%20%20%20int%20index%20%3D%20DMX_Current_Channel%20-%20DMX_Start_Channel%20-%201%3B%0A%20%20%20%20%20%20%20%20if%20((index%20%3E%3D%200)%20%26%26%20(index%20%3C%20COUNT_CHANNELS))%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20data%5Bindex%5D%20%3D%20UART_Data%3B%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20DMX_Current_Channel%2B%2B%3B%0A%20%20%20%20%7D%0A%7D» message=»» highlight=»» provider=»manual»/]
Дополнительное условие (DMX_Break == 1) является костылем и предотвращает установку ложных значений при включении устройства посреди передачи.
В результате мы имеем массив, где лежат значения на интересующих нас каналах. Что с ними делать — придумайте сами. Например LED прожектор или даже, при наличии пары сервоприводов, полноценная голова! Тут только стоит проявить фантазию!
К статье оригинальной статье были приложены два варианта устройств. Первый — тестер линии с отображением данных первого канала на семисегментных индикаторах (3 цифры). Практической пользы от такого устройства мало, но для обучения можно и собрать на макетной плате. Второе же устройство куда полезнее. В нем я использовал выводы с ШИМ, данные для которых поступают по DMX-512. Его можно использовать для оцифровки старых аналоговых диммеров, управляемых сигналом 0-10 Вольт (добавив операционный усилитель), или же для сборки собственных приборов.
Исходный код и прошивки для Atmega8
После оцифровывал старенький димер, но там было уже 6 каналов, а Atmega8 имеет всего 4 аппаратных ШИМ. Перенес код под Atmega48/88/168/328. Прошивка не совсем соответствует схеме устройства, так как при разводке платы все выводы DIP переключателя перепутались.
Исходный код и прошивка 6-канального димера на Atmega48/88/168/328
may i know, how we use it togather with freestyler or qlc.
what driver we use it. in those program.
thank you.
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.
this device can be use for martin lightjockey too?
Yes.