搜索
bottom↓
回复: 24

SIM模块TCP通讯丢字节跟CTS/RTS有关吗

[复制链接]

出0入0汤圆

发表于 2014-9-20 08:53:04 | 显示全部楼层 |阅读模式
测试了SIM900A,通过GPRS连接到服务器端口,以TCP/IP长连接来通讯,但是发现只要发送的数据比较多,就会丢字节,例如连续发送3000字节,服务器那边有时候就会少收到十几个字节。后来换了GU900D,用数据透传的方式来收发,还是会有丢字节现象的发生,查了很久都找不到原因。
后来发现模块的CTS、RTS没有进行连接,想请教下大家,进行TCP/IP时有没有必要连接CTS、RTS引脚?是不是可能因为这个原因而导致SIM900A收到数据太多处理不过来而丢字节的?如果确实需要只能重新打板了。

阿莫论坛20周年了!感谢大家的支持与爱护!!

曾经有一段真挚的爱情摆在我的面前,我没有珍惜,现在想起来,还好我没有珍惜……

出1070入962汤圆

发表于 2014-9-20 09:10:23 来自手机 | 显示全部楼层
SIM900A的MTU是多大?你不拆包直接发大于这个数的数据,就不要赖人家丟包了。另一个模块透传没问题,那是在内部进行了分包处理的。任何内部不好好做分包处理,而有不做输入数据长度检查的模块都是耍流氓。面对流氓自己还不愿意分包处理,那就是在享受流氓的调戏

出0入0汤圆

发表于 2014-9-20 09:18:28 | 显示全部楼层
没有关系

出0入0汤圆

发表于 2014-9-20 09:23:46 | 显示全部楼层
自定义数据格式,接收检查校验

出0入0汤圆

发表于 2014-9-20 10:04:46 | 显示全部楼层
楼主连续发送3000不丢才怪,我记得sim900的缓存才1.5k左右!

出0入0汤圆

 楼主| 发表于 2014-9-21 22:57:07 | 显示全部楼层
Appcat 发表于 2014-9-20 09:10
SIM900A的MTU是多大?你不拆包直接发大于这个数的数据,就不要赖人家丟包了。另一个模块透传没问题,那是在 ...

你好,是这样的,开始的时候用SIM900A,用AT+CIPSEND命令来发送数据,有进行分包处理,每次200字节,发送完一包后再发下一包。但是测试的时候发现一次发上几K的数据就会有问题,我程序设置的每次向SIM900A发送命令时都要收到反馈才能发下一条。
后来换了GU900D,怕像SIM900A一样出问题,就不用AT+CIPSEND命令一点点发数据了,改成用透传的方式,但还是有丢数据。

刚才在网上搜索了一下SIM900A找到如下信息:
RTS、CTS:主要是透传状态下作为硬件流控使用;
在透传模式下,模块完全处于数据态,模块内部buffer有8KByte的空间,正常情况下CTS引脚为低电平,如果buffer内数据大于6KByte,模块CTS引脚置高,此时不要向buffer内丢数据,等待CTS引脚拉低(此时buffer内数据小于2KByte)后在向buffer内丢数据。

这里说SIM900A有8K的buffer,估计GU900D应该也差不多,我发3K应该不会超的。

出0入0汤圆

 楼主| 发表于 2014-9-21 23:03:00 | 显示全部楼层
SIM模块供电4.2V,主控STM32供电电压3.3V,两者的TXD、RXD串100欧的电阻直连,波特率115200。
提供的信息比较少,我也不太清楚需要提供哪些信息供大家判断问题所在,想请大家帮忙判断下比较可能出问题的地方在哪里。

出1070入962汤圆

发表于 2014-9-22 10:02:51 | 显示全部楼层
dalarang 发表于 2014-9-21 22:57
你好,是这样的,开始的时候用SIM900A,用AT+CIPSEND命令来发送数据,有进行分包处理,每次200字节,发送 ...

这个问题是GPRS网络的问题,不是模块的问题。所以不要纠结模块有多少缓冲了。
关键问题是MTU,一般G网的MTU不会大于1.5K,很多模块提供的最大单TCP包长度都要小于这个数,所以自己发送的时候就不要超了。
超了过后,模块一般是不会去很负责的去分包的,很多模块的透传指令就是垃圾,依赖这种指令,小数据流还可以凑合,大数据就完蛋。
所以你的问题在程序里边,不在RTS/CTS上面。

出0入0汤圆

发表于 2014-9-22 10:13:11 | 显示全部楼层
CTS和RTS是串口上流控线,用指令可以取消流控的,所以可以取消去消除这个因素;至于一包能发多少你得仔细看模块手册,单独一包可以发多少,然后网络缓冲是否繁忙等

出0入0汤圆

 楼主| 发表于 2014-9-22 11:16:15 | 显示全部楼层
Appcat 发表于 2014-9-22 10:02
这个问题是GPRS网络的问题,不是模块的问题。所以不要纠结模块有多少缓冲了。
关键问题是MTU,一般G网的M ...

谢谢指导,现已查到是自己软件的问题,是我串口收发中断有点问题。十分感谢!!

目前还是使用GU900D的透传方式,经测试可以一次发送4096字节而没有丢字节。

目前有个比较头疼的问题是,用透传的方式,通讯是否成功不会有任何反馈。偶尔丢包对目前的应用来说并不怎么要紧,但是TCP连接中断后也没有任何反馈,MCU压根就不知道SIM模块到服务器的TCP连接是否已被掐断。

出1070入962汤圆

发表于 2014-9-22 11:22:23 | 显示全部楼层
dalarang 发表于 2014-9-22 11:16
谢谢指导,现已查到是自己软件的问题,是我串口收发中断有点问题。十分感谢!!

目前还是使用GU900D的透 ...

这就是做GPRS的难点了,交给模块自己的透传指令,就等于你放弃了自己的权力,检查TCP掉线是难点,GPRS模块才不会给你做呢。

出0入0汤圆

 楼主| 发表于 2014-9-22 14:11:24 | 显示全部楼层
Appcat 发表于 2014-9-22 11:22
这就是做GPRS的难点了,交给模块自己的透传指令,就等于你放弃了自己的权力,检查TCP掉线是难点,GPRS模 ...

现在又试了以前写的程序,自己分包发送,用AT+CIPSEND命令一包发256字节,收到SEND OK反馈后再发送下一包,可以连续发十几包都没丢字节。这样就可以不使用透传模式了,也可以通过反馈判断通讯是否正常。

感觉GSM模块的故障判断有些繁琐,现在我对收到的GSM异常反馈都不进行判断,只要GSM没有返回正确的OK反馈,就视作异常,重启GSM模块进行重新设置。

出0入0汤圆

 楼主| 发表于 2014-9-22 14:13:55 | 显示全部楼层
另外AT+CIPSEND发包时一包最多允许的字节也没个确定数,搜索一下各种答案都有,用透传的方式时,在服务器端能看到有的包也有1k大小的。AT+CIPSEND发包时一包设为1k不知道会不会有稳定性的问题。

出1070入962汤圆

发表于 2014-9-22 14:24:21 | 显示全部楼层
设定为1K是安全的,并且是高效的。

出0入10汤圆

发表于 2014-9-24 08:58:15 | 显示全部楼层
dalarang 发表于 2014-9-22 14:11
现在又试了以前写的程序,自己分包发送,用AT+CIPSEND命令一包发256字节,收到SEND OK反馈后再发送下一包 ...

当信号不好的时候,发送数据,服务器能收到,但模块好像不会返回SEND OK,楼主有没有碰到过这种情况?

出0入10汤圆

发表于 2014-9-24 09:02:17 | 显示全部楼层
Appcat 发表于 2014-9-22 11:22
这就是做GPRS的难点了,交给模块自己的透传指令,就等于你放弃了自己的权力,检查TCP掉线是难点,GPRS模 ...

检查TCP掉线是难点,猫大侠说得对,采用PPP连接会不会好点呢?采用AT指令,当连接断了,有时候会遇到发送AT+CIPSTATUS查询状态,但模块返回CONNECT OK,过2分钟后才返回CLOSED,不采用握手应答机制的话,猫大侠有没有好的方法判断连接状态呢?

出0入0汤圆

 楼主| 发表于 2014-9-24 09:21:33 | 显示全部楼层
lklhzu 发表于 2014-9-24 08:58
当信号不好的时候,发送数据,服务器能收到,但模块好像不会返回SEND OK,楼主有没有碰到过这种情况? ...

目前是没有遇上,我现在发数据时,如果延迟一小段时间没有返回SEND OK,视为异常,也不管它是什么原因,直接重启GSM模块重新配置。

感觉用GSM模块进行通讯时异常状况会挺多的,网络状态不好、丢包、信号弱、欠费停机等等各原因都有可能,就像关闭TCP连接,有时候就很快,有时候却很久,各种异常一个个判断的话程序太繁琐了,我现在的理念是只要有异常,不做任何判断,直接重启GSM模块重新连接。

出0入0汤圆

发表于 2014-9-24 09:41:11 | 显示全部楼层
你这样无论任何原因都重启模块来解决很不科学,打个比方 对方的服务器挂掉了,你一直重启模块,对模块的寿命会有很大的影响

出1070入962汤圆

发表于 2014-9-24 10:18:58 | 显示全部楼层
lklhzu 发表于 2014-9-24 09:02
检查TCP掉线是难点,猫大侠说得对,采用PPP连接会不会好点呢?采用AT指令,当连接断了,有时候会遇到发送 ...

靠模块与服务器的心跳机制来解决。

出0入0汤圆

发表于 2014-9-24 10:21:42 | 显示全部楼层
sim900a用过,没有使用cts,也没有丢包。

出0入0汤圆

 楼主| 发表于 2014-9-24 16:29:34 | 显示全部楼层
本帖最后由 dalarang 于 2014-9-24 16:31 编辑
Appcat 发表于 2014-9-24 10:18
靠模块与服务器的心跳机制来解决。


猫前辈,我发现一个比较奇怪的问题,想请教下。

我设置一个256字节的数组并赋值:
u8 tmp[256];
for(i=0;i<256;i++)
{
    tmp=i;
}


这样该数组的值就是就是依次0x00-0xFF。
然后向GSM模块发送AT+CIPSEND=256的命令,之后再将这个数组发送出去。
但是在服务器端只能收到26个字节,后来查了很久才发现,发送AT+CIPSEND=256命令后,再发送数组时,只要发到0x19之后就自动发送出去了。
查询ASCII码表,0x17/0x18/0x19分别是传输块结束/取消/介质中断的含义,看起来是AT+CIPSEND后在接收到这几个字节后就视为结束,而不管是否已经达到256,自动将收到的数据发出去。

看起来是数据被当作结束符来解释了,这种情况有什么办法能强制让GSM模块以收到的数据字节数为依据,而不把判断数据中是否有结束符吗。

出0入0汤圆

 楼主| 发表于 2014-9-24 16:37:52 | 显示全部楼层
又重新试了一下,如果不是0-256这样的数组依次排列发送,就不会被中断掉,看来这个问题应该不要紧,因为正常数据不会是这种顺序规则排列的。

出1070入962汤圆

发表于 2014-9-24 17:07:27 | 显示全部楼层
本帖最后由 Appcat 于 2014-9-24 17:10 编辑
dalarang 发表于 2014-9-24 16:29
猫前辈,我发现一个比较奇怪的问题,想请教下。

我设置一个256字节的数组并赋值:


  1. u8 tmp[256];
  2. for(i = 0; i < 256; i++)
  3. {
  4.     tmp[i] = i;
  5. }
复制代码


还有,一般模块要么声明发送多少字节后自己点够数,要么识别某个特殊的字符来结束接收并启动打包发送,哪有这么无赖的做法的,建议你还是查查它的发送指令具体要求。我没有用过SIMCOM的产品。

出0入0汤圆

 楼主| 发表于 2014-9-24 18:58:30 | 显示全部楼层
Appcat 发表于 2014-9-24 17:07
还有,一般模块要么声明发送多少字节后自己点够数,要么识别某个特殊的字符来结束接收并启动打包发送 ...

不无赖啊,只想让它点够数再发送,但是现在没点够数,它就自动识别到特殊字符启动打包发送了。

出1070入962汤圆

发表于 2014-9-24 19:50:42 来自手机 | 显示全部楼层
dalarang 发表于 2014-9-24 18:58
不无赖啊,只想让它点够数再发送,但是现在没点够数,它就自动识别到特殊字符启动打包发送了。 ...

我说模块无赖诶,没说你。要吃透模块的特性,才能准确的选择模块。
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片。注意:要连续压缩2次才能满足要求!!】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-8-25 22:15

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

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