Daftar Isi:

Melampaui StandarFirmata - Ditinjau Kembali: 5 Langkah
Melampaui StandarFirmata - Ditinjau Kembali: 5 Langkah

Video: Melampaui StandarFirmata - Ditinjau Kembali: 5 Langkah

Video: Melampaui StandarFirmata - Ditinjau Kembali: 5 Langkah
Video: Tugas saya adalah mengamati hutan dan sesuatu yang aneh terjadi di sini. 2024, Juli
Anonim
Melampaui StandarFirmata - Ditinjau Kembali
Melampaui StandarFirmata - Ditinjau Kembali

Beberapa waktu yang lalu, saya dihubungi oleh Dr. Martyn Wheeler, pengguna pymata4, untuk panduan dalam menambahkan dukungan untuk sensor Kelembaban/Suhu DHT22 ke perpustakaan pymata4. Pustaka pymata4, bersama dengan mitra Arduino-nya, FirmaExpress, memungkinkan pengguna untuk mengontrol dan memantau perangkat Arduino mereka dari jarak jauh. Dalam beberapa putaran pertukaran email, Dr. Wheeler berhasil memodifikasi pymata4 dan FirmaExpress. Akibatnya, dukungan untuk sensor DHT22 dan DHT11 kini menjadi bagian standar dari pymata4 dan FirmaExpress.

Pada bulan Mei 2014, saya menulis artikel tentang menambahkan dukungan ke Firma untuk perangkat tambahan. Berkaca pada artikel saya itu, saya menyadari betapa banyak yang telah berubah sejak saya mengambil pena ke kertas untuk artikel itu. Selain artikel ini, Dr. Wheeler mendokumentasikan usahanya, dan Anda mungkin ingin memeriksanya juga.

FirmaExpress didasarkan pada StandardFirmata, dan struktur direktori StandardFirmata telah berkembang. Selain itu, pymata4 API juga sedikit berbeda dari PyMata API asli tahun 2014. Saya pikir ini akan menjadi waktu yang tepat untuk mengunjungi kembali dan memperbarui artikel itu. Menggunakan karya Dr. Wheeler sebagai dasar, mari jelajahi cara memperluas fungsionalitas pymata4/FirmataExpress.

Sebelum Kita Mulai - Beberapa Informasi Latar Belakang Tentang Arduino/Firmata

Jadi apa itu Firma? Mengutip dari halaman web Firma, "Firmata adalah protokol generik untuk berkomunikasi dengan mikrokontroler dari perangkat lunak pada komputer host."

Arduino Firmata menggunakan antarmuka serial untuk mengangkut perintah dan informasi laporan antara mikrokontroler Arduino dan PC, biasanya menggunakan tautan serial/USB yang diatur ke 57600 bps. Data yang ditransfer melalui tautan ini adalah biner, dan protokol diimplementasikan dalam model klien/server.

Sisi server diunggah ke mikrokontroler Arduino dalam bentuk sketsa Arduino. Sketsa StandardFirmata, disertakan dengan Arduino IDE, mengontrol pin Arduino I/O, seperti yang diperintahkan oleh klien. Itu juga melaporkan perubahan pin input dan informasi laporan lainnya kembali ke klien. FirmaExpress adalah versi lanjutan dari StandardFirmata. Ini berjalan pada kecepatan tautan serial 115200 bps.

Klien Arduino yang digunakan untuk artikel ini adalah pymata4. Ini adalah aplikasi Python yang dijalankan di PC. Keduanya mengirim perintah ke dan menerima laporan dari server Arduino. Karena pymata4 diimplementasikan dengan Python, ia berjalan di komputer Windows, Linux (termasuk Raspberry Pi), dan macOS.

Mengapa Menggunakan Firma?

Mikrokontroler Arduino adalah perangkat kecil yang luar biasa, tetapi sumber daya prosesor dan memori agak terbatas. Untuk aplikasi yang membutuhkan prosesor atau memori yang intensif, seringkali hanya ada sedikit pilihan selain menurunkan permintaan sumber daya ke PC agar aplikasi berhasil.

Tapi itu bukan satu-satunya alasan untuk menggunakan StandardFirmata. Saat mengembangkan aplikasi Arduino yang lebih ringan, PC dapat menyediakan alat dan kemampuan debugging yang tidak tersedia secara langsung pada mikrokontroler Arduino. Menggunakan klien dan server "tetap" membantu membatasi kompleksitas aplikasi ke PC, yang lebih mudah dikelola. Setelah aplikasi disempurnakan, itu dapat diterjemahkan ke dalam sketsa Arduino yang berdiri sendiri dan khusus.

Mengapa Menggunakan pymata4?

Menjadi penulisnya, tentu saja, saya bias. Dikatakan demikian, ini adalah satu-satunya klien Firmata berbasis Python yang terus dipertahankan selama beberapa tahun terakhir. Ini menyediakan API yang intuitif dan mudah digunakan. Selain sketsa berbasis StandardFirmata, Ini mendukung Firmata melalui WiFi untuk perangkat seperti ESP-8266 saat menggunakan sketsa StandardFirmataWifI.

Selain itu, pymata4 dirancang agar mudah diperluas oleh pengguna untuk mendukung sensor dan aktuator tambahan yang saat ini tidak didukung oleh StandardFirmata.

Langkah 1: Memahami Protokol Firma

Memahami Protokol Firma
Memahami Protokol Firma

Protokol komunikasi Arduino Firmata diturunkan dari protokol MIDI, yang menggunakan satu atau lebih byte 7-bit untuk merepresentasikan data.

Firmata dirancang agar dapat diperluas oleh pengguna. Mekanisme yang menyediakan ekstensibilitas ini adalah protokol pesan System Exclusive (SysEx).

Format pesan SysEx, sebagaimana didefinisikan oleh Protokol Firma, ditunjukkan pada ilustrasi di atas. Ini dimulai dengan byte START_SYSEX dengan nilai tetap 0xF0, heksadesimal, dan diikuti oleh byte perintah SysEx yang unik. Nilai byte perintah harus dalam kisaran heksadesimal 0x00-0x7F. Byte perintah kemudian diikuti oleh sejumlah byte data 7-bit yang tidak ditentukan. Terakhir, pesan diakhiri dengan byte END_SYSEX, dengan nilai tetap 0xF7 heksadesimal.

Encoding/Decoding Data Firma

Karena bagian data pengguna dari pesan SysEx terdiri dari serangkaian byte 7-bit, Anda mungkin bertanya-tanya bagaimana seseorang mewakili nilai yang lebih besar dari 128 (0x7f)? Firmata mengkodekan nilai-nilai tersebut dengan membongkarnya menjadi beberapa potongan byte 7-bit sebelum data disusun di seluruh tautan data. Byte paling signifikan (LSB) dari item data dikirim terlebih dahulu, diikuti oleh komponen item data yang semakin signifikan menurut konvensi. Byte paling signifikan (MSB) dari item data adalah item data terakhir yang dikirim.

Bagaimana Ini Bekerja?

Katakanlah kita ingin memasukkan nilai 525 ke dalam bagian data dari pesan SysEx. Karena nilai 525 jelas lebih besar dari nilai 128, kita perlu membagi atau membongkarnya menjadi "potongan" byte 7-bit.

Inilah cara yang dilakukan.

Nilai 525 dalam desimal setara dengan nilai heksadesimal 0x20D, nilai 2 byte. Untuk mendapatkan LSB, kita menutupi nilainya dengan AND'ing dengan 0x7F. Baik implementasi "C" dan Python ditunjukkan di bawah ini:

// Implementasi "C" untuk mengisolasi LSB

int max_distance_LSB = max_distance & 0x7f; // menutupi byte yang lebih rendah # Implementasi Python untuk mengisolasi LSB max_distance_LSB = max_distance & 0x7F # menutupi byte yang lebih rendah

Setelah masking, max_distance_LSB akan berisi 0x0d. 0x20D & 0x7F = 0x0D.

Selanjutnya, kita perlu mengisolasi MSB untuk nilai 2-byte ini. Untuk melakukan ini, kita akan menggeser nilai 0x20D ke kanan, 7 tempat.

// Implementasi "C" untuk mengisolasi MSB dari nilai 2 byte

int max_distance_MSB = max_distance >> 7; // menggeser byte urutan tinggi # Implementasi Python untuk mengisolasi MSB dari nilai 2 byte max_distance_MSB = max_distance >> 7 # shift untuk mendapatkan byte atas Setelah digeser, max_distance_MSB akan berisi nilai 0x04.

Ketika data marshaled "terpotong" diterima, itu perlu dipasang kembali menjadi satu nilai. Inilah cara data dipasang kembali di "C" dan Python

// implementasi "C" untuk merakit kembali 2 byte, // nilai 7 bit menjadi satu nilai int max_distance = argv[0] + (argv[1] << 7); # Implementasi Python untuk merakit kembali nilai 2 byte, # 7 bit menjadi nilai tunggal max_distance = data[0] + (data[1] << 7)

Setelah dipasang kembali, nilainya sekali lagi sama dengan 525 desimal atau heksadesimal 0x20D.

Proses pembongkaran/pemasangan ulang ini dapat dilakukan oleh klien atau server.

Langkah 2: Mari Mulai

Mendukung perangkat baru memerlukan perubahan pada server residen Arduino dan klien Python residen PC. Karya Dr. Wheeler akan digunakan untuk mengilustrasikan modifikasi yang diperlukan.

Mungkin langkah yang paling penting adalah memutuskan apakah Anda ingin mengintegrasikan perpustakaan perangkat pendukung yang ada ke dalam persamaan sisi Arduino atau menulis milik Anda sendiri. Disarankan bahwa jika Anda dapat menemukan perpustakaan yang ada, jauh lebih mudah untuk menggunakannya daripada menulis sendiri dari awal.

Untuk dukungan perangkat DHT, Dr. Wheeler mendasarkan kode ekstensinya pada perpustakaan DHTNew. Dengan sangat cerdik, Dr. Wheeler membagi fungsionalitas perpustakaan DHTNew di sisi Arduino dan pymata4 persamaan untuk memberikan pemblokiran minimal di sisi Arduino.

Jika kita melihat DHTNew, ia melakukan semua hal berikut:

  • Mengatur mode keluaran digital pin yang dipilih.
  • Jam keluar sinyal yang dikodekan untuk mengambil nilai kelembaban dan suhu terbaru.
  • Memeriksa dan melaporkan setiap kesalahan.
  • Menghitung nilai suhu dan kelembapan yang dapat dibaca manusia dari data mentah yang diambil.

Untuk menjaga hal-hal seefisien mungkin di sisi FirmaExpress, Dr. Wheeler menurunkan rutinitas konversi data dari Arduino ke pymata4.

Langkah 3: Memodifikasi FirmaExpress untuk Dukungan DHT

Pohon Direktori FirmaExpress

Di bawah ini adalah semua file yang terdiri dari repositori FirmaExpress. Pohon ini identik dengan StandardFiramata, hanya saja beberapa nama file mencerminkan nama repositori.

File yang perlu dimodifikasi adalah yang memiliki tanda bintang (*) di sebelahnya.

Firma Express

* Papan.h

contoh

Firma Express

papanx

* FirmaExpress.ino

LISENSI.txt

Makefile

* FirmaConstants.h

* FirmaDefines.h

FirmaExpress.cpp

FirmaExpress.h

FirmaMarshaller.cpp

FirmaMarshaller.h

FirmaParser.cpp

FirmaParser.h

Mari kita lihat masing-masing file dan perubahan yang dibuat.

Boards.h

File ini berisi definisi makro tipe pin untuk setiap tipe papan yang didukung. Ini menentukan jumlah maksimum perangkat yang didukung ketika lebih dari satu perangkat perlu didukung.

Untuk perangkat DHT, hingga 6 perangkat dapat dihubungkan sekaligus dan nilai ini didefinisikan sebagai:

#ifndef MAX_DHTS

#tentukan MAX_DHTS 6 #endif

Selain itu, makro jenis pin dapat ditentukan secara opsional untuk perangkat baru, baik untuk semua jenis papan atau hanya yang menarik bagi Anda. Makro ini sebagian besar digunakan untuk tujuan pelaporan dan tidak digunakan untuk mengontrol perangkat. Makro ini menentukan kedua pin yang mendukung perangkat:

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

Serta makro untuk menentukan konversi nomor pin.

#tentukan PIN_TO_DHT(p) PIN_TO_DIGITAL(p)

FirmaConstants.h

File ini berisi nomor versi firmware, yang mungkin ingin Anda modifikasi untuk melacak versi mana yang telah Anda muat ke Arduino Anda. Ini juga berisi nilai pesan Firma, termasuk pesan Firma SysEx.

Anda perlu menetapkan pesan baru atau kumpulan pesan untuk perangkat Anda dalam file ini. Untuk DHT, dua pesan ditambahkan. Satu mengonfigurasi pin sebagai pin "DHT", dan yang lainnya, sebagai pesan reporter, saat mengirim kembali data DHT terbaru ke klien.

static const int DHT_CONFIG = 0x64;

static const int DHT_DATA = 0x65;

Mode pin juga ditentukan dalam file ini. Untuk DHT, mode pin baru telah dibuat:

static const int PIN_MODE_DHT = 0x0F; // pin dikonfigurasi untuk DHT

Saat menambahkan mode pin baru, TOTAL_PIN_MODES harus disesuaikan:

static const int TOTAL_PIN_MODES = 17;

FirmaDefines.h

File ini harus diperbarui untuk mencerminkan pesan baru yang ditambahkan ke FirmaConstants.h:

#ifdef DHT_CONFIG#undef DHT_CONFIG #endif #define DHT_CONFIG firmata::DHT_CONFIG // DHT request #ifdef DHT_DATA #undef DHT_DATA #endif #define DHT_DATA firmata::DHT_DATA // DHT reply #ifdef DHT_DATA #endif #define DHT_DATA firmata::DHT_DATA // DHT reply #ifdef PIN_MODE::PIN_MODE_DHT

FirmaExpress.ino

Dalam diskusi ini, kita akan membahas "poin tinggi" dari perubahan yang dilakukan pada sketsa Arduino ini.

Agar FirmaExpress mendukung hingga enam perangkat DHT secara bersamaan, 3 array dibuat untuk melacak setiap nomor pin terkait perangkat, nilai WakeUpDelay, dan jenis perangkat, yaitu DHT22 atau DHT11:

// sensor DHT

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

Karena kedua jenis perangkat memerlukan sekitar 2 detik antara pembacaan, kita perlu memastikan bahwa kita membaca setiap DHT hanya sekali dalam jangka waktu 2 detik. Beberapa perangkat, seperti perangkat DHT dan sensor jarak HC-SR04, hanya diakses secara berkala. Ini memberi mereka waktu untuk berinteraksi dengan lingkungan mereka.

uint8_t nextDHT = 0; // indeks ke dht agar perangkat berikutnya dapat dibaca

uint8_t saat iniDHT = 0; // Melacak sensor mana yang aktif. int dhtNumLoops = 0; // Target berapa kali melalui loop b4 mengakses DHT int dhtLoopCounter = 0; // Penghitung lingkaran

Mengkonfigurasi Dan Membaca Perangkat DHT

Ketika FirmaExpress menerima perintah SysEx untuk mengkonfigurasi pin untuk operasi DHT, itu memverifikasi bahwa jumlah maksimum perangkat DHT belum terlampaui. Jika DHT baru dapat didukung, array DHT diperbarui. Jika tipe DHT tidak diketahui, pesan string SysEx dibuat dan dikirimkan kembali ke pymata4

kasus DHT_CONFIG: int DHT_Pin = argv[0]; int DHT_type = argv[1]; if (numActiveDHTs < MAX_DHTS) { if (DHT_type == 22) { DHT_WakeUpDelay[numActiveDHTs] = 1; } else if (DHT_type == 11) { DHT_WakeUpDelay[numActiveDHTs] = 18; } else { Firmata.sendString("ERROR: JENIS SENSOR TIDAK DIKETAHUI, SENSOR VALID ADALAH 11, 22"); merusak; } // uji sensor DHT_PinNumbers[numActiveDHTs] = DHT_Pin; DHT_TYPE[numActiveDHTs] = DHT_type; setPinModeCallback(DHT_Pin, PIN_MODE_DHT);

FirmaExpress kemudian mencoba berkomunikasi dengan perangkat DHT. Jika ada kesalahan, itu membentuk pesan SysEx dengan data kesalahan dan mengirim pesan SysEx kembali ke pymat4. Variabel _bits menyimpan data yang dikembalikan oleh perangkat DHT untuk pemrosesan tambahan oleh pymata4 jika diinginkan.

Firma.write(START_SYSEX);

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

Jika data yang valid dikembalikan, jumlah DHT aktif bertambah. Variabel yang melacak berapa banyak iterasi loop yang harus diselesaikan sebelum memeriksa DHT berikutnya untuk data juga disesuaikan. Variabel ini memastikan bahwa tidak peduli berapa banyak DHT yang ditambahkan ke sistem, semuanya akan dibaca dalam periode 2 detik.

int rv = readDhtSensor(numActiveDHTs);

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

Jika satu atau lebih perangkat DHT telah dikonfigurasi dalam fungsi loop sketsa, maka perangkat DHT berikutnya dibaca. Data yang valid atau status kesalahannya dikembalikan ke pymata4 dalam bentuk pesan 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; DHT saat ini = DHT berikutnya; if (nextDHT++ >= numActiveDHTs - 1) { nextDHT = 0; } if (rv == DHTLIB_OK) { // TEST CHECKSUM uint8_t sum = _bits[0] + _bits[1] + _bits[2] + _bits[3]; if (_bit[4] != jumlah) { rv = -1; } } // mengirim pesan kembali dengan status kesalahan Firma.write(START_SYSEX); Firma.write(DHT_DATA); Firma.write(current_pin); Firma.write(current_type); for (uint8_t i = 0; i < sizeof(_bits) - 1; ++i) { Firma.write(_bits); // Firma.write(_bits; } Firma.write(abs(rv)); Firma.write(0); Firma.write(END_SYSEX); } }

Kode yang digunakan untuk berkomunikasi dengan perangkat DHT diturunkan langsung dari pustaka DHTNew:

int readDhtSensor(int indeks){

// INIT BUFFERVAR UNTUK MENERIMA DATA uint8_t mask = 128; uint8_t idx = 0; // BUFFER KOSONG // memset(_bits, 0, sizeof(_bits)); for (uint8_t i = 0; i 5 BYTES for (uint8_t i = 40; i != 0; i--) { loopCnt = DHTLIB_TIMEOUT; while (digitalRead(pin) == LOW) { if (--loopCnt == 0) return DHTLIB_ERROR_TIMEOUT; } uint32_t t = micros(); loopCnt = DHTLIB_TIMEOUT; while (digitalRead(pin) == HIGH) { if (--loopCnt == 0) return DHTLIB_ERROR_TIMEOUT; } if ((micros() - t) > 40) { _bits[idx] |= mask; } mask >>= 1; if (mask == 0) // byte berikutnya? { mask = 128; idx++; } } return DHTLIB_OK; }

Langkah 4: Memodifikasi Pymata4 untuk Dukungan DHT

private_constants.h

Untuk mendukung DHT, kita perlu menambahkan jenis pin dan pesan SysEx baru ke file ini:

# mode pin INPUT = 0x00 # pin ditetapkan sebagai input OUTPUT = 0x01 # pin ditetapkan sebagai output ANALOG = 0x02 # pin analog dalam mode input analog PWM = 0x03 # pin digital dalam mode output PWM SERVO = 0x04 # pin digital dalam mode output Servo I2C = 0x06 # pin termasuk dalam pengaturan I2C STEPPER = 0x08 # pin apa pun dalam mode stepper SERIAL = 0x0a PULLUP = 0x0b # Pin apa pun dalam mode pullup SONAR = 0x0c # Pin apa pun dalam mode SONAR TONE = 0x0d # Pin apa pun dalam mode nada PIXY = 0x0e # dicadangkan untuk mode kamera pixy DHT = 0x0f # Sensor DHT IGNORE = 0x7f # Pesan perintah DHT SysEx DHT_CONFIG = 0x64 # perintah konfigurasi dht DHT_DATA = 0x65 # balasan sensor dht

Jenis pin yang ditambahkan dan perintah SysEx harus sesuai dengan nilai di FirmaConstants.h yang ditambahkan ke FirmaExpress.

pymata4.py

Pymata4 menggunakan kamus Python untuk mengasosiasikan pesan Firmata yang masuk dengan cepat dengan penangan pesan. Nama kamus ini adalah report_dispatch.

Format untuk entri kamus adalah:

{MessageID: [message_handler, jumlah byte data yang akan diproses]}

Entri telah ditambahkan ke kamus untuk menangani pesan DHT yang masuk:

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

7 byte data dalam pesan adalah nomor pin digital Arduino, jenis perangkat DHT (22 atau 11), dan 5 byte data mentah.

Metode _dht_read_response memeriksa kesalahan yang dilaporkan. Jika tidak ada kesalahan yang dilaporkan, kelembaban dan suhu dihitung menggunakan algoritma porting dari perpustakaan Arduino DHTNew.

Nilai yang dihitung dilaporkan melalui metode callback yang disediakan pengguna. Mereka juga disimpan dalam struktur data pin_data internal. Nilai terakhir yang dilaporkan dapat dipanggil kembali dengan polling pin_data menggunakan metode dht_read.

Mengonfigurasi Perangkat DHT Baru

Saat menambahkan perangkat DHT baru, metode set_pin_mode_dht dipanggil. Metode ini memperbarui pin_data untuk pin digital. Itu juga membuat dan mengirim pesan SysEx DHT_CONFIG ke FirmaExpress.

Langkah 5: Mengakhiri

Seperti yang telah kita lihat, menambahkan dukungan Firmata untuk perangkat baru mengharuskan Anda untuk memodifikasi kode server Arduino FirmaExpress dan kode klien pymata4 berbasis Python. Kode FirmaExpress bisa jadi sulit untuk di-debug. Sebuah metode yang disebut printData telah ditambahkan ke FirmaExpress untuk membantu dalam debugging. Metode ini memungkinkan Anda untuk mengirim nilai data dari FirmaExpress dan akan mencetaknya di konsol pymata4.

Fungsi ini membutuhkan pointer ke string karakter dan nilai yang ingin Anda lihat. Jika nilai data terkandung dalam variabel yang disebut argc, Anda dapat memanggil printData dengan parameter berikut.

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

Jika Anda memiliki pertanyaan, tinggalkan komentar, dan saya akan dengan senang hati menjawabnya.

Selamat mengkode!

Direkomendasikan: