Isi kandungan:

Melangkaui StandardFirmata - Dilayari: 5 Langkah
Melangkaui StandardFirmata - Dilayari: 5 Langkah

Video: Melangkaui StandardFirmata - Dilayari: 5 Langkah

Video: Melangkaui StandardFirmata - Dilayari: 5 Langkah
Video: Crypto Pirates Daily News - January 20th, 2022 - Latest Crypto News Update 2024, Julai
Anonim
Melangkaui StandardFirmata - Dilayari
Melangkaui StandardFirmata - Dilayari

Beberapa ketika yang lalu, saya dihubungi oleh Dr. Martyn Wheeler, pengguna pymata4, untuk panduan dalam menambahkan sokongan untuk sensor Kelembapan / Suhu DHT22 ke perpustakaan pymata4. Perpustakaan pymata4, bersama dengan rakan sejawat Arduino, FirmataExpress, memungkinkan pengguna untuk mengawal dan memantau peranti Arduino mereka dari jauh. Dalam beberapa pusingan pertukaran e-mel, Dr. Wheeler berjaya mengubah kedua pymata4 dan FirmataExpress. Hasilnya, sokongan untuk sensor DHT22 dan DHT11 kini menjadi bahagian standard pymata4 dan FirmataExpress.

Pada bulan Mei 2014, saya menulis artikel mengenai penambahan sokongan kepada Firmata untuk peranti tambahan. Mengingat artikel saya itu, saya menyedari berapa banyak yang telah berubah sejak saya mengambil kertas untuk artikel itu. Sebagai tambahan kepada artikel ini, Dr. Wheeler mendokumentasikan usahanya, dan anda mungkin ingin memeriksanya juga.

FirmataExpress didasarkan pada StandardFirmata, dan struktur direktori StandardFirmata telah berkembang. Selain itu, API pymata4 juga sedikit berbeza dengan API PyMata yang asli pada tahun 2014. Saya fikir ini adalah masa yang tepat untuk melihat semula dan mengemas kini artikel itu. Dengan menggunakan karya Dr. Wheeler sebagai asas, mari kita meneroka cara memperluas fungsi pymata4 / FirmataExpress.

Sebelum Kita Bermula - Beberapa Maklumat Latar Belakang Mengenai Arduino / Firmata

Jadi apa itu Firmata? Memetik dari laman web Firmata, "Firmata adalah protokol generik untuk berkomunikasi dengan mikrokontroler dari perisian pada komputer host."

Arduino Firmata menggunakan antara muka bersiri untuk mengangkut maklumat arahan dan laporan antara mikrokontroler Arduino dan PC, biasanya menggunakan pautan bersiri / USB yang ditetapkan ke 57600 bps. Data yang dipindahkan melalui pautan ini bersifat binari, dan protokol dilaksanakan dalam model pelanggan / pelayan.

Bahagian pelayan dimuat naik ke mikrokontroler Arduino dalam bentuk lakaran Arduino. Sketsa StandardFirmata, disertakan dengan Arduino IDE, mengendalikan pin Arduino I / O, seperti yang diperintahkan oleh klien. Ia juga melaporkan perubahan pin input dan maklumat laporan lain kembali kepada pelanggan. FirmataExpress adalah versi lanjutan dari StandardFirmata. Ia berjalan pada kelajuan pautan bersiri 115200 bps.

Pelanggan Arduino yang digunakan untuk artikel ini adalah pymata4. Ini adalah aplikasi Python yang dijalankan pada PC. Keduanya menghantar perintah ke dan menerima laporan dari pelayan Arduino. Kerana pymata4 dilaksanakan di Python, ia berjalan di komputer Windows, Linux (termasuk Raspberry Pi), dan macOS.

Mengapa Menggunakan Firmata?

Mikrokontroler Arduino adalah peranti kecil yang indah, tetapi sumber pemproses dan memori agak terhad. Untuk aplikasi yang memerlukan pemprosesan atau memori, seringkali ada sedikit pilihan selain memunggah permintaan sumber daya ke PC agar aplikasi berjaya.

Tetapi itu bukan satu-satunya alasan untuk menggunakan StandardFirmata. Semasa mengembangkan aplikasi Arduino yang lebih ringan, PC dapat menyediakan alat dan kemampuan debug yang tidak tersedia langsung pada mikrokontroler Arduino. Menggunakan pelanggan dan pelayan "tetap" membantu membatasi kerumitan aplikasi ke PC, yang lebih mudah diuruskan. Setelah aplikasi disempurnakan, aplikasi dapat diterjemahkan ke dalam sketsa Arduino yang tersendiri.

Mengapa Menggunakan pymata4?

Sebagai pengarangnya, tentunya saya berat sebelah. Yang dikatakan, ia adalah satu-satunya pelanggan Firmata yang berpusat di Python yang terus dikekalkan selama beberapa tahun terakhir. Ia menyediakan API yang intuitif dan mudah digunakan. Selain lakaran berdasarkan StandardFirmata, Ia menyokong Firmata melalui WiFi untuk peranti seperti ESP-8266 ketika menggunakan lakaran StandardFirmataWifI.

Juga, pymata4 dirancang untuk diperluas dengan mudah oleh pengguna untuk menyokong sensor dan penggerak tambahan yang saat ini tidak disokong oleh StandardFirmata.

Langkah 1: Memahami Protokol Firmata

Memahami Protokol Firmata
Memahami Protokol Firmata

Protokol komunikasi Arduino Firmata berasal dari protokol MIDI, yang menggunakan satu atau lebih bait 7-bit untuk mewakili data.

Firmata dirancang agar dapat diperluas oleh pengguna. Mekanisme yang memberikan kepanjangan ini adalah protokol pesanan Sistem Eksklusif (SysEx).

Format mesej SysEx, seperti yang ditentukan oleh Protokol Firmata, ditunjukkan dalam ilustrasi di atas. Ia dimulakan dengan bait START_SYSEX dengan nilai tetap heksadesimal 0xF0, dan diikuti oleh bait perintah SysEx yang unik. Nilai bait arahan mestilah dalam lingkungan heksadesimal 0x00-0x7F. Bait arahan kemudian diikuti oleh bilangan bait data 7-bit yang tidak ditentukan. Akhirnya, mesej ditamatkan dengan bait END_SYSEX, dengan nilai tetap 0xF7 heksadesimal.

Pengekodan / Penyahkodan Data Firmata

Oleh kerana bahagian data pengguna mesej SysEx terdiri daripada satu siri byte 7-bit, anda mungkin tertanya-tanya bagaimana seseorang mewakili nilai yang lebih besar daripada 128 (0x7f)? Firmata mengekodkan nilai-nilai tersebut dengan membongkarnya menjadi beberapa potongan bait 7-bit sebelum data dikumpulkan di pautan data. Byte paling rendah (LSB) item data dihantar terlebih dahulu, diikuti oleh komponen item data yang semakin ketara secara konvensional. Bait yang paling ketara (MSB) item data adalah item data terakhir yang dihantar.

Bagaimana ianya berfungsi?

Katakanlah kami ingin memasukkan nilai 525 ke dalam bahagian data mesej SysEx. Oleh kerana nilai 525 jelas lebih besar daripada nilai 128, kita perlu membelah atau membongkarnya menjadi "potongan" bait 7-bit.

Inilah cara ia dilakukan.

Nilai 525 dalam perpuluhan bersamaan dengan nilai perenambelasan 0x20D, nilai 2-bait. Untuk mendapatkan LSB, kami menutup nilai dengan AND dengan 0x7F. Kedua-dua pelaksanaan "C" dan Python ditunjukkan di bawah:

// "C" pelaksanaan untuk mengasingkan LSB

int max_distance_LSB = max_distance & 0x7f; // sembunyikan byte yang lebih rendah # pelaksanaan Python untuk mengasingkan LSB max_distance_LSB = max_distance & 0x7F # mask topeng yang lebih rendah

Setelah menutup, max_distance_LSB akan mengandungi 0x0d. 0x20D & 0x7F = 0x0D.

Seterusnya, kita perlu mengasingkan MSB untuk nilai 2-bait ini. Untuk melakukan ini, kita akan mengalihkan nilai 0x20D ke kanan, 7 tempat.

// "C" pelaksanaan untuk mengasingkan nilai MSB 2 bait

int max_distance_MSB = max_distance >> 7; // ubah byte pesanan tinggi # Pelaksanaan Python untuk mengisolasi MSB 2 nilai byte max_distance_MSB = max_distance >> 7 # shift untuk mendapatkan bait atas Setelah beralih, max_distance_MSB akan mengandungi nilai 0x04.

Apabila data marshaled "chunkified" diterima, data tersebut harus dipasang kembali menjadi satu nilai. Berikut adalah bagaimana data dikumpulkan semula dalam "C" dan Python

// "C" pelaksanaan untuk memasang kembali 2 bait, // Nilai 7 bit menjadi nilai tunggal int max_distance = argv [0] + (argv [1] << 7); # Pelaksanaan Python untuk memasang kembali nilai 2 bait, # 7 bit menjadi nilai tunggal max_distance = data [0] + (data [1] << 7)

Selepas pemasangan semula, nilainya sekali lagi sama dengan 525 perpuluhan atau 0x20D heksadesimal.

Proses pembongkaran / pemasangan semula ini mungkin dilakukan oleh pelanggan atau pelayan.

Langkah 2: Mari Bermula

Menyokong peranti baru memerlukan perubahan pada pelayan penduduk Arduino dan pelanggan Python yang tinggal di PC. Kerja Dr. Wheeler akan digunakan untuk menggambarkan pengubahsuaian yang diperlukan.

Mungkin langkah yang paling penting adalah untuk memutuskan sama ada anda ingin mengintegrasikan perpustakaan peranti sokongan yang ada ke bahagian persamaan Arduino atau menulis sendiri. Sebaiknya jika anda dapat mencari perpustakaan yang ada, jauh lebih mudah menggunakannya daripada menulis sendiri dari awal.

Untuk sokongan peranti DHT, Dr. Wheeler berdasarkan kod pelanjutannya di perpustakaan DHTNew. Dengan sangat cerdik, Dr. Wheeler membahagikan fungsi perpustakaan DHTNew di seberang Arduino dan pymata4 pada persamaan untuk memberikan sekatan minimum di sisi Arduino.

Sekiranya kita melihat DHTNew, ia melakukan semua perkara berikut:

  • Menetapkan mod output digital pin yang dipilih.
  • Menyalakan isyarat yang dikodkan untuk mendapatkan semula nilai kelembapan dan suhu terkini.
  • Memeriksa dan melaporkan sebarang kesalahan.
  • Mengira nilai suhu dan kelembapan yang dapat dibaca manusia dari data mentah yang diambil.

Untuk memastikan keadaan seefisien mungkin di pihak FirmataExpress, Dr. Wheeler menurunkan rutin penukaran data dari Arduino ke pymata4.

Langkah 3: Mengubah FirmataExpress untuk Sokongan DHT

Pokok Direktori FirmataExpress

Berikut adalah semua fail yang terdiri dari repositori FirmataExpress. Pokok ini sama dengan StandardFiramata, hanya sebilangan nama fail yang menunjukkan nama repositori.

Fail yang memerlukan pengubahsuaian adalah fail yang mempunyai tanda bintang (*) di sebelahnya.

FirmataExpress

├── * Papan.h

├── contoh

Irm └── FirmataExpress

├── ├── boardx

│ ├── * FirmataExpress.ino

IC IC LESEN.txt

F └── Makefile

├── * FirmataConstants.h

├── * FirmataDefines.h

├── FirmataExpress.cpp

├── FirmataExpress.h

├── FirmataMarshaller.cpp

├── FirmataMarshaller.h

├── FirmataParser.cpp

└── FirmataParser.h

Mari lihat setiap fail dan perubahan yang dibuat.

Papan.h

Fail ini mengandungi definisi makro jenis pin untuk setiap jenis papan yang disokong. Ini menentukan jumlah maksimum peranti yang disokong apabila lebih daripada satu peranti perlu disokong.

Untuk peranti DHT, sehingga 6 peranti dapat disambungkan sekaligus dan nilai ini ditakrifkan sebagai:

#ifndef MAX_DHTS

#tentukan MAX_DHTS 6 #endif

Juga, makro jenis pin boleh ditentukan secara pilihan untuk peranti baru, sama ada untuk semua jenis papan atau hanya yang menarik bagi anda. Makro ini kebanyakan digunakan untuk tujuan pelaporan dan tidak digunakan untuk mengawal peranti. Makro ini menentukan kedua-dua pin yang menyokong peranti:

#tentukan IS_PIN_DHT (p) (IS_PIN_DIGITAL (p) && (p) - 2 <MAX_DHTS)

Serta makro untuk menentukan penukaran nombor pin.

#tentukan PIN_TO_DHT (p) PIN_TO_DIGITAL (p)

FirmataConstants.h

Fail ini mengandungi nombor versi firmware, yang mungkin ingin anda ubah untuk mengikuti versi mana yang telah anda muatkan ke Arduino anda. Ini juga berisi nilai-nilai pesan Firmata, termasuk pesan Firmata SysEx.

Anda perlu memberikan mesej baru atau sekumpulan mesej untuk peranti anda dalam fail ini. Untuk DHT, dua mesej ditambahkan. Satu mengkonfigurasi pin sebagai pin "DHT", dan yang lain, sebagai pesan wartawan, ketika mengirim data DHT terbaru kembali kepada klien.

statik const int DHT_CONFIG = 0x64;

statik const int DHT_DATA = 0x65;

Mod pin juga ditentukan dalam fail ini. Untuk DHT, mod pin baru dibuat:

stat stat const int PIN_MODE_DHT = 0x0F; // pin dikonfigurasikan untuk DHT

Semasa menambahkan mod pin baru, TOTAL_PIN_MODES mesti disesuaikan:

stat stat kon TOTAL_PIN_MODES = 17;

FirmataDefines.h

Fail ini mesti dikemas kini untuk menggambarkan mesej baru yang ditambahkan ke FirmataConstants.h:

#ifdef DHT_CONFIG # undef DHT_CONFIG #endif #define DHT_CONFIG firmata:: DHT_CONFIG // Permintaan DHT #ifdef DHT_DATA #undef DHT_DATA #endif #define DHT_DATA firmata:: DHT_DATA // DHT balas #fdFD:: PIN_MODE_DHT

FirmataExpress.ino

Dalam perbincangan ini, kita akan membahas "titik tinggi" dari perubahan yang dibuat pada lakaran Arduino ini.

Agar FirmataExpress dapat menyokong hingga enam peranti DHT secara serentak, 3 tatasusunan dibuat untuk melacak setiap pin nombor peranti, nilai WakeUpDelay, dan jenis peranti, yaitu DHT22 atau DHT11:

// Sensor DHT

int numActiveDHTs = 0; // bilangan DHT yang dilampirkan uint8_t DHT_PinNumbers [MAX_DHTS]; uint8_t DHT_WakeUpDelay [MAX_DHTS]; uint8_t DHT_TYPE [MAX_DHTS];

Kerana kedua-dua jenis peranti memerlukan kira-kira 2 saat antara pembacaan, kita perlu memastikan bahawa kita membaca setiap DHT hanya sekali dalam jangka masa 2 saat. Beberapa peranti, seperti peranti DHT dan sensor jarak HC-SR04, hanya diakses secara berkala. Ini memberi mereka masa untuk berinteraksi dengan persekitaran mereka.

uint8_t seterusnyaDHT = 0; // indeks ke dht agar peranti seterusnya dapat dibaca

uint8_t semasaDHT = 0; // Menjejaki sensor mana yang aktif. int dhtNumLoops = 0; // Sasaran berkali-kali melalui gelung b4 mengakses DHT int dhtLoopCounter = 0; // Kaunter gelung

Mengkonfigurasi Dan Membaca Peranti DHT

Apabila FirmataExpress menerima perintah SysEx untuk mengkonfigurasi pin untuk operasi DHT, ini mengesahkan bahawa jumlah maksimum peranti DHT belum terlampaui. Sekiranya DHT baru dapat disokong, susunan DHT dikemas kini. Sekiranya jenis DHT tidak diketahui, mesej rentetan SysEx dibuat dan dihantar kembali ke pymata4

kes DHT_CONFIG: int DHT_Pin = argv [0]; int DHT_type = argv [1]; if (numActiveDHTs <MAX_DHTS) {if (DHT_type == 22) {DHT_WakeUpDelay [numActiveDHTs] = 1; } lain jika (DHT_type == 11) {DHT_WakeUpDelay [numActiveDHTs] = 18; } lain {Firmata.sendString ("KESALAHAN: JENIS SENSOR YANG TIDAK DIKETAHUI, SENSOR YANG SAH 11, 22"); rehat; } // uji sensor DHT_PinNumbers [numActiveDHTs] = DHT_Pin; DHT_TYPE [numActiveDHTs] = Jenis DHT; setPinModeCallback (DHT_Pin, PIN_MODE_DHT);

FirmataExpress kemudian berusaha untuk berkomunikasi dengan peranti DHT. Sekiranya terdapat kesilapan, ia akan membentuk mesej SysEx dengan data ralat dan menghantar kembali mesej SysEx ke pymat4. Pemboleh ubah _bits menyimpan data yang dikembalikan oleh peranti DHT untuk pemprosesan tambahan oleh pymata4 jika dikehendaki.

Firmata.write (START_SYSEX);

Firmata.write (DHT_DATA); Firmata.write (DHT_Pin); Firmata.write (DHT_type); untuk (uint8_t i = 0; i> 7 & 0x7f); } Firmata.write (abs (rv)); Firmata.write (1); Firmata.write (END_SYSEX);

Sekiranya data yang sah dikembalikan, jumlah DHT aktif akan bertambah. Pemboleh ubah yang mengawasi berapa banyak lelaran gelung untuk diselesaikan sebelum memeriksa DHT berikutnya untuk data juga disesuaikan. Pemboleh ubah ini memastikan bahawa tidak kira berapa banyak DHT yang ditambahkan ke sistem, semuanya akan dibaca dalam jangka masa 2 saat.

int rv = readDhtSensor (numActiveDHTs);

jika (rv == DHTLIB_OK) {numActiveDHTs ++; dhtNumLoops = dhtNumLoops / numActiveDHTs; // semua baik-baik saja}

Sekiranya satu atau lebih peranti DHT telah dikonfigurasi dalam fungsi gelung lakaran, maka peranti DHT seterusnya dibaca. Sama ada data yang sah atau status kesalahannya dikembalikan ke pymata4 dalam bentuk mesej SysEx:

if (dhtLoopCounter ++> dhtNumLoops) {if (numActiveDHTs) {int rv = readDhtSensor (nextDHT); uint8_t current_pin = DHT_PinNumbers [nextDHT]; uint8_t current_type = DHT_TYPE [nextDHT]; dhtLoopCounter = 0; currentDHT = nextDHT; jika (nextDHT ++> = numActiveDHTs - 1) {nextDHT = 0; } if (rv == DHTLIB_OK) {// CHECKSUM UJIAN uint8_t jumlah = _bits [0] + _bits [1] + _bits [2] + _bits [3]; jika (_bits [4]! = jumlah) {rv = -1; }} // hantar semula mesej dengan status ralat Firmata.write (START_SYSEX); Firmata.write (DHT_DATA); Firmata.write (current_pin); Firmata.write (current_type); untuk (uint8_t i = 0; i <sizeof (_bits) - 1; ++ i) {Firmata.write (_bits ); // Firmata.write (_bits ;} Firmata.write (abs (rv)); Firmata.write (0); Firmata.write (END_SYSEX);}}

Kod yang digunakan untuk berkomunikasi dengan peranti DHT diambil secara langsung dari perpustakaan DHTNew:

int readDhtSensor (indeks int) {

// INIT BUFFERVAR UNTUK MENERIMA DATA uint8_t mask = 128; uint8_t idx = 0; // KOSONG BUFFER // memset (_bits, 0, sizeof (_bits)); untuk (uint8_t i = 0; i 5 BYTES untuk (uint8_t i = 40; i! = 0; i--) {loopCnt = DHTLIB_TIMEOUT; while (digitalRead (pin) == RENDAH) {jika (--loopCnt == 0) kembalikan DHTLIB_ERROR_TIMEOUT;} uint32_t t = mikros (); loopCnt = DHTLIB_TIMEOUT; manakala (digitalRead (pin) == TINGGI) {jika (--loopCnt == 0) kembalikan DHTLIB_ERROR_TIMEOUT;} jika ((mikro () - t)> 40) {_bits [idx] | = mask;} mask >> = 1; if (mask == 0) // byte seterusnya? {Mask = 128; idx ++;}} pulangkan DHTLIB_OK;}

Langkah 4: Mengubah Pymata4 untuk Sokongan DHT

private_constants.h

Untuk menyokong DHT, kita perlu menambahkan kedua-dua jenis pin dan SysEx pada fail ini:

# mod pin INPUT = 0x00 # pin ditetapkan sebagai input OUTPUT = 0x01 # pin ditetapkan sebagai output ANALOG = 0x02 # pin analog dalam analog Mod input PWM = 0x03 # pin digital dalam mod output PWM SERVO = 0x04 # pin digital dalam mod output Servo I2C = 0x06 # pin termasuk dalam persediaan I2C STEPPER = 0x08 # pin apa pun dalam mod stepper SERIAL = 0x0a PULLUP = 0x0b # Mana-mana pin dalam mod penarikan SONAR = 0x0c # Sebarang pin dalam mod SONAR TONE = 0x0d # Sebarang pin dalam mod nada PIXY = 0x0e # dikhaskan untuk mod kamera pixy DHT = 0x0f # Sensor DHT IGNORE = 0x7f # Mesej arahan DHT SysEx DHT_CONFIG = 0x64 # dht config perintah DHT_DATA = 0x65 # dht balasan sensor

Jenis pin yang ditambahkan dan perintah SysEx mesti sepadan dengan nilai dalam FirmataConstants.h yang ditambahkan ke FirmataExpress.

pymata4.py

Pymata4 menggunakan kamus Python untuk mengaitkan mesej Firmata yang masuk dengan pengendali mesej dengan cepat. Nama kamus ini adalah report_dispatch.

Format entri kamus adalah:

{MessageID: [message_handler, bilangan bait data yang akan diproses]}

Entri ditambahkan ke kamus untuk menangani mesej DHT yang masuk:

{PrivateConstants. DHT_DATA: [self._dht_read_response, 7]}

7 bait data dalam mesej adalah nombor pin digital Arduino, jenis peranti DHT (22 atau 11), dan 5 bait data mentah.

Kaedah _dht_read_response memeriksa sebarang kesilapan yang dilaporkan. Sekiranya tidak ada kesilapan yang dilaporkan, kelembapan dan suhu dikira menggunakan algoritma yang dipindahkan dari perpustakaan Arduino DHTNew.

Nilai yang dikira dilaporkan melalui kaedah panggilan balik yang disediakan pengguna. Mereka juga disimpan dalam struktur data pin_data dalaman. Nilai terakhir yang dilaporkan mungkin dipanggil semula dengan pin_data pengundian menggunakan kaedah dht_read.

Mengkonfigurasi Peranti DHT Baru

Semasa menambahkan peranti DHT baru, kaedah set_pin_mode_dht dipanggil. Kaedah ini mengemas kini pin_data untuk pin digital. Ia juga membuat dan menghantar mesej DHT_CONFIG SysEx ke FirmataExpress.

Langkah 5: Mengemas

Seperti yang telah kita lihat, menambahkan sokongan Firmata untuk peranti baru memerlukan anda mengubah kod pelayan Arduino FirmataExpress dan kod klien pymata4 berasaskan Python. Kod FirmataExpress boleh menjadi sukar untuk di-debug. Kaedah yang disebut printData ditambahkan ke FirmataExpress untuk membantu debugging. Kaedah ini membolehkan anda menghantar nilai data dari FirmataExpress dan akan mencetaknya di konsol pymata4.

Fungsi ini memerlukan penunjuk ke rentetan watak dan nilai yang ingin anda lihat. Sekiranya nilai data terkandung dalam pemboleh ubah yang disebut argc, Anda mungkin memanggil printData dengan parameter berikut.

printData ((char *) "argc =", argc);

Sekiranya anda mempunyai sebarang pertanyaan, tinggalkan komen, dan dengan senang hati saya akan menjawabnya.

Selamat pengekodan!

Disyorkan: