В ходе выполнения Домашняя автоматизация Выяснилось, что имеющийся в наличии расходомер газа ВК-Г4 имеет интересную особенность: его младший разряд имеет встроенный магнит, способный замыкать геркон, установленный снаружи самого прибора (т.е.
разрешение газовой компании не требуется).
чтобы его подключить).
Об этом говорится даже в заграничный пасспорт на самой стойке.
Правда, рекомендуется использовать «Генератор НЧ-импульсов ИН-З 61», но по сути это всего лишь геркон, установленный на счетчике за заоблачную цену.
Поэтому вместо ИН-З 61 было решено использовать самый дешевый датчик Холла с цифровым выходом (т.е.
со встроенным триггером Шмитта).
Из имеющегося в наличии был взят датчик Холла типа SS441A. В соответствии с техническая спецификация на SS44xA третья цифра кодирует его магнитную чувствительность, которая определяет физическое расположение датчика на газовом счетчике.
В качестве системы управления я использую одноплатный компьютер Banana PI под управлением ОС Linux (ванильное ядро 4.2+).
Физическое подключение SS44xA очень простое: соедините выход (-) с общим проводом; контакт (+) подключен к +5В (а не к +3,3В); вывод (D) подключен к порту GPIO и через резистор 4,7 кОм подтянут к +3,3В.
Но каково же было мое удивление, когда я не смог найти драйверы ядра, способные просто подсчитывать количество импульсов на данном порту GPIO! Я так понимаю, Linux - это не ОС реального времени, а просто считающий низкочастотные импульсы.
У меня одного такая проблема? Внимательно просмотрев последние исходники ядра, было обнаружено два промежуточных решения:
- Используйте стандартный драйвер UIO. Если такое устройство открыть как файл в прикладной программе и записать в него соответствующее значение, то последующая операция чтения из него будет приостановлена до тех пор, пока не произойдет прерывание, вызванное изменением уровня сигнала на соответствующем GPIO;
- Используйте стандартный драйвер gpio_keys. С его помощью можно объявить GPIO как «кнопку» или «переключатель» и отлавливать события в прикладной программе, связанные с изменением их состояния.
Это не лучшее решение, так как если оно по какой-то причине закончится, мы можем пропустить определенное количество импульсов, что весьма критично для целей учета.
Поэтому, чтобы минимизировать риски, было решено написать собственный драйвер устройства, который бы работал непосредственно на уровне ядра.
Итак, знакомьтесь: драйвер для подсчета импульсов на произвольной линии GPIO настраивается с использованием технологии дерева устройств.
Предварительные условия
- Используемое ядро Linux версии 4.x или выше.
- Файлы заголовков ядра, используемые для его сборки (обычно находятся в /usr/include/linux в целевой системе).
- Инструменты для компиляции модулей в целевой системе или инструменты для кросс-компиляции
- Исходный или двоичный файл дерева устройств для используемой аппаратной платформы.
- Дерево устройств для двоичного компилятора (программа dtc)
Но в принципе ограничений на целевую сборку быть не должно.
Я не описываю здесь сборку внешнего модуля (нужно ли? в принципе, ресурсов с таким описанием довольно много), поэтому будем считать, что у вас уже есть готовые модули counters.ko gpio-pulse.ko собран для вашего ядра.
Дальнейший процесс я описываю на примере Banana PI, но по аналогии его можно перенести на любую другую платформу.
Открытие этикетка разъема на борту.
Нас интересует разъем CON3 (GPIO Headers).
Выбираем любой понравившийся контакт и определяем его функциональность (например, мне понравился пин 12 на разъеме CON3, к которому подключен разъем-порт PH2).
Проверка с помощью Техническое описание Allwinner A20 (таблица функций мультиплексирования GPIO) — выбранный порт должен поддерживать генерацию прерываний (в моем случае это EINT2 в столбце Multi 6).
Далее нам нужно определить номер пина через GPIO, который соответствует выбранному порту (PH2).
Мне было проще это определить непосредственно на рабочем устройстве: # grep '(PH2)' /sys/kernel/debug/pinctrl/1c20800.pinctrl/pinmux-pins контакт 226 (PH2): (MUX НЕ ЗАЯВЛЕН) (GPIO НЕ ЗАЯВЛЕН) при этом я убедился, что этот порт в данный момент ничем не используется (MUX и GPIO UNCLAIMED).
Теперь вы можете создать конфигурацию дерева устройств.
Примеры для некоторых устройств доступны в исходном коде ядра Linux в папке Arch/arm/boot/dts; для Banana PI файл называется sun7i-a20-bananapi.dts В нем вносим следующие изменения:
Параметр gpios в узле рассчитывается следующим образом:/ { model = "Banana Pi BPI-M1"; compatible = "sinovoip,bpi-m1", "allwinner,sun7i-a20"; .
counters { compatible = "gpio-pulse-counter"; gas-meter@0 { label = "Gas meter"; pinctrl-names = "default"; pinctrl-0 = <&ext_counter_bananapi>; /* CON3, pin 12: PH2 - pin 226 (Multi6 function: EINT2) */ /* bank: 226 / 32 = 7, pin into the bank 226 % 32 = 2 */ gpios = <&pio 7 2 GPIO_ACTIVE_LOW>; interrupt-parent = <&pio>; interrupt-names = "counter-edge-falling"; interrupts = <2 IRQ_TYPE_EDGE_FALLING>; /* PH2 / EINT2 */ }; }; &pio { .
/* External counter */ ext_counter_bananapi: counter_pins@0 { allwinner,pins = "PH2"; allwinner,function = "gpio_in"; allwinner,drive = <SUN4I_PINCTRL_10_MA>; allwinner,pull = <SUN4I_PINCTRL_NO_PULL>; }; };
- Сначала идет ссылка на метку pio;
- Далее идет номер банка, который содержит нужный порт GPIO. В Allwinner A20 каждый банк содержит 32 порта, поэтому номер банка определяется как целая часть вывода GPIO, деленная на 32;
- Далее идет пин-код внутри банка.
Поскольку каждый банк имеет 32 контакта, это значение рассчитывается как остаток от деления контакта GPIO на 32;
- Последний параметр указывает, какой уровень сигнала считается активным.
- Первый параметр указывает номер прерывания контроллера GPIO (для EINT2 будет 2)
- Второй параметр — IRQ_TYPE_EDGE_FALLING, который позволяет генерировать прерывание при переходе сигнала с высокого уровня на низкий уровень (поскольку наш датчик — открытый коллектор и подключен к +VCC)
dtc -I dts -O dtb sun7i-a20-bananapi.dts > sun7i-a20-bananapi.dtb
Получив полученный файл sun7i-a20-bananapi.dtb, переписываем файл в /boot/dtb/sun7i-a20-bananapi.dtb. Записываем модули ядра counters.ko gpio-pulse.ko в любое место внутри /lib/modules/$(uname -r)/kernel/drivers и загружаем целевую систему.
На загруженной целевой системе мы выдаем команду depmod -a
и снова перезагрузитесь.
После этого посмотрите на вывод команды dmesg: # dmesg
.
[ 4.745570] counters: Class driver loaded. [ 4.749235] gpio_pulse: Device #0 gas-meter: IRQ: 53 GPIO: 226 .
Отлично, модули загружены и работоспособны.
Сначала проверяем работоспособность программно: # cat /sys/class/counters/counter0/values/count
0
# echo 1 > /sys/class/counters/counter0/values/pulse
# cat /sys/class/counters/counter0/values/count
1
# echo 1 > /sys/class/counters/counter0/values/pulse
# echo 1 > /sys/class/counters/counter0/values/pulse
# cat /sys/class/counters/counter0/values/count
3
(мы моделировали сигнал с помощью программного обеспечения).
Теперь подключаем датчик Холла и убеждаемся в его работе, поднеся к нему какой-нибудь магнит (например, от магнитной наклейки на холодильнике).
Послесловие
Наконец-то у меня появилось время выложить фотографии.Так: Настоящий датчик.
Чувствительной его частью является сторона без скосов (т.е.
прижимаем к счетчику под младшей цифрой)
Затем зафиксируйте датчик изолентой
Для прочности вырезаем кусок пенопласта по размеру углубления в газовом счетчике и дополнительно закрепляем им датчик
Затем закрепляем этот кусок и провод изолентой
Ну вот что в результате получилось
Прошу не пинать решение по поводу крепежа, потому что.
В доме еще идет ремонт и крепеж, по сути, прототипы.
Теги: #linux #Raspberry Pi #Умный дом #GPIO #Allwinner #геркон #banana pi #Дерево устройств #Датчик Холла #VK-G4 #UIO #gpio_keys #holl #SS441A
-
Будущее Web 2.0 – Бизнес 2.0?
19 Oct, 24 -
Многодоменный Сервер Nginx -> Apache
19 Oct, 24