Показаны сообщения с ярлыком GPIO. Показать все сообщения
Показаны сообщения с ярлыком GPIO. Показать все сообщения

среда, 19 апреля 2017 г.

Raspberry Pi 3, pigpio, шина DALI и программа для работы с ней

см. ранее Raspberry Pi 3, работа с GPIO в Linux и DALI

Ядро программы на C под Raspbian, которое умеет отправлять и принимать сообщения шины DALI, готово. Для подключения Raspberry к шине используется самодельный адаптер на GPIO. Для работы с GPIO - библиотека pigpio (почему именно она - см. ранее).

Ради организации полной проверки программы, в плане работы с сигналами, проверки адаптера и GPIO, учитывая описанные ранее сложности с задержками в многопотоковой среде, я реализовал процедуру поиска устройств на шине DALI по неизвестным длинным адресам - самый сложный алгоритм, который обязано выполнять любое устройство DALI-мастер.
Он подразумевает посылку множества команд в шину и получение ответов, причем от каждого ответа зависит все дальнейшее поведение алгоритма - при сбоях в приеме запросов устройствами или получении ответов весь алгоритм ломается. Вообще, программа похожа на бинарный поиск в отсортированном массиве из 16 миллионов адресов, причем последовательно обнаруживается устройство с самым меньшим значением адреса среди еще не найденных.

Поэтому с одной стороны, алгоритм наиболее интересен, с другой он работает только при стабильной работе шины, а с третьей, он необходим для подключения и конфигурирования каждого нового управляемого устройства.
За два вечера все заработало как надо (тестовый стенд на фото - два 4-х канальных диммера подключены к шине и дают 8 самостоятельных устройств DALI, каждое со своим адресом).

Raspberry в корпусе, адаптер, диммеры и сигнал DALI на экране:
посылка запроса и ответ от диммера

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

Проблема оказалась в формировании сигнала в библиотеке pigpio: она требует указания ширины каждого импульса в микросекундах, выдавая при этом сигнал, по моим замерам, на 15% длиннее запрошенного. Из-за этого диммер не всего мог правильно расшифровать принятый фрейм. После учета этой коррекции программа заработала как часы. Проблема, думается, не зашита в код pigpio, а зависит от каких-то факторов, скажем, версии Raspberry (Pi 3), Raspbian (последняя на апрель 2017 года) или настроек каких-либо таймингов системы (я лично ничего не менял, кроме скорости работы SD-карты). Т.е. это ошибка, но проявляется не у всех.

Другая трудность - на нее я уже жаловался - недоступность полной документации по системе команд DALI и расшифровке ответов. Приходится комбинировать, часто неточную или неверную, информацию из нескольких источников, включая анализ доступного в интернете исходного кода программ.

понедельник, 17 апреля 2017 г.

Raspberry Pi 3, работа с GPIO в Linux и DALI

см. ранее Освещение на протоколе DALI и его компоненты

Raspberry привлекает не только как маленький и дешевый компьютер, но и наличием GPIO - цифровых интерфейсов ввода-вывода, и с первого взгляда похож на мощный микроконтроллер, вроде замены, Arduino, вкупе с Linux-сервером. Заманчиво, заманчиво...

Я приобрел Raspberry в качестве сервера заботливой ("умной") квартиры, имея ввиду подключение к нему шины управления светом DALI через простой самодельный адаптер, вероятных цифровых датчиков, вроде температуры, видеокамер, как датчиков движения и охраны, ну, и тому подобное.
И вот теперь, начиная писать под Raspbian (официальный Linux для Raspberry), я понимаю свое заблуждение про универсальность.

В общем, Raspberry с Raspbian производит приятное впечатление: работает сразу после копирования системы на SD-карту и подключения hdmi, загружается быстро. Замечая отсутствие хорошей документации, известную медленную работу с SD, пока не пошаманишь и слабый Wi-Fi, начинается понимание, что Raspberry - не зрелый продукт серьезной фирмы, а неплохая реализация неплохой идеи, но, "на коленке". Нет, я только "за" и поддерживаю кошельком, я скорее про завышенные ожидания.

Итак, возвращаясь к настоящей задаче - добавлению квартирному серверу функции управления освещением по интерфейсу DALI.

адаптер собран, к Raspberry подключен (2xGPIO и питание)

Для приема данных 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 такое поведение необходимо только исполнительным устройствам, но не мастер-контроллеру.