查看: 5681|回复: 10

Arduino小车机器人开发

[复制链接]
  • TA的每日心情
    郁闷
    2018-12-6 22:21
  • 签到天数: 48 天

    [LV.5]常住居民I

    发表于 2017-6-1 00:55 | 显示全部楼层 |阅读模式
    待写
    如果以上内容对你有帮助,你可以通过打赏支持作者
  • TA的每日心情
    慵懒
    2017-11-25 10:54
  • 签到天数: 8 天

    [LV.3]偶尔看看II

    发表于 2017-6-3 19:38 | 显示全部楼层
    奈何大神,交个好友吧  QQ 644952627
  • TA的每日心情
    慵懒
    2017-11-25 10:54
  • 签到天数: 8 天

    [LV.3]偶尔看看II

    发表于 2017-6-3 19:38 | 显示全部楼层
    我加不了你。。。。说我没有权限

    点评

    有问题可以直接论坛或者QQ群交流  详情 回复 发表于 2017-6-3 20:02
  • TA的每日心情
    郁闷
    2018-12-6 22:21
  • 签到天数: 48 天

    [LV.5]常住居民I

     楼主| 发表于 2017-6-3 20:02 | 显示全部楼层
    韩娅 发表于 2017-6-3 19:38
    我加不了你。。。。说我没有权限

    有问题可以直接论坛或者QQ群交流
    如果以上内容对你有帮助,你可以通过打赏支持作者
  • TA的每日心情
    郁闷
    2018-12-6 22:21
  • 签到天数: 48 天

    [LV.5]常住居民I

     楼主| 发表于 2017-6-7 10:51 | 显示全部楼层

    有问题可以直接发帖提问,或者加社区QQ群提问。。。
    如果以上内容对你有帮助,你可以通过打赏支持作者
  • TA的每日心情
    开心
    2017-9-11 09:29
  • 签到天数: 1 天

    [LV.1]初来乍到

    发表于 2017-6-7 16:03 | 显示全部楼层
    等着呢,赶紧的吧!
  • TA的每日心情
    慵懒
    2017-6-27 08:45
  • 签到天数: 15 天

    [LV.4]偶尔看看III

    发表于 2017-6-14 13:30 | 显示全部楼层
    奈何! 请问假如我要用modbus RTU这个程序控制一个LED灯 接下来该怎么写?

    #define bufferSize 255  //一帧数据的最大字节数量
    #define baudrate 9600  //定义通讯波特率
    #define slaveID 1  //定义modbus RTU从站站号
    #define modbusDataSize 100  //定义modbus数据库空间大小

    unsigned int modbusData[modbusDataSize] = {}; //建立modbus数据库

    unsigned int calculateCRC(unsigned char* _regs, unsigned char arraySize); //声明CRC校验函数
    void modbusRTU_slave();  //声明modbus RTU从站函数


    void setup()  //初始化函数
    {
      Serial.begin(baudrate);
      Serial.flush();
      pinMode(13, OUTPUT);

    }

    void loop()   //主循环
    {
      modbusRTU_slave();  //执行modbus函数

    }


    void modbusRTU_slave()
    {
      unsigned char frame[bufferSize];  //用于保存接收或发送的数据
      unsigned int characterTime; //字符时间
      unsigned int errorFlag = 0; //错误标志
      unsigned int crc16;  //校验位
      unsigned char address = 0;

      if (baudrate > 19200)  //波特率大于19200时进入条件
      {
        characterTime = 750;
      }
      else
      {
        characterTime = 15000000 / baudrate; //1.5字符时间
      }
      while (Serial.available() > 0) //如果串口缓冲区数据量大于0进入条件
      {

        if (address < bufferSize) //接收的数据量应小于一帧数据的最大字节数量
        {
          frame[address] = Serial.read();
          address++;
        }
        else  //条件不满足时直接清空缓冲区
        {
           Serial.read();
        }
        delayMicroseconds(characterTime);  //等待1.5个字符时间
        if (Serial.available() == 0) //1.5个字符时间后缓冲区仍然没有收到数据,认为一帧数据已经接收完成,进入条件
        {
          if (frame[0] == slaveID || frame[0] == 0) //站号匹配或者消息为广播形式,进入条件
          {
            crc16 = ((frame[address - 2] << 8) | frame[address - 1]);
            if (calculateCRC(&frame[0], address - 2) == crc16) //数据校验通过,进入条件
            {
              unsigned char function = frame[1]; //读取功能码
              if (frame[0] != 0 && (function == 3)) //功能码03不支持广播消息
              {
                unsigned int startData = ((frame[2] << 8) | frame[3]); //读取modbus数据库起始地址
                unsigned int dataSize = ((frame[4] << 8) | frame[5]); //需要读取的modbus数据库数据长度
                unsigned int endData = startData + dataSize; //需要读取的modbus数据库数据的结束地址
                unsigned char responseSize = 5 + dataSize * 2; //计算应答的数据长度
                unsigned int temp1, temp2, temp3;

                if (dataSize > 125) //modbus一帧的最大数据量为255个字节,即一次最多读取125个数据
                {
                  errorFlag = 1;
                  //待添加错误信息返回函数
                }
                else
                {
                  frame[0] = slaveID; //设定站号
                  frame[1] = function; //设定功能码
                  frame[2] = dataSize * 2; //设定数据长度
                  temp3 = 3;
                  for (temp1 = startData; temp1 < endData; temp1++)
                  {
                    if (temp1 >= modbusDataSize) //需要读取的地址大于modbus数据库的最大地址
                    {
                      temp2 = 0;
                    }
                    else  //取出modbus数据库中的数据
                    {
                      temp2 = modbusData[temp1];
                    }
                    frame[temp3] = temp2 >> 8;
                    temp3++;
                    frame[temp3] = temp2 & 0xFF;
                    temp3++;
                  }
                  crc16 = calculateCRC(&frame[0], responseSize - 2);
                  frame[responseSize - 2] = crc16 >> 8; //填写校验位
                  frame[responseSize - 1] = crc16 & 0xFF;
                  Serial.write(&frame[0], responseSize); //返回功能码03的消息
                }
              }
              else if (function == 6) //功能码为06时进入条件
              {
                unsigned int startData = ((frame[2] << 8) | frame[3]); //写入modbus数据库的地址
                unsigned int setData = ((frame[4] << 8) | frame[5]); //写入modbus数据库的数值
             
                if (startData >= modbusDataSize)
                {
                  errorFlag = 1;
                  //待添加错误信息返回函数
                }
                else
                {
                  modbusData[startData] = setData; //写入数据到modbus数据库
                  frame[0] = slaveID; //设定站号
                  frame[1] = function; //设定功能码
                  frame[2] = startData >> 8;  //填写数据库地址
                  frame[3] = startData & 0xFF;
                  frame[4] = modbusData[startData] >> 8;  //填写数据库数值
                  frame[5] = modbusData[startData] & 0xFF;
                  crc16 = calculateCRC(&frame[0], 6); //计算校验值
                  frame[6] = crc16 >> 8;  //填写校验位
                  frame[7] = crc16 & 0xFF;
                  Serial.write(&frame[0], 8); //返回功能码06的消息
                }
              }
              else if (function == 16) //功能码为16时进入条件
              {
                if (frame[6] != address - 9) //校验数据长度
                {
                }
                else  //校验数据长度正确
                {
                  unsigned int startData = ((frame[2] << 8) | frame[3]); //写入modbus数据库起始地址
                  unsigned int dataSize = ((frame[4] << 8) | frame[5]); //需要写入的modbus数据库数据长度
                  unsigned int endData = startData + dataSize; //需要写入的modbus数据库数据的结束地址
                  unsigned int temp1, temp2;
                  temp2 = 7; //从数据贞的第8个数据开始读取
                  for (temp1 = startData; temp1 < endData; temp1++)
                  {
                    if (temp1 >= modbusDataSize) //需要写入的地址大于modbus数据库的最大地址
                    {
                      //待添加错误信息返回函数
                    }
                    else  //将数据写入modbus数据库中
                    {
                      modbusData[temp1] = (frame[temp2] << 8 | frame[temp2 + 1]);
                      temp2 += 2;
                    }
                  }
                  frame[0] = slaveID; //填写站号,frame[1]到frame[5]不变
                  crc16 = calculateCRC(&frame[0], 6); //计算CRC校验
                  frame[6] = crc16 >> 8;  //填写校验位
                  frame[7] = crc16 & 0xFF;
                  Serial.write(&frame[0], 8); //发送功能码16的应答数据
                }
              }
            }
          }
        }
      }
    }




    //CRC校验函数
    //参数1:待校验数组的起始地址
    //参数2:待校验数组的长度
    //返回值CRC校验结果,16位,低字节在前
    unsigned int calculateCRC(unsigned char* _regs, unsigned char arraySize)
    {
      unsigned int temp, temp2, flag;
      temp = 0xFFFF;
      for (unsigned char i = 0; i < arraySize; i++)
      {
        temp = temp ^ *(_regs + i);
        for (unsigned char j = 1; j <= 8; j++)
        {
          flag = temp & 0x0001;
          temp >>= 1;
          if (flag)
            temp ^= 0xA001;
        }
      }
      temp2 = temp >> 8;
      temp = (temp << 8) | temp2;
      temp &= 0xFFFF;
      return temp;
    }

    点评

    没用过这个库,不知道是啥  详情 回复 发表于 2017-6-14 15:38
  • TA的每日心情
    郁闷
    2018-12-6 22:21
  • 签到天数: 48 天

    [LV.5]常住居民I

     楼主| 发表于 2017-6-14 15:38 | 显示全部楼层
    0521 发表于 2017-6-14 13:30
    奈何! 请问假如我要用modbus RTU这个程序控制一个LED灯 接下来该怎么写?

    #define bufferSize 255  //一 ...

    没用过这个库,不知道是啥
    如果以上内容对你有帮助,你可以通过打赏支持作者

    该用户从未签到

    发表于 2017-7-14 19:58 | 显示全部楼层
    奈何col 发表于 2017-6-3 20:02
    有问题可以直接论坛或者QQ群交流

    qq群是多少嘞

    点评

    网站首页,右侧  详情 回复 发表于 2017-7-14 21:24
    您需要登录后才可以回帖 登录 | 立即注册  

    本版积分规则

    热门推荐

    如何用Arduino制作一支带逗比功能的笔
    如何用Arduino制作一支带
    一年一度的六一儿童节又到啦(划掉)过完啦,这年头谁还不是个宝宝!各位超龄儿童有没
    设计了一款智能加湿器,出现了一些控制上的问题
    设计了一款智能加湿器,出
    最近在学习blinker,就想着把手头的加湿器改装成智能加湿器,用了一块WiFiduino、一个
    esp上传代码失败
    esp上传代码失败
    #include #include const char* ssid = "E206"; const char* password = "20620620
    小白求助
    小白求助
    小白刚接触arduino编程基础较差,发现可以使用图形编程软件,想问一下图片上的是什么
    Arduino MEGA 与UNO 通过nRF24L模块通讯
    Arduino MEGA 与UNO 通过n
    之前在深水宝很“实惠”的店铺买了一些原件,随手砍了esp8266以及nRF24L*3 因为缺
    Copyright   ©2015-2016  Arduino中文社区  Powered by©Discuz!   ( 蜀ICP备14017632号-3 )
    快速回复 返回顶部 返回列表