小R科技-WIFI机器人网·机器人创意工作室

 找回密码
 立即注册
查看: 7282|回复: 7

【求助】关于下位机通信协议

[复制链接]
发表于 2013-8-7 16:31:18 | 显示全部楼层 |阅读模式
本帖最后由 ylsmwj 于 2013-8-7 16:46 编辑

最近在坛子里找了个下位机通信协议
原帖地址:arduino下位机通信协议(完全兼容论坛的上位机程序)
我将该程序写入了ARDUINO板,按照论坛的通信协议:WIFI机器人网·机器人创意工作室上位机与下位机通信协议V1.0版
用USB TO TTL小板向ARDUINO板发送前进指令“FF000100FF“,后退“FF000200FF“,arduino板均无任何反应,不知何解
但我已确认USB TO TTL小板正确的向ARDUINO板发送了指令,换我自己编写的单字符通信协议就一切正常。
本人小白,没学过编程,这段程序前边能看懂,可都了后边接收串口数据那部分实在是看不懂了
那位大大能帮我逐句解释下,小弟不胜感激
小弟的理解是这样的,下边这段程度里if(Serial.available())判断串口缓冲区是否有数据,条件显然为真,
tempData = Serial.read();这句将串口缓冲区中的第一个字节赋予tempData
if(tempData == UART_FLAG && flagCount < 2),这句判断接收到的是否为0XFF与小于2,因为read()函数智能读取一个字节
因此这里的条件应该不成立,如果发送的是“FF000100FF“,那么此时接收到的应该是一个“F”,因此条件不成立跳过,接下来执行这两句
rxData[n] = tempData;
n++;
执行这两句后N应该等于2
再接着执行if(flagCount == 2)这句,但此时flagCount的值应该为0,因此条件不成立跳过
接下来是if(UARTReveived == 1),此时UARTReveived应为0,因此也不成立,跳过
这样就直接到了程序尾部,
void loop()函数本身就相当于一个死循环,因此又到了程序的开头部分读取串口缓冲区的数据
但是read()函数,每次读取一个字节,因此程序的流程又回到了我上边的解释。

小弟没学过编程,全凭查资料看到这里,显然是我理解的有问题,实在是弄不下去了,盼各位大大救命,不胜感激,谢谢!

就这一段程序里接收串口数据后,下面的判断部分实在不懂
int n = 1;
int flagCount = 0;
int tempData = 0;
int UARTReveived = 0;
int rxData[5];
void loop()
{
  if(Serial.available())
  {
    tempData = Serial.read();
    delay(3);
    if(tempData == UART_FLAG && flagCount < 2)
    {
      rxData[0] = tempData;
      flagCount++;
    }
    else
    {
      rxData[n] = tempData;
      n++;
    }
    if(flagCount == 2)
    {
      rxData[4] == UART_FLAG;
      UARTReveived = 1;
      n = 1;
      flagCount = 0;
      tempData = 0;
      Serial.flush();
    }
  }
  if(UARTReveived == 1)
  {
    if(rxData[1] == MOTO)
    {
       switch(rxData[2])
       {
         case FORWARD:
         carGoFwd();
         break;
         case BACKWARD:
         carGoBwd();
         break;
         case TURNLEFT:
         carTurnL();
         break;
         case TURNRIGHT:
         carTurnR();
         break;
         case CARSTOP:
         carStop();
         break;
       }
       UARTReveived = 0;
    }
    else if(rxData[1] == SERVO)
    {
      servoSet(rxData[2], rxData[3]);
      UARTReveived = 0;
    }
    else if(rxData[1] == MOTOSPEED)
    {
      CHNSpeed(rxData[2], rxData[3]);
      UARTReveived = 0;
    }
  }
}


回复

使用道具 举报

发表于 2013-8-22 22:23:24 | 显示全部楼层
int n = 1;
int flagCount = 0;  '接收到数据包FF的数量,如果数值等于0表示接收到数据包头,等于2表示接收到数据包尾
int tempData = 0; ' 存放读取到的缓冲区的第一个字节
int UARTReveived = 0; 接收到数据包的结尾,也就是第二个FF的时候该变量的值为1,这时表示数据包已经接收完整,准备执行命令;执行完后该值变为0
int rxData[5];
void loop()
{
  if(Serial.available())
  {
    tempData = Serial.read();
    delay(3);
    if(tempData == UART_FLAG && flagCount < 2) ' flagCount < 2成立时有两种情况:flagCount == 0或者 flagCount == 1。等于0时表示之前没有接收过FF,这次接收到的FF是数据包的开头。等于1则表示之前已经接受过一次FF,这次接收到的第二个FF是数据包的结尾。假如发送的是“FF000100FF”,那第一次检测到FF(也就是tempData == UART_FLAG )时flagCount == 0 ,所以条件为真,执行大括号的内容。注意一个字节是十六进制的0xFF,而不是F!    {
      rxData[0] = tempData; '把接收到的FF存放到数组 rxData的第一位。这里其实有一点逻辑错误!!当接收到数据包的结尾,也就是flagCount == 1 时,也会往数组的第一位写进FF,但这完全不会影响到程序的执行。
      flagCount++; ' 每接收到第一个FF,这个值就会加1。
    }
    else ' 如果上述条件不成立则表示正在接收数据包中
    {
      rxData[n] = tempData;
      n++;
    }
    if(flagCount == 2) '当接收到第二个FF时,这个条件就会成立,表示数据包接收完毕
    {
      rxData[4] == UART_FLAG;
      UARTReveived = 1;
      n = 1;
      flagCount = 0;
      tempData = 0;
      Serial.flush();
    }
  }
  if(UARTReveived == 1)
  {
    if(rxData[1] == MOTO)
    {
       switch(rxData[2])
       {
         case FORWARD:
         carGoFwd();
         break;
         case BACKWARD:
         carGoBwd();
         break;
         case TURNLEFT:
         carTurnL();
         break;
         case TURNRIGHT:
         carTurnR();
         break;
         case CARSTOP:
         carStop();
         break;
       }
       UARTReveived = 0;
    }
    else if(rxData[1] == SERVO)
    {
      servoSet(rxData[2], rxData[3]);
      UARTReveived = 0;
    }
    else if(rxData[1] == MOTOSPEED)
    {
      CHNSpeed(rxData[2], rxData[3]);
      UARTReveived = 0;
    }
  }
}
回复 支持 1 反对 0

使用道具 举报

发表于 2013-8-8 19:58:18 | 显示全部楼层
这协议是16进位的,你测试时有从单字符换成16进位吗
建议看robotStudio大的程序来学
要的话也是可以把我的程序发给你
回复 支持 反对

使用道具 举报

发表于 2013-8-22 22:28:34 | 显示全部楼层
我测试过该程序执行没有问题的!如果你用串口调试不行的话,估计你是没有在串口调试软件中把发送的数据改成16进制!!!!但是我写了这段程序后兴趣转移去玩四轴了,所以没有进一步完善。如果上位机的通信协议没有改变的话你直接论坛发布的上位机调试应该是可以的!
回复 支持 反对

使用道具 举报

 楼主| 发表于 2013-8-23 14:27:30 | 显示全部楼层
jackzeng 发表于 2013-8-22 22:23
int n = 1;
int flagCount = 0;  '接收到数据包FF的数量,如果数值等于0表示接收到数据包头,等于2表示接 ...


经过你得解释,我总算明白了,我一直以为接收一个字节就是“F”,没想到十六进制里是“0XFF",太感谢你了,谢谢!
回复 支持 反对

使用道具 举报

发表于 2013-9-1 10:38:22 | 显示全部楼层
To ”ylsmwj“,如果想发送”FF000100FF"给arduino,在串口调试工具中应该发送什么?还不是很理解这句话。谢谢
回复 支持 反对

使用道具 举报

 楼主| 发表于 2013-9-1 11:15:22 | 显示全部楼层
boyboysk 发表于 2013-9-1 10:38
To ”ylsmwj“,如果想发送”FF000100FF"给arduino,在串口调试工具中应该发送什么?还不是很理解这句话。谢 ...

想发送”FF000100FF"给arduino在串口工具中应该选择“十六进制”发送,因为这个通信协议是基于十六进制数据的,如果不选择十六进制的话,下位机无任何反应。
回复 支持 反对

使用道具 举报

发表于 2015-10-24 21:38:21 | 显示全部楼层
u70253a 发表于 2013-8-8 19:58
这协议是16进位的,你测试时有从单字符换成16进位吗
建议看robotStudio大的程序来学
要的话也是可以把我 ...

能发给我下么 学习学习{:2_31:}
回复 支持 反对

使用道具 举报

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

本版积分规则

关闭

新品特惠推荐上一条 /2 下一条

QQ|QQ技术咨询1|QQ技术咨询2|商务合作微信1:xiaorgeek001|商务合作微信2:XiaoRGEEK|诚聘英才|Archiver|手机版|小R科技-WIFI机器人网·机器人创意工作室 ( 粤ICP备15000788号-6 )

GMT+8, 2024-3-28 23:31 , Processed in 1.084177 second(s), 19 queries .

Powered by XiaoR GEEK X3.4

© 2014-2021 XiaoR GEEK

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