No processo de automação doméstica, descobriu-se que o medidor de vazão de gás VK-G4 disponível tem uma característica interessante: um ímã é incorporado à descarga de baixa ordem que pode fechar a chave reed instalada fora do próprio dispositivo (ou seja, não é necessária permissão para conectá-lo) empresa de gás). Isso é indicado no passaporte no próprio balcão. É verdade que é recomendável usar o "gerador de pulsos de baixa frequência IN-Z 61", mas, na realidade, é apenas uma chave reed montada em um medidor por um preço insano. Portanto, em vez do IN-Z 61, decidiu-se usar o sensor Hall mais barato com uma saída digital (ou seja, com um gatilho Schmitt integrado).A partir do disponível foi retirado o sensor Hall tipo SS441A. De acordo com a folha de dados do SS44xA, sua sensibilidade magnética é codificada no terceiro dígito, que determina a localização física do sensor no medidor de gás.Como sistema de controle, eu uso um computador Banana PI de placa única executando Linux (vanilla kernel 4.2+). A conexão física do SS44xA é muito simples:conectamos a saída (-) a um fio comum;a saída (+) está conectada a + 5V (e não a + 3,3V);o pino (D) é conectado à porta GPIO e puxado através de um resistor de 4,7 kΩ para + 3,3V.Mas qual foi a minha surpresa quando não consegui encontrar drivers de árvore do kernel que pudessem contar o número de pulsos em uma determinada porta GPIO! Entendo que o Linux não é um sistema operacional em tempo real, mas apenas contando pulsos de baixa frequência ... Realmente foi meu trabalho?Tendo analisado cuidadosamente as fontes mais recentes do kernel, duas soluções intermediárias foram descobertas:- Use um driver UIO padrão. Se um dispositivo desse tipo for aberto como um arquivo no programa aplicativo e o valor correspondente for gravado nele, a operação de leitura subsequente será suspensa até que ocorra uma interrupção devido a uma alteração no nível do sinal no GPIO correspondente;
- gpio_keys. GPIO «» (button) «» (switch), , .
O uso de qualquer uma dessas soluções exigirá um aplicativo daemon que deve estar ativo para executar a contagem de pulsos. Esta não é a melhor solução, porque, se for concluída por qualquer motivo, podemos pular um certo número de pulsos, o que é bastante crítico para fins contábeis. Portanto, para minimizar os riscos, foi decidido escrever nosso próprio driver de dispositivo que funcionaria diretamente no nível do kernel.Portanto, conheça: um driver para contar pulsos em uma linha GPIO arbitrária , configurável usando a tecnologia Device Tree.Condições prévias- Versão do kernel Linux usada 4.x ou posterior
- Arquivos de cabeçalho do kernel usados para construí-lo (geralmente localizado em / usr / include / linux no sistema de destino)
- -
- Device Tree
- Device Tree ( dtc)
Para o meu trabalho, uso o assembly da Armbian e, no site deles, você também pode usar as fontes do kernel, com base nas quais o assembly foi preparado. Mas, em princípio, não deve haver restrições no conjunto de destino.Não descrevo a montagem do módulo externo (e o quê? Em princípio, existem muitos recursos com essa descrição), portanto acreditamos que você já tenha os contadores prontos.ko módulos gpio-pulse.ko montados para o seu núcleo. Descrevo o processo posterior usando o exemplo do Banana PI, mas por analogia, ele pode ser transferido para qualquer outra plataforma.Abra a placa de descrição do conectorno quadro. Estamos interessados no conector CON3 (GPIO Headers). Selecionamos qualquer contato que gostamos e determinamos sua funcionalidade (por exemplo, gostei do pino 12 no conector CON3, ao qual a porta do soquete PH2 está conectada). Verificamos com a folha de dados do Allwinner A20 (tabela de funções de multiplexação GPIO) - a porta selecionada deve suportar a geração de interrupções (no meu caso, é EINT2 na coluna Multi 6). Em seguida, precisamos determinar o número do pino em termos de GPIO, que corresponde à porta selecionada (PH2). Foi mais fácil determinar isso diretamente no dispositivo em funcionamento:# grep '(PH2)' /sys/kernel/debug/pinctrl/1c20800.pinctrl/pinmux-pinspin 226 (PH2): (MUX UNCLAIMED) (GPIO UNCLAIMED)ao mesmo tempo e certificou-se que esta porta não está sendo usada atualmente por nada (MUX e GPIO UNCLAIMED).Agora você pode criar uma configuração da Árvore de Dispositivos. Exemplos para alguns dispositivos estão disponíveis nos arquivos de origem do kernel Linux na pasta arch / arm / boot / dts; para Banana, o arquivo PI é chamado sun7i-a20-bananapi.dts.Nele, fazemos as seguintes alterações:/ {
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>;
};
};
O parâmetro gpios no nó é calculado da seguinte maneira:- Primeiro vem um link para o rótulo do pio;
- A seguir, é o número do banco, que contém a porta GPIO desejada. Para o Allwinner A20, cada banco contém 32 portas; portanto, o número do banco é definido como a parte inteira da divisão do pino GPIO por 32;
- Em seguida é o número do pino dentro do banco. Porque cada banco possui 32 pinos, esse valor é calculado como o restante da divisão do pino GPIO por 32;
- O último parâmetro é uma indicação de qual nível de sinal é considerado ativo
O parâmetro interrupts no nó é calculado da seguinte maneira:- O primeiro parâmetro indica o número de interrupção do controlador GPIO (para EINT2 será 2)
- O segundo parâmetro é IRQ_TYPE_EDGE_FALLING, que permite gerar uma interrupção quando o sinal passa de alto a baixo (porque temos um sensor coletor aberto e puxado para + VCC)
Nós compilamos o arquivo da Árvore de Dispositivos modificado:dtc -I dts -O dtb sun7i-a20-bananapi.dts > sun7i-a20-bananapi.dtb
Com o sun7i-a20-bananapi.dtb resultante, substituímos o arquivo em /boot/dtb/sun7i-a20-bananapi.dtb. Escrevemos osmódulos do kernel counters.ko gpio-pulse.ko em qualquer lugar em / lib / modules / $ (uname -r) / kernel / drivers e carregue o sistema de destino. No sistema de destino carregado, damos o comandodepmod -a
e reinicie novamente. Depois disso, examinamos a saída do comando dmesg:
...
[ 4.745570] counters: Class driver loaded.
[ 4.749235] gpio_pulse: Device
...
Ótimo, os módulos estão carregados e funcionais. Verificamos a funcionalidade primeiro programaticamente:
0
1
3
(imitamos um sinal por software).Agora, conectamos o sensor Hall e garantimos sua operacionalidade, trazendo algum ímã para ele (por exemplo, de um adesivo magnético na geladeira).Posfácio
Finalmente, tive tempo para postar fotos. Então:Na verdade, o sensor. A sua parte sensível é o lado sem chanfros (isto é, que pressioná-lo para o contador sob o mínimo de descarga).
Em seguida, fixar o sensor com fita isolante.
Para maior resistência, cortar um pedaço de espuma para o contador de gás para o tamanho do recesso e, em seguida, fixar o sensor a ele.
Em seguida, fixar esta peça e o fio com fita isolante.
Bem e foi o que aconteceu como resultado:
para a decisão sobre fixadores, não chute o pé, porque a casa ainda está passando por reparos e acessórios, de fato, é um protótipo.