极客工坊

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 29753|回复: 10

如何修改Arduino的串口通信协议,提高发送的数据的可靠性

[复制链接]
发表于 2015-8-20 18:47:18 | 显示全部楼层 |阅读模式
想通过Arduino的串口传输一些数据,想在数据开始的时候加一些数据帧,起到起始位的作用,然后在数据结尾加上一位奇偶校验位,发的时候好发啊,但是接收的时候如何接收到正确的数据,把那些起始的数据帧和奇偶校验位去掉,还原原来的数据,求大神指点下。
回复

使用道具 举报

发表于 2015-8-20 19:38:05 | 显示全部楼层
两种方法:
1:本身串口通信自己就有校验的,
2:自己加,你知道怎么加上去,去掉的过程就是反过来啊。数据接收完以后,根据你自己的算法计算校验结果,跟收到的数据中校验数据比对。
回复 支持 反对

使用道具 举报

发表于 2015-8-20 19:41:27 | 显示全部楼层
要看看你想發送的是什麼類型的資料.
如果是文字, 只用了 7 bit 的 ASCII, 就簡單得多了.   可以用很多特別的數據作記認.
例如每筆資料用 0xFE 開始, 用 0xFF 作結尾.  還可以加入一些 checksum 之類的校對碼, 要確保資料正確, 應該不是大問題.

如果是 binary data, 即會用盡每一個 byte, 就要自己設定一套 protocol, 加入多位的首尾碼, 長度, checksum 之類.
但由於 binary data 終於可以出現任何組合, 結果只可以減低風險, 無論風險多少 (那管是 0.000000000000001%), 也非絕對的安全, 總有出錯的機會.   當然, 如果是雙向通訊, 發送方要收到請求時才會送出資料, 就不怕把不同的資料混亂了, 結尾碼加上多位元的 checksum 以及資料長度的比較, 應該不會有出錯的機會.

但如果發送的一方是自主地不斷送出資料, 而且是 binary data, 就要看資料的性質, 以確保其正確.  在資料中間多加入一些特定的參考數值, 有助確保資料的真確性.

回复 支持 反对

使用道具 举报

发表于 2015-8-20 23:33:46 | 显示全部楼层
打个包就好了,包头+数据+包尾+异或校验。
然后收到数据的时候只需要先找出包头包尾,然后再对中间的数据进行校验就行了
回复 支持 反对

使用道具 举报

发表于 2015-8-20 23:40:23 | 显示全部楼层
通幽境 发表于 2015-8-20 23:33
打个包就好了,包头+数据+包尾+异或校验。
然后收到数据的时候只需要先找出包头包尾,然后再对中间的数据进 ...


打包要先看看數據的類型, 如果數據中剛好出現 包尾 的數據, 就有可能會出問題了.
萬一隨後的數值, 剛好跟 校驗 的數值相符, 就會被誤認了.  
對於 binary 的數據, 這並非不可能的, 問題只是出現的機會率有多大.
回复 支持 反对

使用道具 举报

发表于 2015-8-20 23:49:36 | 显示全部楼层
Super169 发表于 2015-8-20 23:40
打包要先看看數據的類型, 如果數據中剛好出現 包尾 的數據, 就有可能會出問題了.
萬一隨後的數值, 剛好 ...

这个可能是有的,但是你忘了考虑包长的问题。。
这种方式在实际的使用中要么是定长包,要么是不定长包。定长包自是不用说,不定长包为了收到后能够方便的处理数据,都会带上包长一起发出。
所有可以避免这个问题。
回复 支持 反对

使用道具 举报

发表于 2015-8-21 00:36:52 | 显示全部楼层
本帖最后由 Super169 于 2015-8-21 00:39 编辑
通幽境 发表于 2015-8-20 23:49
这个可能是有的,但是你忘了考虑包长的问题。。
这种方式在实际的使用中要么是定长包,要么是不定长包。 ...


你先看看我之前的回答吧, 你說的東西我已提出了.

包長也不可以說是完全沒問題的, 也要看看發送的資料類型.  如果是發送一個 binary file, 內裡可以有各種可能性.
你是假設第一個 byte 就是開始了.  如果資料是不斷發送, 幾筆資料連續送出, 數據的部份就有可能出現完整的另一組數據, 包括了首尾碼及長度甚至校驗也完全匹配的.  當然, 機會率很低很低, 但還是有可能的.  所以並非絕對的安全.

長時間通訊過程, 間中出現問題, 漏了一個 byte 是有可能的.  萬一剛好甩了首碼, 之後如何確認下一筆數據, 單靠首尾碼還是有一定風險的.  

當然, 如果是在 arudino 的通訊, 一般數據的長度都不會太多, 內裡包含另一組合格的數據, 幾乎可以說是不可能.  你說的做法在 arduino 世界, 是應該足夠了, 只是我把問題帶遠了.   所以我說還要看數據的類形.
回复 支持 反对

使用道具 举报

发表于 2015-8-22 21:44:28 | 显示全部楼层
Super169 发表于 2015-8-21 00:36
你先看看我之前的回答吧, 你說的東西我已提出了.

包長也不可以說是完全沒問題的, 也要看看發送的資料 ...

首先,我们将数据打包发送的目的是为了保证收到数据的完整。
其次,连续发送数据的时候,完全是有可能在一个数据包的中间出现另外一个完整的数据包的。
当收到的数据包不完整的时候,说明数据是不完整的,不能使用。而收到数据发现乱码,丢失的情况是不可能完全消除的。所以对不能使用的数据包,抛弃就是了。
最后,没必要考虑数据类型,所谓类型归根结底只是01机器码而已,并无二致。另外,arduino只是将单片机的使用门槛降低了,变得更加方便而已。也许还不是很稳定,但是其他的并没有什么不同。Atmel不比STM32,PIC之类的差。。
回复 支持 反对

使用道具 举报

发表于 2015-8-22 21:59:44 | 显示全部楼层
通幽境 发表于 2015-8-22 21:44
首先,我们将数据打包发送的目的是为了保证收到数据的完整。
其次,连续发送数据的时候,完全是有可能在 ...

不用看類型, 只是因為在 單機片的世界, 資料是有限的.

正如我之前說, 是我把問題帶遠了, 因為我本身是在電腦上的程式的.

如果你要發送一個不知大少的 binary file, 用這種方式就會出現漏洞了.

当收到的数据包不完整的时候,说明数据是不完整的,不能使用。而收到数据发现乱码,丢失的情况是不可能完全消除的。所以对不能使用的数据包,抛弃就是了。


其實你這段的意思, 也代表要接收一方對資料的類型有一定的認識.  可能我用字不好, 我說的類型, 並不是指 binary 或 text, 而是數據的意義(或者說, 是如何判斷該數據是否正常).

如果你要做一個 generic 既通訊模組, 本身就只知道數據包是否完整, 但是否可用是不會知道(知道的話, 就是要了解數據的類型了).

anyway, 是我不好, 把問題帶到別處了.  我只是想你明白, 當數據的 size 可以變得很大的時候, 單靠首尾碼, 長度, 校驗 是不足以絕對保證的.  一舨還有很多方法, 去增加特別碼(例如首尾碼)的確認的準確性.
回复 支持 反对

使用道具 举报

 楼主| 发表于 2015-8-24 11:51:34 | 显示全部楼层
能不能来几个具体的程序解释一下啊
回复 支持 反对

使用道具 举报

发表于 2015-8-24 14:31:54 | 显示全部楼层
参考mod-bus 工业协议 就行
已经有标准库可用
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

Archiver|联系我们|极客工坊

GMT+8, 2026-6-16 23:18 , Processed in 0.037850 second(s), 22 queries .

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表