Эмуляция ведомых 1-wire устройств на MSP430
Как-то раз я купил на eBay диммер для светодиодной ленты с ИК-пультом управления. Помимо того, факта, что через пару часов использования умер выходной MOSFET и его пришлось менять, со временем обнаружились следующие проблемы: Слишком низкая частота ШИМ. При низкой яркости мигание было видно невооруженным глазом. Наверное, это связано с параметрами работы выходного транзистора — если, например, время включения/выключения слишком большое, то частоту ШИМ повышать нельзя. Отсутствие каких-либо возможностей для коммуникации, кроме ИК-пульта. На плате обнаружилось много разных дополнительных разъемов (питание +5V, выход ШИМ и еще какие-то), но никакого другого интерфейса управления. Что, впрочем, логично. Иногда такие недостатки можно устранить доработкой прошивки, но на микроконтроллере была стерта маркировка, и ничего похожего в таком корпусе я на Digikey/Mouser не нашел. Было решено реализовать аналогичную схему, лишенную указанных недостатков. Из интерфейсов управления рядом оказался 1-wire. Так появилась библиотека для эмуляции slave-устройств, совместимых с 1-wire.
Протокол работы1-wire — двунаправленная шина связи. Устройства используют выход с открытым коллектором для изменения состояния линии данных, которая подтянута к +5V. Кодирование информации осуществляется с помощью времени, на которое устройство притягивает линию данных к 0. Более подробно о шине можно прочитать здесь.
Реализация на базе микроконтроллера MSP430G2553 Основная проблема — микроконтроллер питается от напряжения 3.3V максимум, на такое же напряжение рассчитаны порты GPIO. Для того, чтобы подключиться к линии данных, можно использовать два пина: один как вход (с подключением через резистивный делитель), второй — как выход (с использованием транзистора для соединения линии с землей). Ориентировочная схема представлена на рисунке ниже.
Линейный стабилизатор нужен, если планируется питать МК от 1-wire линии.
Код Созданная библиотека состоит из двух частей:
Код, обрабатывающий передачу отдельных бит (таймслотов), байтов, сигнала сброса и работающий с командами SEARCH и MATCH Код, отвечающий за какое-либо конкретное устройство. Эта часть обрабатывает доступ к регистровому пространству Зачем это сделано? Во-первых, для того, чтобы можно было легко перейти от одного устройства к другому. Во-вторых, у библиотеки есть возможность эмуляции нескольких устройств с разными адресами на одном микроконтроллере. Это возможно благодаря алгоритму поиска устройств на шине: микроконтроллер отвечает сразу за несколько адресов. Каждое такое виртуальное устройство отвечает за собственную часть периферии микроконтроллера.
Чтобы полученное устройство было совместимо с существующими решениями, был написан код для эмуляции микросхемы, частично совместимой с DS2408, которую по каким-то причинам перестали выпускать. Это позволяет использовать устройство вместе с owserver и owhttpd. В случае с диммером байт, отвечающий за состояние выходов микросхемы, задает скважность ШИМ-выхода.
Инициализировать библиотеку можно довольно просто:
#include
#include «one-slave.h» #include «one-2408.h»
// Массив с описаниями устройств static one_device devices[] = { { // (ROM-адрес) | (Family code) .rom = 0×0011223344556600 | ONE_2408_FC, // Функция инициализации предоставляется конкретным устройством .init = &one_2408_init, // Параметры устройства: в данном случае указатель на область регистров, // отвечающих за PORT1 в микроконтроллере .device = &(one_2408) { .port_base = &P1IN } }, { .rom = 0×00AA000000000100 | ONE_2408_PWM_FC, .init = &one_2408_pwm_init, // PWM-выход: P2.1 .device = &(one_2408_pwm) { .out_bit = BIT1, .port_base = &P2IN } } };
void main (void) { WDTCTL = WDTPW | WDTHOLD; one_init ( (one_device *) &devices, ARRAY_SIZE (devices) ); _EINT (); while (1) { one_process_state (); } } Железо Вместо существующей платы была создана другая:
В реальности плата выглядит хуже, потому что нашлось несколько огрехов, которые нужно было исправить. Использовать переменный резистор для ручной регулировки, к сожалению, не получилось — не хватило таймеров, из двух два были заняты. Создавать на основе аппаратного таймера много «программных» в данном случае нельзя, так как на линии все происходит довольно быстро (для МК) и код обработки прерывания таймера может испортить какой-нибудь таймслот длиной в 30 мкс.
В новой плате частота PWM составляет 15 кГц, увидеть мерцание глазами и камерой не получилось.
Подключение к Openhab Подключение к Openhab осуществляется довольно просто — с использованием биндинга HTTP. Для изменения яркости достаточно отправить запрос к owhttpd следующего вида:
http://owhttpd:2121/29.0100000000AA/PIO.BYTE/? PIO.BYTE=VALUE VALUE — значение от 0 до 255.
На телефоне это выглядит так:
Пульт управления тоже работать не перестал, он теперь работает через LIRC, который передает коды клавиш в Openhab. Благодаря Openhab при нажатии кнопок на пульте сразу изменяется состояние элементов управления на телефоне.
Заключение В заключение перечислю еще раз основные особенности библиотеки:
Работа на прерываниях, в промежутках между транзакциями микроконтроллер находится в режиме низкого энергопотребления Возможность эмуляции нескольких устройств на одном микроконтроллере Работа проверялась на MSP430G2553, теоретически, на других контроллерах этой серии тоже заработает Исходники можно найти здесь: github.com/resetnow/one-slave