查看: 353|回复: 14

[未解决] Arduino 求助 串口接收数据不正确,数据丢失问题

[复制链接]
  • TA的每日心情
    擦汗
    2020-6-7 00:18
  • 签到天数: 2 天

    [LV.1]初来乍到

    发表于 2020-6-2 21:59 | 显示全部楼层 |阅读模式
    问题整了好久,我自己写的C#程序发送数据,arduino接收数据。
    但是发现arduino接收的时候数据不正确,整了好几天,一直搞不懂问题出在哪?
    \r\n

    1、这个发送程序,要发送的是左边的这个数据。


    2、因为数据接收不对,所以我用串口精灵监视发送的数据,发现数据是有正确发送的。


    3、这个是接收的arduino程序。我设定了一个二维数组,然后把接收数据一次放入数组,之后处理2位数组。(加不加这个语句serial.print(data[i][j],效果一样)



    4、一直解释不了,我就把这个接受过数据的数组用led显示出来,我设定接收1显示1,接收0显示0,接收到其他就显示实心方框,led显示如下:


    发现前几行的数据是正常的,第三行开始就出现了问题,我想了好久到底那点出现了问题,求大佬指导。


    发送程序

    发送程序

    串口监视,数据正确

    串口监视,数据正确
    ardunio接收程序.PNG

    led的显示

    led的显示

    该用户从未签到

    发表于 2020-6-3 07:15 来自手机 | 显示全部楼层
    程序不完整我无法解析,初步判断:你是不是忘记写 void loop了啊,小伙子
  • TA的每日心情
    擦汗
    2019-7-29 00:08
  • 签到天数: 47 天

    [LV.5]常住居民I

    发表于 2020-6-3 13:50 | 显示全部楼层
    程序逻辑有猫饼。

    现有逻辑(伪):
    等待串口数据        // Serial.available
    读取 24*26 个字节        // Serial.read

    这里有个问题,串口只要收到1字节等待语句就失效了。
    连续读500多字节,后续的字节都没来及收到就读出去了,数据自然有问题。
  • TA的每日心情
    无聊
    2016-12-23 16:50
  • 签到天数: 2 天

    [LV.1]初来乍到

    发表于 2020-6-3 17:36 来自手机 | 显示全部楼层
    本帖最后由 skyhome 于 2020-6-3 17:42 编辑

    for循环中加一个判断串口是否有数据的语句就可以了,有就循环继续,没有等待
  • TA的每日心情
    擦汗
    2020-6-7 00:18
  • 签到天数: 2 天

    [LV.1]初来乍到

     楼主| 发表于 2020-6-3 22:50 | 显示全部楼层
    本帖最后由 zwer_joel 于 2020-6-3 23:06 编辑
    t3486784401 发表于 2020-6-3 13:50
    程序逻辑有猫饼。

    现有逻辑(伪):

    我解决了这个问题:

    1、我对 Serial.available的理解是返回串口缓存取的长度,用来判断缓存区是否有数据,并不会对缓存区的数据进行修改或者添加。

    2、Serial.read()读取的是缓存区的第一个字节,缓存会减少一个字节。

    3、也就是说,就算没有Serial.available这条语句,我只要能保证串口的缓存区里有数据,并且提前已知数据的长度,我只要用read去读取就行了。

    所以,现在的问题是,我知道发送的数据,数据的长度,并且发送正确。但是就是只能接收前面几个字节!!!
    我今天发现了问题所在:

    1、我发现读取的字符有64个!为什么是这个数,我查看了arduino 资料。串口的接收的缓存只有64字节!!!!!!
    2、这就解释了为啥数据接收不全!因为arduino会自动的吧后面的数据丢弃!

    解决的办法:
    1、我修改了内存的大小,在Arduino\hardware\arduino\avr\cores\arduino\HardwareSerial.h里面。
    2、但是还有个问题和你说的一样,数据还没有接收完,就要往2维数组里传递,所以我做了一个加入了一个延时。
    3、这个问题就解决了
  • TA的每日心情
    擦汗
    2020-6-7 00:18
  • 签到天数: 2 天

    [LV.1]初来乍到

     楼主| 发表于 2020-6-3 22:52 | 显示全部楼层
    skyhome 发表于 2020-6-3 17:36
    for循环中加一个判断串口是否有数据的语句就可以了,有就循环继续,没有等待 ...

    问题的关键是arduino本身的串口缓存定义。详细解决在我回复2楼的帖子上!,感谢!!
  • TA的每日心情
    擦汗
    2020-6-7 00:18
  • 签到天数: 2 天

    [LV.1]初来乍到

     楼主| 发表于 2020-6-3 23:00 | 显示全部楼层
    zwer_joel 发表于 2020-6-3 22:50
    我解决了这个问题:

    1、我对 Serial.available的理解是返回串口缓存取的长度,用来判断缓存区是否有数据 ...

    C:\Users\Shizhuo\Desktop\提问\修改后的程序.PNG
    修改后的程序.PNG
    led修正.jpg
  • TA的每日心情
    擦汗
    2019-7-29 00:08
  • 签到天数: 47 天

    [LV.5]常住居民I

    发表于 2020-6-4 00:10 | 显示全部楼层
    zwer_joel 发表于 2020-6-3 22:50
    我解决了这个问题:

    1、我对 Serial.available的理解是返回串口缓存取的长度,用来判断缓存区是否有数据 ...

    LZ 似乎在跑偏的路上越走越远。

    a. 只是简单的收定长数据包,没必要去库里改缓冲区长度;
    b. 延时的办法,换个波特率(例如降低到 1200bps )就麻烦了;
    c. 最简单只需要每次读取前,都等待到 Serial.available( )>0 即可:
        while( Serial.available( )==0 );
        char ch= Serial.read( );
  • TA的每日心情
    擦汗
    2020-6-7 00:18
  • 签到天数: 2 天

    [LV.1]初来乍到

     楼主| 发表于 2020-6-4 00:28 | 显示全部楼层
    本帖最后由 zwer_joel 于 2020-6-4 00:30 编辑
    t3486784401 发表于 2020-6-4 00:10
    LZ 似乎在跑偏的路上越走越远。

    a. 只是简单的收定长数据包,没必要去库里改缓冲区长度;

    1、这个办法好,是修改波特率可以达到。
    2、但是接收的这种写法, 我最开始就写过了,还是会丢失数据。

    缓存区只有64个字节,当接收超过64个字节的内容的时候,arduino会把64后面的数据丢弃的!
    如果一次性发送500个字节,arduino会把后面的436个数据都给丢弃。并不是每次检查串口Serial.available( )>0 就能解决的。


    解决办法和讨论是在这看到的:https://www.arduino.cn/thread-7885-1-1.html
  • TA的每日心情
    擦汗
    2019-7-29 00:08
  • 签到天数: 47 天

    [LV.5]常住居民I

    发表于 2020-6-4 01:07 | 显示全部楼层
    zwer_joel 发表于 2020-6-4 00:28
    1、这个办法好,是修改波特率可以达到。
    2、但是接收的这种写法, 我最开始就写过了,还是会丢失数据。

    不得不多问一句:
    你用的什么平台?9600bps 的波特率下,500字节都来不及接收(读取速率<串口速率)导致缓冲区溢出?

    除非是 Leonardo 这样的平台(虚拟串口,波特率无效),

    否则用 16U2/340G 这样物理芯片的 Arduino (例如UNO, MEGA)不可能来不及读取。
    毕竟将近 500ms 的传送时间,写入内存绰绰有余,而不是缓冲区溢出。
    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    热门推荐

    5分钟带你快速了解新一代开发板:M5STACK
    5分钟带你快速了解新一代
    一、什么是M5Stack M5Stack是一种模块化、可堆叠扩展的开发板,每个模块
    创客火首发无人机编队套装,开启不一样的人工智能教育
    创客火首发无人机编队套装
    2017年国务院发布《新一代人工智能发展规划》,提出要广泛开展人工智能科普活动,在中
    求助,用l298n模块控制电机转速,老是无缘无故的转动怎么...
    求助,用l298n模块控制电
    代码如下:int state1=0; int state2=0; void setup() { pinMode(9,OUTPUT); pinMode(
    【干货分享】mega2560原理图PCB图纸altium designer18
    【干货分享】mega2560原理
    分享一下mega2560的板子 AD版本 **** 本内容被作者隐藏 **** ergo
    绑定github账号,免费增加设备额度
    绑定github账号,免费增加
    免费增加blinker设备额度的方法: 1.登录点灯管理台( https://admin.diandeng.tech/
    Copyright   ©2015-2016  Arduino中文社区  Powered by©Discuz!   
    快速回复 返回顶部 返回列表