Kapan satu beralih dari ASCII ke protokol serial lanjutan?


28

Semua perangkat mikrokontroler saya yang berkomunikasi dengan PC melalui UART menggunakan string ASCII untuk mengirim perintah dan menerima data (seperti yang diterapkan dalam Arduino). Itulah yang saya pelajari ketika saya mulai menggali ke dalam elektronik dan saya selalu merasa mengirim string kosong sudah cukup. Namun saya perhatikan bahwa sebagian besar perangkat yang saya temui menggunakan protokol biner canggih yang mencakup kode fungsi, alamat, dan pengecekan kesalahan CRC.

Kapan komunikasi dasar ASCII dapat diterima dan kapan saya harus mempertimbangkan sesuatu yang lebih maju, seperti Modbus? Apakah perangkat komersial menggunakan ASCII seperti itu? Industri?


3
Jawaban singkat: Ketika aplikasi Anda membutuhkannya. Ya, perangkat komersial menggunakan ASCII. Ambil GPS NMEA sebagai contoh. (Dan lagi, saya akan merujuk pertanyaan saya sendiri di sini )
Eugene Sh.

1
Modbus memiliki mode ASCII. Lihat Modicon Modbus Protocol Reference Guide
Tut

@EugeneSh .: Perlu dicatat bahwa NMEA memiliki bidang checksum, dan menjatuhkan satu sampel meledak karena kegagalan checksum (yang terjadi lebih sering daripada yang Anda kira) umumnya bukan kegagalan kritis. Itu mungkin tidak berlaku untuk protokol lain ... dan ada banyak protokol GPS biner yang digunakan (misalnya Garmin) untuk aplikasi yang memang kritis (atau di mana laju sampel lebih tinggi dari 1Hz adalah diperlukan, yang NMEA terlalu bertele-tele). Meskipun ini hanya menguatkan poin Anda.
Lightness Races dengan Monica

Jawaban:


28
  1. ASCII dan CRC tidak saling eksklusif. ASCII adalah penyandian, dan CRC untuk pengecekan kesalahan.

  2. APA SAJA dapat dikirim sebagai ASCII. Kami orang tua tentu ingat UUEncoding, yang mengubah apa pun menjadi string ASCII.

  3. A) Bagi saya, biasanya masalah kecepatan dan efisiensi. Mengirim nomor 32-bit besar oleh ASCII dapat memakan waktu lama, tetapi hanya perlu 4 byte untuk mengirimkannya sebagai biner melalui protokol serial.

    B) Mengirim ANGKA melalui ASCII berarti Anda harus mengonversi nomor tersebut ke ASCII, yang merupakan langkah ekstra yang jelas (ini adalah bagian dari apa yang dilakukan "printf").

  4. Jika Anda entah bagaimana kehilangan tempat Anda, mengacaukan, kehilangan format, mendapatkan endian yang salah, dll, protokol komunikasi biner pasti dapat mengacaukan. Jika Anda mengirim ASCII, akan lebih mudah untuk pulih dari kekacauan hanya dengan masuk dan MELIHAT aliran data.


12
+1 untuk "ASCII adalah penyandian". Itu bukan protokol; protokol dapat dibangun di atas ASCII.
Pete Becker

8
Memulihkan secara otomatis dari screwup pada dasarnya tidak lebih mudah untuk protokol berbasis teks sebagai protokol biner, tetapi memeriksa dan men-debugnya tentu saja bisa.
Nick Johnson

1
@NickJohnson - tentu saja. Begitu Anda pada titik membuka file dalam hex editor untuk melihat apa yang dapat Anda pulihkan, Anda sudah berada di FUB sejauh SOP berjalan
Scott Seidman

1
@nickjohnson itu tidak benar. ASCII memberi Anda banyak pilihan framing / pembatas band untuk membantu sinkronisasi dan pemulihan, yang akan membutuhkan pelarian tambahan, isian bit, interval waktu atau trik lain jika saluran digunakan untuk data biner lebar penuh.
Chris Stratton

2
Saya selalu menyukai ASCII saat menulis protokol untuk semua manfaat yang jelas (keterbacaan, logabilitas, dll). Ada dua kasus ketika biner lebih masuk akal: pertama, jika kecepatan adalah masalah dan Anda perlu biner untuk menjejalkan data sebanyak mungkin ke dalam aliran, dan kedua, sedikit, jika Anda sengaja mencoba mengaburkan atau bahkan mengenkripsi data streaming untuk menghalangi atau mencegah rekayasa balik. Pada saat itu, saya telah membalikkan protokol biner yang direkayasa dan sebagian besar hanya membuat saya jengkel lebih daripada sebenarnya mencegah tindakan itu.
J ...

10

Berikut ini beberapa pemikiran tentang hal itu:

  • ASCII bagus karena Anda dapat menggunakan monitor serial untuk melihat secara manual apa yang dikirim.
  • jika koneksi Anda tidak dapat diandalkan, Anda harus mengharapkan kesalahan transmisi dan harus menggunakan CRC untuk memeriksa integritas setiap pesan yang diterima. Ini juga dapat dilakukan pada pesan ASCII.
  • jika koneksi Anda terlalu lambat Anda dapat mengurangi ukuran pesan Anda dengan beralih ke format biner
  • Format biner khusus mungkin lebih mudah untuk didekode di sisi penerima daripada ASCII

7

Pada tingkat paling sederhana, Anda bisa mengatakan protokol komunikasi sederhana memiliki tiga lapisan: fisik, transportasi, dan aplikasi. (Ada model dengan lebih banyak seperti OSI dengan 7 atau TCP / IP dengan 4. Jumlah lapisan tidak terlalu penting dalam konteks pertanyaan ini.)

Lapisan aplikasi adalah lapisan yang Anda tangani langsung dalam kode Anda, dan fokus pertanyaan. Sejauh menyangkut lapisan transport, byte yang Anda lewati di send_data hanyalah pola biner, tetapi Anda dapat menafsirkannya dalam kode aplikasi Anda sebagai huruf 'A'. Perhitungan CRC atau checksum akan sama terlepas dari apakah Anda menganggap byte sebagai 'A,' 0x41, atau 0b01000001.

Lapisan transport adalah level paket, di mana Anda memiliki header pesan Anda, dan pengecekan kesalahan, apakah itu CRC atau checksum dasar. Dalam konteks firmware, Anda mungkin memiliki fungsi seperti send_data, tempat Anda mengirimkan byte untuk dikirimkan. Di dalam fungsi itu dimasukkan ke dalam paket yang mengatakan, "Hei ini adalah pesan normal, memerlukan pengakuan, dan checksumnya adalah 0x47, waktu saat ini adalah X." Paket ini dikirim melalui lapisan fisik ke node penerima.

Lapisan fisik adalah tempat elektronik dan antarmuka didefinisikan: konektor, level tegangan, timing, dll. Lapisan ini dapat berkisar dari beberapa jejak yang menjalankan sinyal TTL untuk UART dasar pada PCB, hingga pasangan diferensial sepenuhnya terisolasi seperti pada beberapa Implementasi BISA .

Pada node penerima, paket masuk pada lapisan fisik, dibongkar pada lapisan transport, dan kemudian pola biner Anda tersedia untuk lapisan aplikasi. Terserah lapisan aplikasi simpul penerima untuk mengetahui apakah pola itu harus ditafsirkan sebagai 'A,' 0x41, atau 0b01000001, dan apa yang harus dilakukan dengannya.

Kesimpulannya, mengirimkan karakter ASCII cukup banyak dapat diterima jika itu yang diperlukan oleh aplikasi. Yang penting adalah memahami skema komunikasi Anda, dan memasukkan mekanisme pengecekan kesalahan.


Protokol Ascii juga dapat menggabungkan checksum. Saya telah menemukan variasi Hex-as-ascii, menggunakan representasi angka ascii.
Eugene Sh.

@EugeneSh. Klarifikasi poin itu
Matt Young

Bukan untuk nitpick, tetapi TCP bukan empat lapisan; itu terlihat pas di lapisan empat model OSI. Komunikasi serial tidak terlalu cocok dengan model OSI.
batsplatsterson

@batsplatsterson Itu adalah nitpicking, dan cukup baik tidak relevan dengan poin yang saya buat.
Matt Young

5

Poin yang belum disebutkan adalah bahwa apakah seseorang menggunakan ASCII atau protokol biner, mengirimkan karakter rub-out sebelum setiap paket akan memastikan bahwa bahkan jika noise garis atau kesalahan pembingkaian muncul sebelum dimulainya paket, semua karakter setelah digosok out akan dibingkai dengan benar tanpa adanya kebisingan lebih lanjut. Jika tidak, jika seseorang mengirim paket secara terus menerus dan tidak menyertakan karakter apa pun yang dijamin untuk mencapai sinkronisasi ulang, mungkin saja satu kesalahan dapat merusak semua yang terjadi hingga jeda transmisi berikutnya. Karakter 0xFF bagus karena menjamin bahwa setiap penerima akan dapat melakukan sinkronisasi ulang pada karakter berikut.

(*) 0xFF - disebut rub-out karena seseorang yang mengetik karakter yang salah saat mengetik data ke pita kertas dapat menekan tombol "step tape backward" dan menekan rub-out untuk mengganti karakter yang dilubangi dengan 0xFF, yang akan diabaikan oleh sebagian besar penerima).


2

Salah satu keuntungan mengirim string ASCII adalah bahwa kode kontrol kemudian dapat digunakan untuk memberi sinyal awal / akhir pesan. misalnya STX (char 2) dan ETX (char 3) dapat menandakan mulai transmisi dan transmisi akhir. Atau Anda dapat menambahkan umpan garis sederhana untuk menandai akhir transmisi.

Saat mengirim data biner, ini menjadi lebih rumit karena tidak ada pola bit tertentu yang dapat dicadangkan untuk kode kontrol (tanpa overhead atau kompleksitas tambahan) karena byte data yang valid mungkin memiliki pola yang sama.


3
Banyak protokol biner DO mencadangkan satu atau lebih pola bit sebagai kode kontrol, tetapi mereka juga menyertakan mekanisme pelarian untuk menangani kode-kode itu ketika muncul dalam data.
Dave Tweed

Anda dapat memesan pola apa saja untuk menandai apa pun yang Anda inginkan dalam biner. Sebagai contoh, saya sedang mengerjakan proyek dengan aliran data yang cepat dan aliran data yang lambat keluar dari uart yang sama. Saya memesan int32 negatif terbesar sebagai bendera untuk data saya yang lambat, dan hanya menjenuhkan data negatif saya di +1 terbesar negatif.
Scott Seidman

Sepakat. Saya menjelaskan ini dalam jawaban yang diedit, saya harap.
Transistor

2

ASCII baik-baik saja, saya menggunakannya di hampir semua proyek. Itu membuat debugging lebih mudah untuk memantau port, dan itu hanya akan menjadi masalah jika ada banyak data untuk dikirim.

Bonus lain, saya menggunakan perangkat radio serial untuk mendapatkan pesan di antara arduinos, dan saya bisa menggunakan monitor serial yang terhubung ke laptop saya dan menyuntikkan pesan untuk membuat hal-hal tertentu terjadi. Bagus untuk pengujian.

Selain itu, mengirimkan hal-hal sebagai biner bukan tidak mungkin untuk di-debug dan tergantung pada alat Anda, Anda dapat memiliki biner yang diekstraksi dan dikonversi menjadi sesuatu yang dapat dibaca manusia. Atau jika Anda tahu apa yang Anda cari, Anda dapat secara visual memeriksa datastream dan mengenali nilai-nilai di mana mereka seharusnya dan kesalahan menemukan cara itu, meskipun, tidak begitu mudah. yaitu, Anda akan mengenali pola byte dan mengenali nilai yang diharapkan


2

Alih-alih Modbus pertimbangkan HDLC . Anda mendapatkan deteksi kesalahan (yang penting pada saluran serial berisik). Sinkronisasi kuat, melarikan diri kuat.

Saya telah menggunakan HDLC di jaringan RS-485 tanpa masalah dan PPP juga menggunakannya.


2
Akan lebih baik jika Anda menunjukkan mengapa Anda menyarankannya pada Modbus.
Saya tidak tahu apa yang saya lakukan

1

ASCII atas UART adalah yang paling populer sebagian karena:

  • Itu dapat dibaca manusia saat debugging (saya belum melihat penganalisa logika yang tidak mendekode ASCII).

  • Ini sangat mudah diimplementasikan, Anda punya tabel ASCII melalui google cepat yang terstandarisasi dengan baik.

  • Ini telah membangun sinkronisasi dengan bit start / stop.

  • Hampir seluruh dunia hobbyst telah mengatur dirinya sendiri dengan ASCII melalui serial, jadi setiap metode baru harus berurusan dengan itu, dan itu tidak mudah dengan cara apa pun.

Kemudian Anda masuk ke situasi ketika Anda mulai mengirim pengkodean tertentu, seperti mengirim representasi dalam memori float dibandingkan dengan mengkonversi float ke ASCII, mengirimkannya melalui serial yang bisa lebih dari 4 byte, dan kemudian mengubahnya kembali ke representasi dalam memori pada host. Sebagai gantinya, Anda hanya mengirim representasi 4 byte setiap waktu. Tentu, Anda dapat mulai menangani pengodean sendiri, tetapi kemudian Anda perlu mengatur tag awal / akhir, pesanan, dll.

Sebaliknya, hal-hal seperti Protobuf dapat digunakan. Ini sebenarnya digunakan dalam proyek yang saya kerjakan dan itu sangat bermanfaat, itu pesan panjang variabel, menangani endian untuk Anda, dan beberapa fitur keren lainnya. Ukuran kode juga tidak terlalu besar, dan Anda dapat menentukan semuanya untuk dialokasikan secara statis saat startup. Anda harus melempar checksum sendiri, jika Anda membutuhkannya.

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.