Kami membuat pengontrol untuk rumah pintar dan tidak hanya.
Dalam artikel sebelumnya, saya menggambarkan pengembangan sistem secara keseluruhan. Dalam hal ini, saya akan menjelaskan pengembangan pengontrol yang bertanggung jawab atas sensor polling dan modul I / O. "Mengapa menemukan kembali kemudi?" - kamu bertanya. Pertama, ini menarik, dan kedua, anehnya, tidak ada solusi OpenSource untuk pengontrol yang mencakup perangkat lunak dan perangkat keras. Artikel ini ditujukan untuk orang-orang yang sedikit berpengalaman dalam elektronik dan pengembangan linux tertanam.
Membuat pengontrol, Anda katakan, sangat rumit - Anda perlu membuat papan, menulis perangkat lunak, mencetak kasing. Namun dalam kenyataannya, semuanya sedikit lebih rumit, itulah yang dituangkan untuk saya, tetapi pada prinsipnya Anda benar:
1. perangkat keras pengontrol
- Pilihan papan cpu untuk controller
- Pilihan pengontrol IO
- Pilihan catu daya
- blok diagram pengontrol
- pengembangan papan silang untuk pengontrol
- pengembangan papan untuk modul RS-485
- produksi papan
2. perangkat lunak untuk pengontrol
- Pilihan sistem bangun untuk kernel linux dan rootfs
- struktur partisi kartu SD
- pilihan bootloader dan memuat rootf yang diperlukan
- perubahan pohon perangkat
- pilihan sistem untuk mengumpulkan debet yang diperdagangkan
- menulis sistem pembangunan
- menulis inti komunikasi
- menulis gateway mqtt (poin pengontrol diskrit / analog -> topik mqtt)
- Menulis parser Google dan membangun file konfigurasi json untuk gateway
- menulis monitor titik untuk mengakses titik-titik pengontrol
- mount sistem file hanya baca
3. kasus pengontrol
- Apa yang seharusnya, konektor, pendingin, kursi untuk papan, hipotek untuk klip untuk kurung pada dinrake.
- desain dan pencetakan
Beberapa kata tentang perangkat keras.
Mungkin hanya yang paling putus asa sekarang mengambil prosesor terpisah, memori, flash, power controller, beberapa ratus komponen dan mulai memahat semuanya. Sisanya menggunakan hasil kerja orang lain, lebih cepat dan lebih mudah. Anda hanya perlu membuka browser dan menulis "komputer papan tunggal" dan menghabiskan sisa hari memilih yang tepat. Saya membutuhkan banyak port serial dan diharapkan papan mendukung -40 Β° C hingga + 85 Β° C, sehingga pilihannya jatuh pada BeagleBone Black (BBB). Juga pada BBB, semua periferal terhubung ke dua konektor PBD dari 46 pin dengan peningkatan 2,54, yang nyaman untuk pembuatan prototipe dan pengembangan papan-silang. Diperlukan papan silang untuk menggabungkan semua komponen dalam satu papan, bagi saya itu adalah papan cpu, catu daya, pengontrol IO, dan papan saluran RS485. Selain itu, papan silang inilah yang harus diperbaiki pada kasing dan ada konektor untuk daya dan kabel RS485.

Jadi, kami menemukan papan cpu, hal berikutnya yang harus diputuskan adalah apakah perlu untuk menempatkan pengontrol Input / Output (IO) pada cross-board atau tidak. Saya meletakkannya di papan tulis, dan saya belum berhasil menggunakannya. Satu-satunya hal yang dia lakukan adalah menunda dimulainya BBB untuk 1s setelah menerapkan daya dan melayani tombol reset.
Catu daya untuk controller, saya mengambil MeanWell NSD10-12S5 siap pakai, mengembangkannya untuk satu perangkat adalah usaha yang tidak berarti, saya hanya mengambilnya untuk konsumsi dan hanya itu. Jangan memperhatikan LCD, ada di papan tulis, tapi saya tidak menerapkan dukungan.


Beberapa kata tentang kartu saluran RS485.
Ada 4 antarmuka BBB serial pada papan silang. Jadi di sana Anda dapat meletakkan semua jenis saluran yang Anda butuhkan, RS485, CAN, modul Zigbee ...
Saya membutuhkan saluran RS485, jadi saya membuatnya hanya, mereka dengan kontrol transmisi / penerimaan otomatis dan dengan isolasi galvanik. Mengapa tidak menggunakan kontrol transceiver dengan BBB, karena TI secara resmi berhenti mendukung strobo untuk RS485 pada driver perangkat serial. Anda dapat menemukan tambalan untuk driver, Anda dapat menambahkannya sendiri, tetapi mengapa? Setelah membuat saluran itu sendiri, Anda dapat meletakkannya di papan mana saja, misalnya, di RaspberyPi, di mana tidak pernah ada dukungan seperti itu, jika ada, maka perbaiki saya. Strobo untuk driver rs485 dikonfigurasi pada attiny10, murah dan ceria.
Kami kembali ke perangkat lunak.
Memilih sistem build untuk kernel linux dan rootfs.
Ada beberapa sistem semacam ini, yang paling populer adalah Yocto dan BuildRoot. Jika Anda perlu mengembangkan proyek besar, jika Anda punya banyak waktu dan keinginan untuk menulis resep, maka Yocto adalah pilihan Anda. Dengan bantuan BuildRoot, Anda dapat mengumpulkan semua yang Anda butuhkan untuk peluncuran papan yang sederhana sangat, sangat sederhana, karena Saya membuat sistem di Beaglebone Black (selanjutnya BBB) kemudian:
- baca apa yang tertulis di sini habr.com/en/post/448638
- bersihkan
- buat beaglebone_defconfig
- membuat
Itu saja. Sekarang semua yang Anda butuhkan untuk menjalankan papan terletak di folder / buildroot / output / images.
Semuanya terlihat sangat sederhana dan tidak menarik, sehingga Anda bisa melakukan sedikit lebih rumit:
- mengintegrasikan buildroot ke sistem build Anda, mengunduhnya dengan skrip, ingat untuk menggunakan tag stabil, dan jangan mengambil pengembangan terakhir
- tulis defconfig Anda dan letakkan skrip di folder / buildroot / configs sebelum merakit buildroot, jangan lupa bahwa semua defconfigs harus diakhiri dengan * _defconfig, jika tidak buildroot tidak melihatnya
- salin post-build.sh Anda ke board / beaglebone / post-build.sh
- buat skrip yang akan melakukan n1, n2 dan n3 untuk Anda
Akibatnya, buildroot akan menghasilkan zImage dan rootfs.tar
Memilih struktur partisi kartu SD:
Mengenai hal ini, saya pikir, tidak perlu memusatkan banyak perhatian.
Saya membuat 4 bagian BOOT / ROOT_1 / ROOT_2 / DATA.
Bagian BOOT berisi semua yang Anda butuhkan untuk bootstrap: MLO, barebox.bin, barebox.env, am335x-boneblack.dtb, zImage, boot.txt.
ROOT_1 dan ROOT_2 berisi rootfs, pilihannya ditulis dalam file boot.txt (lihat di bawah). Semua partisi ini dipasang sebagai hanya baca untuk menghindari crash sistem file ketika daya dimatikan. DATA berisi konfigurasi desain, ketika mengubah yang tidak perlu membangun kembali kode.
Struktur partisi seperti itu di masa depan akan membuatnya mudah untuk menulis komponen pembaruan perangkat lunak. Komponen ini akan menimpa salah satu bagian ROOT_1 / ROOT_2, yang tidak digunakan sekarang, dan kemudian hanya mengubah file boot.txt jika Anda tidak perlu mengubah kernel.
Memilih bootloader.
Saya punya banyak percobaan dengan bootloader untuk BBB. Pada awalnya saya menggunakan, seperti semua orang, U-Boot yang dihasilkan BuildRoot. Tetapi saya tidak menyukainya, mungkin, tentu saja, ini masalah kebiasaan, tetapi bagi saya sepertinya terlalu banyak, sangat berat dan sulit dikonfigurasikan. Kemudian, saya berpikir bahwa tidak akan buruk untuk memulai sistem dengan cepat, dalam 2-3 detik, dan mengajukan X-Loader sehingga akan memuat kernel, saya berhasil, tetapi sekali lagi ada masalah konfigurasi, dan waktu mulai untuk saya tidak kritis (sistem pada boot sistemd dengan sendirinya dengan sendirinya, bahkan jika Anda menghapus semua yang tidak diperlukan).
Pada akhirnya, saya memilih barebox, saya sangat menyukai kesederhanaannya, plus situs tersebut memiliki semua dokumentasi (www.barebox.org).
Misalnya, untuk memuat rootfs dari partisi pertama atau kedua, Anda hanya perlu:
1. pada bagian boot, buat file boot.txt yang akan mengekspor variabel tipe βexport BOOT_NUM = Xβ
2. buat dua skrip / env / boot / sdb1 / env / boot / sdb2 untuk menjelaskan opsi-opsi boot, misalnya:
echo "botting with mmcblk0p2 as rootfs..." global.bootm.image=/boot/zImage global.bootm.oftree=/boot/am335x-boneblack.dtb global.linux.bootargs.console="console=ttyO0,115200" global.linux.bootargs.debug="earlyprintk ignore_loglevel" global.linux.bootargs.base="root=/dev/mmcblk0p2 ro rootfstype=ext4 rootwait"
3. buat skrip / env / boot / sd di mana, tergantung pada BOOT_NUM, mulai skrip sdb1 atau sdb2
4. atur variabel boot.default
nv boot.default=sd saveenv
5. Lebih lanjut mengubah BOOT_NUM di boot.txt kami akan memuat rootfs dari partisi pertama atau kedua, yang di masa depan dapat digunakan untuk pembaruan perangkat lunak.
Perubahan ke bagan perangkat.
Karena saya menggunakan MODBUS RTU via RS485 untuk berkomunikasi dengan modul, saya perlu mengaktifkan hampir semua port serial yang ada di BBB. Untuk melakukan ini, Anda harus mengaktifkannya kembali di pohon perangkat, karena Secara default, sebagian besar dimatikan.
Itu akan benar untuk membuat tambalan Anda untuk file am335x-bone-common.dtsi dari paket buildrut dan menerapkannya setiap kali sebelum merakitnya, tetapi kemalasan menang dan saya hanya mengeluarkan semua file yang saya butuhkan, mengubah semua yang saya butuhkan dan membangunnya dengan tangan saya.
Karena ini dilakukan sekali, itu mungkin dan jadi:
1. Buat folder dengan file yang diperlukan untuk perakitan:
am335x-bone-common.dtsi am335x-boneblack-common.dtsi am335x-boneblack.dts am33xx-clocks.dtsi am33xx.dtsi am33xx.h gpio.h omap.h tps65217.dtsi
2. Dalam file am335x-bone-common.dtsi, Anda harus mengonfigurasi pin dengan benar dan tidak mengaktifkan driver port:
uart1_pins: pinmux_uart1_pins { pinctrl-single,pins = < AM33XX_IOPAD(0x980, PIN_INPUT_PULLUP | MUX_MODE0) AM33XX_IOPAD(0x984, PIN_OUTPUT_PULLDOWN | MUX_MODE0) >; }; uart2_pins: pinmux_uart2_pins { pinctrl-single,pins = < AM33XX_IOPAD(0x950, PIN_INPUT_PULLUP | MUX_MODE1) AM33XX_IOPAD(0x954, PIN_OUTPUT_PULLDOWN | MUX_MODE1) >; }; uart4_pins: pinmux_uart4_pins { pinctrl-single,pins = < AM33XX_IOPAD(0x870, PIN_INPUT_PULLUP | MUX_MODE6) AM33XX_IOPAD(0x874, PIN_OUTPUT_PULLDOWN | MUX_MODE6) >; }; uart5_pins: pinmux_uart5_pins { pinctrl-single,pins = < AM33XX_IOPAD(0x8C4, PIN_INPUT_PULLUP | MUX_MODE4) AM33XX_IOPAD(0x8C0, PIN_OUTPUT_PULLDOWN | MUX_MODE4) >; }; &uart1 { pinctrl-names = "default"; pinctrl-0 = <&uart1_pins>; status = "okay"; }; &uart2 { pinctrl-names = "default"; pinctrl-0 = <&uart2_pins>; status = "okay"; }; &uart4 { pinctrl-names = "default"; pinctrl-0 = <&uart4_pins>; status = "okay"; }; &uart5 { pinctrl-names = "default"; pinctrl-0 = <&uart5_pins>; status = "okay"; };
3. Selanjutnya, sedikit keajaiban, dan file selesai am335x-boneblack.dtb terletak di direktori yang sama:
a. sudo apt-get install device-tree-compiler
b. jalankan preprocessor:
cpp -Wp,-MD,am335x-boneblack.dtb.d.pre.tmp -nostdinc -Iinclude -Isrc -Itestcase-data -undef -D__DTS__ -x assembler-with-cpp -o am335x-boneblack.dtb.dts.tmp am335x-boneblack.dts
c. jalankan kompiler itu sendiri:
dtc -O dtb -o am335x-boneblack.dtb -b 0 -i src -d am335x-boneblack.dtb.d.dtc.tmp am335x-boneblack.dtb.dts.tmp
4. am335x-boneblack.dtb harus diletakkan di partisi boot di sebelah kernel dan di skrip startup untuk barebox tambahkan baris berikut - "
global.bootm.oftree=/boot/am335x-boneblack.dtb
"
Memilih sistem untuk mengumpulkan debet yang diperdagangkan.
Seperti yang Anda ketahui, sistem tanpa bug tidak ada, serta analisis sistem multi-utas tanpa jejak. Sangat mudah jika jejak-jejak ini tidak ditampilkan hanya di konsol, tetapi dikumpulkan menggunakan sesuatu yang khusus dibuat untuk ini, sehingga akan mungkin untuk mengurutkannya berdasarkan proses, menerapkan filter, dll. Dan saya hanya tahu satu sistem bagus yang mudah dibangun di bawah host dan target. Ini adalah DLT, jika Anda belum pernah mendengar tentang ini, maka itu tidak masalah, semua kesenjangan pengetahuan dapat dengan mudah ditutupi dengan membaca
di.projects.genivi.org/wiki/display/PROJ/Diagnostic+Log+and+Trace .
Sistem ini terdiri dari dlt-daemon dan dlt-viewer. Seperti namanya, dlt-daemon berjalan pada target, dan dlt-viewer pada host. Plus untuk semua ini, ke biner Anda, dari mana kami ingin mengumpulkan jejak, Anda perlu menautkan lib lib.

Secara umum, semuanya nyaman, bagaimana mengumpulkan jejak dan menganalisisnya, saya sarankan.
Menulis sistem pembangunan.
Mengapa menulis sistem build, karena Anda dapat mengunduh semuanya dari repositori, membangunnya dengan tangan Anda, membangun berdasarkan rootfs dan cadar ini, pengontrol berfungsi. Tetapi untuk mengulangi trik semacam itu dalam sebulan akan lebih sulit, dan dalam dua - ini umumnya tidak mungkin. Sekali lagi, Anda harus mengingat apa, di mana harus meletakkan, apa yang harus dibangun dan bagaimana memulainya. Oleh karena itu, setelah menghabiskan banyak waktu pada awalnya, Anda menyimpannya nanti, plus Anda mendapatkan kesempatan untuk membangun dengan nyaman di bawah host dan target. Sistem build terdiri dari sekumpulan skrip yang pertama-tama menyiapkan host untuk build, mengunduh komponen pihak ketiga, seperti buildroot, mosquitto, DLT daemon, dari repositori mereka, membangunnya, meletakkannya di tempat mereka. Dan kemudian Anda dapat meluncurkan pembangunan proyek Anda. Jika build di bawah host tidak sulit dilakukan, maka Anda harus selalu mengutak-atik build di bawah target, dan akan lebih baik jika skrip melakukannya.
Buildroot dapat dikonfigurasi sehingga menjalankan skrip post-build setelah membentuk rootfs, yang akan terletak di buildroot / output / target. Ini memberi Anda peluang besar untuk meletakkan semua yang Anda butuhkan di sana. Dan kemudian, gambar sistem file sudah akan berisi semua yang Anda butuhkan untuk memulai sistem Anda.
Resepnya kira-kira seperti ini:
- Anda perlu menyalin binari Anda di suatu tempat di buildroot / output / target, misalnya di / opt / bin
- jika ada konfigurasi, maka lakukan hal yang sama dengannya, hanya di / opt / etc
- salin binari pihak ketiga, bagi saya itu mosquitto, daemon DLT, lib dan konfigurasi mereka
- Untuk memulai sistem itu sendiri ketika memuat controller, Anda perlu menyalin layanan systemd Anda, lebih baik untuk menggabungkannya ke target Anda dan mengaktifkannya kembali dengan membuat symlink di multi-user.
- salin fstab yang dimodifikasi (mengapa, saya akan memberi tahu Anda nanti)
Setelah itu, Anda hanya perlu membongkar buildroot / output / images / rootfs.tar ke bagian yang diinginkan dari kartu SD dan nyalakan daya.
build git repo: https://github.com/azhigaylo/build
Menulis inti komunikasi.
Konsep ini setua modbus itu sendiri.
Setiap perangkat I / O dalam jaringan modbus memiliki (16 bit) register yang tersedia untuk membaca, membaca / menulis, di mana data disimpan dan melalui mana perangkat ini dikendalikan. Controller, pada gilirannya, memiliki array diskrit (status dan nilai byte) dan titik analog (status dan nilai float), di mana ia menyimpan status semua parameter.
Jadi, tugas inti komunikasi sederhana - mengumpulkan data dari perangkat I / O menggunakan protokol modbus, memetakannya ke titik-titik pengontrol dan menyediakan akses ke titik-titik ini untuk tingkat atas. Dan jika Anda perlu mengelola sesuatu, maka semuanya ada di arah lain - perangkat logis (lebih lanjut tentang itu nanti) harus berlangganan ke titik pengontrol dan menulis ke titik ini memulai terjemahan parameter ini ke perangkat output air fisik.

Untuk menyusun data dan bekerja dengan perangkat, Anda dapat memperkenalkan konsep perangkat logis yang akan menampilkan keadaan perangkat fisik di perangkat lunak Anda.
Saya juga memutuskan untuk membagi perangkat logis menjadi dua kelompok:
- Standar (modul Aries input / output diskrit), yang jumlah modbus register dengan datanya diketahui sebelumnya, dan itu cukup hanya untuk menentukan titik-titik pengontrol tempat menyimpan data ini.
- Perangkat pengguna, bagi mereka perlu untuk secara mandiri menggambarkan pemetaan register modbus ke titik-titik pengontrol.
Dari semua hal di atas, masuk akal untuk memiliki semacam konfigurator untuk pengontrol, apakah itu hanya konfigurasi json atau alat yang ditulis sendiri yang menghasilkan konfigurasi biner, apa pun yang sesuai. Saya memiliki pilihan kedua, karena ada ide untuk menulis inti komunikasi sehingga dapat dengan mudah dijalankan tidak hanya pada papan Linux tetapi juga pada Arduin dengan FreeRtos, mengubah level PAL dalam perangkat lunak.
Di konfigurator untuk setiap perangkat, Anda perlu mengatur nomor port pengontrol rs485, alamat perangkat, dan titik pengontrol di mana status komunikasi dengan perangkat ditampilkan, plus untuk setiap perangkat standar salurannya dijelaskan, dan untuk perangkat pengguna, registernya dipetakan ke titik-titik.


File konfigurasi seperti itu, yang berisi semua data yang diperlukan pada pembangunan jaringan modbus, memungkinkan Anda untuk tidak mengubah kode sumber untuk proyek jika Anda perlu menambah / menghapus / mengubah perangkat input / output, cukup untuk mengubah parameter dalam konfigurator dan menyimpannya dalam file konfigurasi.
Pada saat startup, inti komunikasi mem-parsing konfigurasi dan membuat berdasarkan daftar perangkat logis untuk setiap port controller rs485, kemudian utas dibuat untuk setiap port dan polling siklik perangkat fisik dimulai.
core git repo: https://github.com/azhigaylo/homebrain_core
Menulis gateway mqtt.
Sebenarnya - titik pengontrol Anda, baik diskrit maupun analog, dengan antarmuka berpemilik untuk mengaksesnya, tidak terlalu menarik bagi siapa pun. Jadi hanya ada satu jalan keluar - mqtt. Saya pikir saya tidak akan melebih-lebihkan jika saya mengatakan bahwa ini adalah protokol yang paling umum untuk bertukar pesan kecil, plus itu sangat sederhana dan dapat dimengerti untuk digunakan. Jadi ketika saya perlu mengirimkan data dari controller - saya tidak berpikir panjang tentang apa yang harus digunakan.

Karena Saya memiliki banyak parameter, lalu selalu ada kebingungan dalam file konfigurasi gateway, di mana pemetaan titik-titik pengontrol ke topik mqtt gateway didaftarkan. Google membantu tabel, dan menulis parser csv dari tabel ini di file konfigurasi json untuk gateway.
gateway git repoparser git repoMonitor titik penulisan.
Terkadang sangat berguna untuk melihat apa yang terjadi dengan titik-titik pengontrol, untuk ini saya menulis sebuah aplikasi kecil yang terhubung langsung ke inti komunikasi dan membaca status titik-titik diskrit dan analog. Saya cukup akrab dengan UI, jadi saya dapat entah bagaimana membuang aplikasi ke QML, itu bekerja dengan derit, Anda dapat menghitung poinnya, Anda dapat menulisnya, tetapi saya tidak membutuhkan lebih banyak.
pointmonitor git repo: https://github.com/azhigaylo/pointmonitor
Pasang sistem file hanya baca.
Biasanya, beberapa orang memperhatikan ini, dan bahkan dalam proyek produksi, Anda dapat menemukan perangkat di mana partisi dengan rootfs dapat ditulis. Cepat atau lambat ini menyebabkan crash pada semua, bahkan sistem file yang paling stabil. Karena Karena pengontrol dapat dimatikan kapan saja, itu hanya masalah waktu / kasus ketika ini terjadi. Untuk meminimalkan probabilitas ini, Anda perlu sedikit mengotak-atik fstab, dan sebelum membangun gambar rootfs, letakkan di sana, seperti dijelaskan di atas. Di fstab, pertama, Anda perlu me-mount sistem file sebagai hanya baca, dan kedua, semua yang dapat diubah dapat dipetakan ke tmpfs.
Fstab saya adalah ini, mungkin berbeda untuk Anda:
/dev/root / auto ro 0 1 tmpfs /tmp tmpfs nodev,nosuid,size=50M 0 0 tmpfs /srv tmpfs nodev,size=50M 0 0 tmpfs /var/log tmpfs defaults,noatime,size=50M 0 0 tmpfs /var/tmp tmpfs defaults,noatime,size=50M 0 0 tmpfs /var/run tmpfs defaults,noatime,size=50M 0 0 tmpfs /var/lib tmpfs defaults,noatime,size=10M 0 0
Badan pengontrol
Sebuah printer 3D telah lama dimasukkan dalam bagian masthead untuk setiap insinyur petani kolektif, sayangnya saya tidak memilikinya, tetapi sedang bekerja. Baru-baru ini, kegembiraan karyawan lain untuknya telah hilang, saya menggunakan ini ketika mencetak semua yang saya butuhkan dan tidak perlu, Anda bisa diyakinkan dengan membaca posting saya sebelumnya.
Kami menggambar di FreeCAD, kami menghasilkan gcode di Cura dan kami mendapatkan kasing, tanpa lupa membuat kursi untuk papan, guntingan untuk konektor dan pendingin dan hipotek untuk klip pada rel din.


Nah, itu saja, sekarang kami memiliki papan, perangkat lunak pada kartu SD dan kasing. Kami mengambil file (saya tidak bercanda) dan menghubungkan semuanya bersama-sama, menghubungkan daya, kabel RS485 dan semuanya mulai berfungsi. Dan Anda berkata sulit, sulit ...