Penghitung impuls di Linux (kami mendapatkan informasi tentang aliran gas dari penghitung VK-G4)

Dalam proses otomatisasi rumah tangga, ditemukan bahwa pengukur aliran gas VK-G4 yang tersedia memiliki fitur yang menarik: magnet dibangun ke dalam pengeluaran junior, yang dapat menutup sakelar buluh yang dipasang di luar perangkat itu sendiri (mis., Izin tidak diperlukan untuk menghubungkannya perusahaan gas). Ini bahkan ditunjukkan di paspor di konter itu sendiri. Benar, disarankan agar Anda menggunakan "generator pulsa frekuensi rendah IN-Z 61," tetapi pada kenyataannya itu hanya saklar buluh yang dipasang pada meter untuk harga gila. Oleh karena itu, alih-alih IN-Z 61, diputuskan untuk menggunakan sensor Hall termurah dengan output digital (mis. Dengan pemicu Schmitt terintegrasi).

Dari yang tersedia diambil sensor Hall tipe SS441A. Menurut datasheet pada SS44xA, sensitivitas magnetiknya dikodekan pada digit ketiga, yang menentukan lokasi fisik sensor pada meter gas.
Sebagai sistem kontrol, saya menggunakan komputer Banana PI satu papan yang menjalankan Linux (vanilla kernel 4.2+). Koneksi fisik SS44xA sangat sederhana: kami
menghubungkan output (-) ke kabel biasa;
output (+) terhubung ke + 5V (dan tidak ke + 3.3V);
pin (D) terhubung ke port GPIO dan ditarik melalui resistor 4,7 kΩ ke + 3,3V.
Tapi apa yang mengejutkan saya ketika saya tidak dapat menemukan driver kernel di-pohon yang hanya bisa menghitung jumlah pulsa pada port GPIO yang diberikan! Saya mengerti bahwa Linux bukan OS real-time, tetapi hanya menghitung pulsa frekuensi rendah ... Apakah ini benar-benar pekerjaan saya?
Setelah dengan hati-hati melihat sumber kernel terbaru, dua solusi menengah ditemukan:
  1. Gunakan driver UIO standar. Jika perangkat tersebut dibuka sebagai file dalam program aplikasi dan nilai yang sesuai ditulis untuk itu, operasi pembacaan selanjutnya dari itu akan ditangguhkan sampai gangguan terjadi karena perubahan level sinyal pada GPIO yang sesuai;
  2. gpio_keys. GPIO «» (button) «» (switch), , .

Menggunakan salah satu dari solusi ini akan memerlukan aplikasi daemon yang harus aktif untuk melakukan penghitungan pulsa. Ini bukan solusi terbaik, karena jika diselesaikan karena alasan apa pun, kita dapat melewati sejumlah pulsa, yang sangat penting untuk keperluan akuntansi. Oleh karena itu, untuk meminimalkan risiko, diputuskan untuk menulis driver perangkat kami sendiri yang akan bekerja secara langsung di tingkat kernel.
Jadi, ketemu: driver untuk menghitung pulsa pada jalur GPIO yang sewenang-wenang , dapat dikonfigurasi menggunakan teknologi Device Tree.

Prasyarat
  • Kernel Linux yang digunakan versi 4.x atau yang lebih baru
  • File header kernel digunakan untuk membangunnya (biasanya terletak di / usr / include / linux pada sistem target)
  • -
  • Device Tree
  • Device Tree ( dtc)

Untuk pekerjaan saya, saya menggunakan perakitan dari Armbian , dan di situs web mereka Anda juga dapat mengambil sumber kernel, atas dasar mana perakitan disiapkan. Namun, pada prinsipnya, seharusnya tidak ada batasan pada perakitan target.
Saya tidak menjelaskan perakitan modul eksternal di sini (dan apa? Pada prinsipnya, ada banyak sumber daya dengan deskripsi seperti itu), jadi kami percaya bahwa Anda sudah memiliki counter siap pakai. Modul gpio-pulse.ko sudah terpasang untuk kernel Anda. Saya menjelaskan proses lebih lanjut dengan menggunakan contoh Banana PI, tetapi secara analogi dapat ditransfer ke platform lain.

Buka pelat deskripsi konektordi papan tulis. Kami tertarik pada konektor CON3 (Header GPIO). Kami memilih kontak apa pun yang kami suka dan menentukan fungsinya (misalnya, saya menyukai pin 12 pada konektor CON3, yang terhubung ke port soket PH2). Kami memeriksa dengan lembar data Allwinner A20 (tabel fungsi multiplexing GPIO) - port yang dipilih harus mendukung generasi interupsi (dalam kasus saya ini adalah EINT2 di kolom Multi 6). Selanjutnya, kita perlu menentukan nomor pin dalam hal GPIO, yang sesuai dengan port yang dipilih (PH2). Lebih mudah bagi saya untuk menentukan ini secara langsung pada perangkat yang berfungsi:

# grep '(PH2)' /sys/kernel/debug/pinctrl/1c20800.pinctrl/pinmux-pins
pin 226 (PH2): (MUX UNCLAIMED) (GPIO UNCLAIMED)

pada saat yang sama dan memastikan bahwa port ini saat ini tidak digunakan oleh apa pun (MUX dan GPIO TIDAK TERMASUK).

Sekarang Anda dapat membuat konfigurasi Device Tree. Contoh untuk beberapa perangkat ada dalam kode sumber kernel Linux di folder arch / arm / boot / dts, untuk Banana file PI disebut sun7i-a20-bananapi.dts
Di dalamnya kita membuat perubahan berikut:
/ {
        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>;
        };
};


Parameter gpios di simpul dihitung sebagai berikut:
  • Pertama datang tautan ke label pio;
  • Berikutnya adalah nomor bank, yang berisi port GPIO yang diinginkan. Untuk Allwinner A20, setiap bank berisi 32 port, sehingga nomor bank didefinisikan sebagai bagian integer dari pembagian pin GPIO dengan 32;
  • Berikutnya adalah nomor pin di dalam bank. Karena setiap bank memiliki 32 pin, maka nilai ini dihitung sebagai sisa pembagian pin GPIO sebesar 32;
  • Parameter terakhir adalah indikasi level sinyal mana yang dianggap aktif

Parameter interupsi dalam simpul dihitung sebagai berikut:
  • Parameter pertama menunjukkan angka interupsi pengendali GPIO (untuk EINT2 itu akan menjadi 2)
  • Parameter kedua adalah IRQ_TYPE_EDGE_FALLING, yang memungkinkan pembuatan interupsi ketika sinyal beralih dari tinggi ke rendah (karena kami memiliki sensor kolektor terbuka dan ditarik ke + VCC)

Kami mengkompilasi file Device Tree yang dimodifikasi:
dtc -I dts -O dtb sun7i-a20-bananapi.dts > sun7i-a20-bananapi.dtb

Dengan hasil sun7i-a20-bananapi.dtb, kami menimpa file di /boot/dtb/sun7i-a20-bananapi.dtb Kami menulis
modul kernel counters.ko gpio-pulse.ko di mana saja di / lib / modules / $ (uname -r) / kernel / driver dan muat sistem target. Pada sistem target yang dimuat, kami memberikan perintah
depmod -a

dan reboot lagi. Setelah itu, kita melihat output dari perintah dmesg:
# dmesg
...
[    4.745570] counters: Class driver loaded.
[    4.749235] gpio_pulse: Device #0 gas-meter: IRQ: 53 GPIO: 226
...

Hebat, modul dimuat dan fungsional. Kami memeriksa fungsionalitas terlebih dahulu secara terprogram:
# 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

(kami meniru sinyal oleh perangkat lunak).

Sekarang kita menghubungkan sensor Hall dan memastikan operabilitasnya dengan membawa beberapa magnet ke sana (misalnya, dari stiker magnet di kulkas).

Kata penutup


Akhirnya, saya punya waktu untuk memposting gambar. Jadi:

Sebenarnya sensornya. Bagian sensitifnya adalah sisi tanpa bevel (yaitu, kita tekan ke meter di bawah debit paling sedikit).


Lalu kita perbaiki sensor dengan pita listrik.


Untuk kekuatan, potong sepotong busa ke meter gas untuk ukuran reses dan kemudian perbaiki sensor untuk itu.

Kemudian kita perbaiki bagian ini dan kawat dengan pita listrik.


Nah dan inilah yang terjadi sebagai akibatnya.


Untuk keputusan tentang fastener, tolong jangan menendang kakimu, karena rumah itu masih mengalami perbaikan dan perlengkapan, pada kenyataannya, adalah prototipe.

Source: https://habr.com/ru/post/id386647/


All Articles