En el proceso de automatización doméstica, se descubrió que el medidor de flujo de gas VK-G4 disponible tiene una característica interesante: un imán está integrado en la descarga de bajo orden que puede cerrar el interruptor de láminas instalado fuera del dispositivo (es decir, no se requiere permiso para conectarlo). compañía de gas). Esto incluso se indica en el pasaporte en el mostrador. Es cierto que se recomienda que utilice el "Generador de pulsos de baja frecuencia IN-Z 61", pero en realidad es solo un interruptor de láminas montado en un medidor por un precio increíble. Por lo tanto, en lugar de IN-Z 61, se decidió utilizar el sensor Hall más barato con una salida digital (es decir, con un disparador Schmitt integrado).Del disponible se tomó el sensor Hall tipo SS441A. De acuerdo con la hoja de datos del SS44xA, su sensibilidad magnética está codificada en el tercer dígito, que determina la ubicación física del sensor en el medidor de gas.Como sistema de control, uso una computadora Banana PI de placa única con Linux (vanilla kernel 4.2+). La conexión física del SS44xA es muy simple:conectamos la salida (-) a un cable común;la salida (+) está conectada a + 5V (y no a + 3.3V);el pin (D) está conectado al puerto GPIO y atravesó una resistencia de 4.7 kΩ a + 3.3V.¡Pero cuál fue mi sorpresa cuando no pude encontrar controladores en el núcleo del árbol que pudieran contar la cantidad de pulsos en un puerto GPIO dado! Entiendo que Linux no es un sistema operativo en tiempo real, solo cuenta pulsos de baja frecuencia ... ¿Realmente ha sido mi trabajo?Después de mirar cuidadosamente las últimas fuentes del núcleo, se descubrieron dos soluciones intermedias:- Use un controlador UIO estándar. Si dicho dispositivo se abre como un archivo en el programa de aplicación y se le escribe el valor correspondiente, la operación de lectura posterior se suspenderá hasta que se produzca una interrupción debido a un cambio en el nivel de señal en el GPIO correspondiente;
- gpio_keys. GPIO «» (button) «» (switch), , .
El uso de cualquiera de estas soluciones requerirá una aplicación daemon que debe estar activa para realizar el conteo de pulsos. Esta no es la mejor solución, porque si se completa por alguna razón, podemos omitir un cierto número de pulsos, lo cual es bastante crítico para fines contables. Por lo tanto, para minimizar los riesgos, se decidió escribir nuestro propio controlador de dispositivo que funcionaría directamente a nivel del núcleo.Entonces, conozca: un controlador para contar pulsos en una línea GPIO arbitraria , configurable usando la tecnología Device Tree.Condiciones previas- Usó el kernel de Linux versión 4.xo posterior
- Archivos de encabezado del kernel utilizados para compilarlo (generalmente ubicado en / usr / include / linux en el sistema de destino)
- -
- Device Tree
- Device Tree ( dtc)
Para mi trabajo, utilizo el ensamblado de Armbian , y en su sitio web también puede tomar las fuentes del núcleo, sobre la base de las cuales se preparó el ensamblaje. Pero, en principio, no debería haber restricciones en el ensamblado objetivo.No describo el ensamblaje del módulo externo aquí (¿y qué? En principio, hay una gran cantidad de recursos con dicha descripción), por lo que creemos que ya tiene ensamblados los módulos counters.ko gpio-pulse.ko para su núcleo. Describo el proceso posterior utilizando el ejemplo de Banana PI, pero por analogía se puede transferir a cualquier otra plataforma.Abra la placa de descripción del conector.a bordo. Estamos interesados en el conector CON3 (encabezados GPIO). Seleccionamos cualquier contacto que nos guste y determinamos su funcionalidad (por ejemplo, me gustó el pin 12 en el conector CON3, al que está conectado el puerto de enchufe PH2). Verificamos con la hoja de datos Allwinner A20 (tabla de funciones de multiplexación GPIO): el puerto seleccionado debe admitir la generación de interrupciones (en mi caso, es EINT2 en la columna Multi 6). A continuación, debemos determinar el número de pin en términos de GPIO, que corresponde al puerto seleccionado (PH2). Me resultó más fácil determinar esto directamente en el dispositivo de trabajo:# grep '(PH2)' /sys/kernel/debug/pinctrl/1c20800.pinctrl/pinmux-pinspin 226 (PH2): (MUX NO RECLAMADO) (GPIO NO RECLAMADO)al mismo tiempo y me aseguré que este puerto no está siendo utilizado por nada (MUX y GPIO NO RECLAMADO).Ahora puede crear una configuración de árbol de dispositivos. Algunos ejemplos para algunos dispositivos están en el código fuente del kernel de Linux en la carpeta arch / arm / boot / dts, para Banana el archivo PI se llama sun7i-a20-bananapi.dts.En él hacemos los siguientes cambios:/ {
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>;
gpios = <&pio 7 2 GPIO_ACTIVE_LOW>;
interrupt-parent = <&pio>;
interrupt-names = "counter-edge-falling";
interrupts = <2 IRQ_TYPE_EDGE_FALLING>;
};
};
&pio {
...
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>;
};
};
El parámetro gpios en el nodo se calcula de la siguiente manera:- Primero viene un enlace a la etiqueta pio;
- El siguiente es el número de banco, que contiene el puerto GPIO deseado. Para Allwinner A20, cada banco contiene 32 puertos, por lo que el número de banco se define como la parte entera de dividir el pin GPIO por 32;
- El siguiente es el número de pin dentro del banco. Porque cada banco tiene 32 pines, entonces este valor se calcula como el resto de dividir el pin GPIO por 32;
- El último parámetro es una indicación de qué nivel de señal se considera activo
El parámetro de interrupciones en el nodo se calcula de la siguiente manera:- El primer parámetro indica el número de interrupción del controlador GPIO (para EINT2 será 2)
- El segundo parámetro es IRQ_TYPE_EDGE_FALLING, que permite la generación de una interrupción cuando la señal va de mayor a menor (porque tenemos un sensor de colector abierto y lo colocamos en + VCC)
Compilamos el archivo modificado del Árbol de dispositivos:dtc -I dts -O dtb sun7i-a20-bananapi.dts > sun7i-a20-bananapi.dtb
Con el sun7i-a20-bananapi.dtb resultante, sobrescribimos el archivo en /boot/dtb/sun7i-a20-bananapi.dtb. Escribimos losmódulos del núcleo counters.ko gpio-pulse.ko en cualquier lugar de / lib / modules / $ (uname -r) / kernel / drivers y cargar el sistema de destino. En el sistema de destino cargado, le damos el comandodepmod -a
y reiniciar de nuevo. Después de eso, miramos la salida del comando dmesg:
...
[ 4.745570] counters: Class driver loaded.
[ 4.749235] gpio_pulse: Device
...
Genial, los módulos están cargados y son funcionales. Verificamos primero la funcionalidad mediante programación:
0
1
3
(imitamos una señal por software).Ahora conectamos el sensor Hall y nos aseguramos de su operatividad trayendo un imán (por ejemplo, de una etiqueta magnética en el refrigerador).Epílogo
Finalmente, tuve tiempo de publicar fotos. Entonces: enrealidad el sensor. Su parte sensible es el lado sin biseles (es decir, apretamos al metro bajo la menos alta).
Entonces fijar el sensor con cinta aislante.
Para la fuerza, cortar un trozo de espuma en el medidor de gas para el tamaño de la cavidad y luego fijar el sensor a él.
Entonces fijar esta pieza y el cable con cinta aislante.
Bueno y esto es lo que sucedió como resultado.
Para la decisión sobre los sujetadores, no patee los pies, porque La casa todavía está en reparaciones y accesorios, de hecho, es un prototipo.