см. ранее Освещение на протоколе DALI и его компоненты
Raspberry привлекает не только как маленький и дешевый компьютер, но и наличием GPIO - цифровых интерфейсов ввода-вывода, и с первого взгляда похож на мощный микроконтроллер, вроде замены, Arduino, вкупе с Linux-сервером. Заманчиво, заманчиво...
Я приобрел Raspberry в качестве сервера заботливой ("умной") квартиры, имея ввиду подключение к нему шины управления светом DALI через простой самодельный адаптер, вероятных цифровых датчиков, вроде температуры, видеокамер, как датчиков движения и охраны, ну, и тому подобное.
И вот теперь, начиная писать под Raspbian (официальный Linux для Raspberry), я понимаю свое заблуждение про универсальность.
В общем, Raspberry с Raspbian производит приятное впечатление: работает сразу после копирования системы на SD-карту и подключения hdmi, загружается быстро. Замечая отсутствие хорошей документации, известную медленную работу с SD, пока не пошаманишь и слабый Wi-Fi, начинается понимание, что Raspberry - не зрелый продукт серьезной фирмы, а неплохая реализация неплохой идеи, но, "на коленке". Нет, я только "за" и поддерживаю кошельком, я скорее про завышенные ожидания.
Итак, возвращаясь к настоящей задаче - добавлению квартирному серверу функции управления освещением по интерфейсу DALI.
Для приема данных DALI нужно уметь считывать состояние цифрового входа не реже 1/2400 секунды или раз в 0,4 мс. Эта простейшая задача для любого копеечного микроконтроллера, однако, под Raspbian сталкивается с серьезными трудностями. Все дело в работающих параллельно моей программе процессах Linux kernel (даже при отсутствии других запущенных программ). Из-за них процесс, читающий состояние GPIO или, что правильнее, вызываемый по прерыванию на фронт сигнала, получает управление нерегулярно и с задержками. Для человека задержка процесса на 2 мс не заметна, и она допустима для настольных многозадачных систем, но для чтения сигнала скоростью более 250 бит/c - почти фатальна.
Начиная программировать на C под Raspbian я узнал, что встроенной в систему поддержки работы с GPIO как бы и нет. И нашел стороннюю библиотеку bcm2835. С ее помощью я проверил, что адаптер работает и сигналы DALI видит. Попытка написать процедуру чтения данных DALI разбилась о тот факт, что bcm2835 не поддерживает прерывания. Вообразите мое разочарование: любой микроконтроллер о шести ножках за 30 центов поддерживает прерывания и GPIO, а Raspberry Pi под официальной Raspbian с официальной поддержкой GPIO, не работает из коробки не только с прерываниями, но и с GPIO.
Новые поиски библиотеки работы с цифровыми входами навели на wiringPi, с прерываниями. И новый опыт показал затруднения программной работы с DALI из-за случайных задержек, описанных выше: при появлении на входе сигнала выставляется флаг прерывания, однако, при параллельно работающих процессах ядра, которые сами активно управляют прерываниями, моя функция периодически вызывается с задержкой, из-за которой часть данных DALI оказывается "не услышана". Если говорить о реальных тестах, то на Raspbian, где работает только программа прослушивания DALI, я получаю 5% ошибок из-за задержек до 2 мс (из которых 2% вполне реально исправить алгоритмом).
Третья по счету библиотека - pigpio - работает с GPIO через DMA (процесс работы с памятью, реализованный аппаратно, поэтому прерывания и другие сложности в ядре процессора ему не должны мешать). Библиотека обещает точность временных интервалов порядка 5 мкс. Такие времена вполне подходят для декодирования DALI. Только нужно понимать, что задержки в вызове программы никуда не денутся. Она будет получать все биты с цифрового входа и точное время появления каждого бита, но получать их с опозданием. Поэтому возможность реализации процесса, где после получения данных требуется ответить за определенный интервал времени, остается под вопросом, благо, в DALI такое поведение необходимо только исполнительным устройствам, но не мастер-контроллеру.
Raspberry привлекает не только как маленький и дешевый компьютер, но и наличием GPIO - цифровых интерфейсов ввода-вывода, и с первого взгляда похож на мощный микроконтроллер, вроде замены, Arduino, вкупе с Linux-сервером. Заманчиво, заманчиво...
Я приобрел Raspberry в качестве сервера заботливой ("умной") квартиры, имея ввиду подключение к нему шины управления светом DALI через простой самодельный адаптер, вероятных цифровых датчиков, вроде температуры, видеокамер, как датчиков движения и охраны, ну, и тому подобное.
И вот теперь, начиная писать под Raspbian (официальный Linux для Raspberry), я понимаю свое заблуждение про универсальность.
В общем, Raspberry с Raspbian производит приятное впечатление: работает сразу после копирования системы на SD-карту и подключения hdmi, загружается быстро. Замечая отсутствие хорошей документации, известную медленную работу с SD, пока не пошаманишь и слабый Wi-Fi, начинается понимание, что Raspberry - не зрелый продукт серьезной фирмы, а неплохая реализация неплохой идеи, но, "на коленке". Нет, я только "за" и поддерживаю кошельком, я скорее про завышенные ожидания.
Итак, возвращаясь к настоящей задаче - добавлению квартирному серверу функции управления освещением по интерфейсу DALI.
адаптер собран, к Raspberry подключен (2xGPIO и питание)
Начиная программировать на C под Raspbian я узнал, что встроенной в систему поддержки работы с GPIO как бы и нет. И нашел стороннюю библиотеку bcm2835. С ее помощью я проверил, что адаптер работает и сигналы DALI видит. Попытка написать процедуру чтения данных DALI разбилась о тот факт, что bcm2835 не поддерживает прерывания. Вообразите мое разочарование: любой микроконтроллер о шести ножках за 30 центов поддерживает прерывания и GPIO, а Raspberry Pi под официальной Raspbian с официальной поддержкой GPIO, не работает из коробки не только с прерываниями, но и с GPIO.
Новые поиски библиотеки работы с цифровыми входами навели на wiringPi, с прерываниями. И новый опыт показал затруднения программной работы с DALI из-за случайных задержек, описанных выше: при появлении на входе сигнала выставляется флаг прерывания, однако, при параллельно работающих процессах ядра, которые сами активно управляют прерываниями, моя функция периодически вызывается с задержкой, из-за которой часть данных DALI оказывается "не услышана". Если говорить о реальных тестах, то на Raspbian, где работает только программа прослушивания DALI, я получаю 5% ошибок из-за задержек до 2 мс (из которых 2% вполне реально исправить алгоритмом).
Третья по счету библиотека - pigpio - работает с GPIO через DMA (процесс работы с памятью, реализованный аппаратно, поэтому прерывания и другие сложности в ядре процессора ему не должны мешать). Библиотека обещает точность временных интервалов порядка 5 мкс. Такие времена вполне подходят для декодирования DALI. Только нужно понимать, что задержки в вызове программы никуда не денутся. Она будет получать все биты с цифрового входа и точное время появления каждого бита, но получать их с опозданием. Поэтому возможность реализации процесса, где после получения данных требуется ответить за определенный интервал времени, остается под вопросом, благо, в DALI такое поведение необходимо только исполнительным устройствам, но не мастер-контроллеру.
Здравствуйте! А почему бы не использовать для приема и передачи DALI банальный UART. Я в свое время написал для ARM обмен с 1Wire на UART.
ОтветитьУдалитьDALI физически несовместим с UART, начиная от напряжения (порядка 22 V против 3.3 или 5), способа формирования логических уровней (у DALI это замыкание линии через резистор, нормальное напряжение - высокое) и, заканчивая, почти уверен, способом формирования последовательности бит из перепадов уровней.
ОтветитьУдалитьЕстественно физику надо конвертировать, это ежу понятно.
ОтветитьУдалитьТогда не понятно, какой смысл конвертить ее в UART, если использованный мной, фактически, конвертер уровней, проще в реализации?
ОтветитьУдалитьКонвертор уровней останется. Принимать и передавать будет UART.
ОтветитьУдалитьХорошо. В чем смысл использования UART против GPIO, пусть даже фрейм DALI можно будет принять UART-ом (не очень ясно, как: фрейм может быть 8, 16 или 24 бита, причем старт и стоп биты одинарные)? В чем выгода?
ОтветитьУдалитьhttp://ww1.microchip.com/downloads/en/AppNotes/90003200A.pdf
ОтветитьУдалитьМеньше напрягаем процессор, минимизируем ошибки...
Насколько я понял, указанный UART модуль (TB3200) производит MC. В Raspberry 3 стоит SoC Broadcom BCM2837. Применимо ли описание TB3200 к Raspberry 3?
ОтветитьУдалить