黄工无刷电机学习
直播中

万航渡路

8年用户 1286经验值
擅长:电源/新能源
私信 关注
[问答]

如何使用CAN通讯与RS485通讯去控制电机

CAN通讯与RS485通讯最重要的三个部分是什么?
如何使用CAN通讯与RS485通讯去控制电机?

回帖(1)

任青

2021-10-8 09:35:37
  一.电机
  这个SHABI电机是日本的多摩川伺服电机,型号也是很老的型号,中国的代理都没有见过。
  开始说使用CAN通讯控制电机,让我弄了一个多月,结果这玩意儿用中国的CAN卡根本就不行。
  二.CAN通讯
  开始的CAN通讯其实也学到了一些东西,CAN通讯主要就是对电机的ID号发送信息,最重要的三个部分就是:
  1.电机ID号码,这个通常是可以根据电机自带软件更改的,控制的时候注意以下就好
  2.波特率,这个也很简单,说明书就有
  3.发送的消息,一般情况下就是八个字节,都是十六进制
  调试经验:一般情况下先在WINDOWS下面用CAN卡自带的调试软件调试一下,一般把消息发送出去后会收到绿的消息回来,电机驱动可以后,就能够使用UBUNTU了。由于这个本比电机不会CAN,这里就不说了。
  三.RS485
  RS485跟CAN通讯相差不大,也是上面的三个部分,调这个电机的时候,我把波特率也更改了,虽然这个电机***,不过日本人做的还是很OK的。
  这个也很简单,在UBUNTU 里面先打开串口,
  //定义串口
  string port=“/dev/ttyUSB1”;
  //打开串口的函数
  bool openSerial(const char* port)
  {
  com=modbus_new_rtu(port,19200,‘E’,8,1);
  if(com==nullptr)
  {
  cout《《“wrong modbus parameter.”《《endl;
  return false;
  }
  timeval time_out;
  time_out.tv_sec=0;
  time_out.tv_usec=1000*100;
  // modbus_set_response_timeout(com,time_out.tv_sec,time_out.tv_usec);
  modbus_rtu_set_serial_mode(com,MODBUS_RTU_RS485);
  if(modbus_connect(com)==-1)
  {
  cout《《“Cannot connect modbus at port:”《《port《《endl;
  return false;
  } else
  cout《《“Connected modbus at port:”《《port《《endl;
  return true;
  }
  这些也都比较简单,然后初始化电机,为了防止电机打开后异常,开始就设置成“清除电机警报”。然后就是电机伺服打开-----位置控制模式。
  RS485在UBUNTU中使用的是modbus这个库,因为我的***电脑在CMAKlist里面好像找不到这个库,就直接把库的一些头文件放进了INCLUDE里面了,反正也不影响使用。
  modbus_t* com;//com用于电机速度控制反馈
  ///************电机伺服打开*************//
  void SetModbus(int motor1)
  {
  const uint16_t src[]={0x3};
  const uint16_t clear[]={0x8};
  modbus_set_slave(com,motor1);
  modbus_write_registers(com,startstop,1,clear); //清除报警
  modbus_write_registers(com,startstop,1,src); //电机伺服打开
  }
  ///************电机控制模式*************//
  void controlset(int motor1)
  {
  const uint16_t src[]={0x01};
  modbus_set_slave(com,motor1);
  modbus_write_registers(com,controlmod,1,src); //设置控制模式---位置控制
  const uint16_t acc[]={0x64};
  const uint16_t v[]={0x190};
  modbus_write_registers(com,seta,1,acc); //设置加速度
  modbus_write_registers(com,setv,1,v); //设置定位目标速度
  modbus_write_registers(com,setaa,1,acc); //设置减速度
  cout《《“motor INIT!!!!!!!”《《endl;
  }
  //****************************************************************************************
  ///************电机位置控制*************//
  void movemotor(int motor1,int speed)
  {
  if(speed》0)
  {
  //左转
  uint16_t src[]={0X00};
  uint16_t srcc[]= {(uint16_t)speed};
  cout《《*srcc《《endl;
  modbus_set_slave(com,motor1);
  modbus_write_registers(com,posezero,1,src); // 发出位置指令
  modbus_write_registers(com,posezero1,1,srcc); // 发出位置指令
  }
  else
  {
  //右转&&向后??????
  //如果speed = -100,那么speed = 0XFFFF-speed=65535-100=65435,不知道具体输入到电机是什么情况
  //可以向将一个10进制数输入到srcc里面看看情况。
  speed =-speed;
  speed = 65535-speed;
  uint16_t srrc[]={0XFFFF};
  uint16_t ssrcc[]= {(uint16_t)speed};
  modbus_set_slave(com,motor1);
  modbus_write_registers(com,posezero,1,srrc);
  modbus_write_registers(com,posezero1,1,ssrcc);
  }
  }
  这个里面就是用modbus库的一些函数给电机发送指令,“motor1”里面应该是电机的ID号码,一般为十六进制,modbus_set_slave的意思是设置从站,modbus_write_registers是发送功能消息指令,带有S的应该功能码10,这个可以对多个电机同时发送,不太会用这个函数,所以写了很多次数,看起来有些***。
  另外就是这个电机也比较***,位置控制的时候,不能控制他的加速度和减速度,加速太大的话,直接就自保护了。后面设置成每发送一次电机位置就设置一次速度,就可以了。
  controlturn是使用RS485驱动电机的; serialPort是读取GPS信息的,主要包括坐标和航向角度; controldis是自己写的纯跟踪算法,有基于GPS和视觉的; readCAN是通过CAN进行读写操作的。
1 举报

更多回帖

发帖
×
20
完善资料,
赚取积分