【新手向】总线舵机使用教程


说在前面:
如果你看到/想要购买如图所示的舵机,那么恭喜你可以看这篇帖子来跟我一起使(cai)用(keng)了 :partying_face:

一些总线舵机的优点:

  1. 只需要一根总线就可以连接所有总线舵机,大大减少了接线时的麻烦,同时对于连接结构的灵活性也得到了提升(不会被很多线卡住,,)而且写代码的时候不用在意哪个口接哪个(x2.
  2. 扭力相对pwm舵机较大,市面上有15,20,30,45kg等可供选择

亿些缺点:

  1. 贵。一个总线舵机是50-100+不等,而一个SG90舵机大约是7元
  2. 控制必须要使用格式恒定的字符串指令,在需要多次输入时在交互方面比较头疼

如果你觉得可以忍受上述缺点,请继续往下看:

一、硬件准备

  1. 一块主控板,我这里用的是arduino uno核心板2.

  2. 一块24路舵机接线板


    *1处为普通舵机接线处,可见满满当当

  3. 一个可以稳定输出5-8.4v直流的电源,总线舵机需要通过电源额外供电,不然直接用电脑供电控制板可能会烧(

二、一些其他准备

  1. 需要安装串口工具(需要的串口工具及代码都附在最后链接
  2. 准备一个arduino
  3. 看一下链接里的总线舵机使用手册,通读一遍

三、代码编写

  1. 调试各个舵机,使其的控制模式、波特率、初始值达到设定的目标,这里我修改官方程序使其便于调整,完整程序见链接,部分代码如下:
/*******全局变量宏定义*******/
#define UART_RECEIVE_BUF_SIZE 100

/*******全局变量定义*******/
u8 i=0;
u8 uart_receive_buf[UART_RECEIVE_BUF_SIZE]={0}, uart_receive_buf_index, uart_get_ok;

void setup(void) {																																																																																																																															//ZL
	setup_led();			//初始化LED信号灯
	setup_uart();			//初始化串口

/**********************************************
	* @总线设备基本控制指令表:
	*	1.	#000PID!						//读取ID指令
	*	2.	#000PID001!						//设置ID指令
	*	3.	#000PVER!						//读取版本
	*	4.	#000PBD1!						//设置波特率 默认115200  1:9600 , 2:19200 , 3:38400 , 4:57600 , 5:115200 , 6:128000 7:256000  8:1000000
	*	5.	#000PCLE!						//恢复出厂设置包括ID
	* @总线舵机ZServo控制指令表:
	*	1.	#000P1500T1000!					//舵机角度控制
	*	2.	#000PDST!						//停止
	*	3.	#000PDPT!						//暂停
	*	4.	#000PDCT!						//继续
	*	5.	#000PCSD!						//设置当前值为开机值
	*	6.	#000PCSM!						//开机释放扭力
	*	7.	#000PRAD!						//读取角度
	*	8.	#000PULK!						//释力
	*	9.	#000PULR!						//恢复扭力
	*	10.	#000PSCK!						//设置当前值为1500的偏差值
	*	11.	#000PSCK+050!					//把1500+50作为1500的中间值
	*	12.	#000PSCK-050!					//把1500-50作为1500的中间值
	*	13.	#000PMOD!						//读取模式
	*	14.	#000PMOD1!						//设置模式 舵机模式:2 270 逆时针 1:270 顺 4 180 逆时针 3:180 顺    马达模式:6 360 逆时针 5:360 顺圈 8 360 逆时针 7:360 顺时
	*	15.	#000PRTV!						//读取电压和温度
	*	16.	#000PSTB!						//读取保护值
	*	17.	#000PSTB=60!					//设置保护值 默认60 范围25-80
	*	18.	#000PPAAAIBBB!					//设置KP = AAA, KI = BBB
	*	19.	#000PMIN!						//设置最小值
	*	20.	#000PMAX!						//设置最大值
	*	21.	#000PULM! 						//释力 不带阻力
	*	22.	#000PLN!						//RGB灯开启
	*	23.	#000PLF!						//RGB灯关闭
 **********************************************/
// uart_send_str((u8 *)"#255PCLE!");  //恢复出厂设置
// uart_send_str((u8 *)"#000PID001!"); //设置ID指令
// uart_send_str((u8 *)"#001PID!");  //读取ID指令
// delay(500);
  
// uart_send_str((u8 *)"#255PBD1!");
// delay(500);

// uart_send_str((u8 *)"#002PMOD4!");  //设置舵机模式
// delay(500);

// uart_send_str((u8 *)"#001PCSD!");  //设置当前值为开机值
// delay(500);

// uart_send_str((u8 *)"#002PSCK!");  //设置当前值为中间值
// delay(500);

// uart_send_str((u8 *)"#001P1500T1000!");
// uart_send_str((u8 *)"#002P1500T1000!");
// uart_send_str((u8 *)"#003P1500T1000!");
// uart_send_str((u8 *)"#004P1500T1000!");
// delay(1500);

}

总之是按需取用(都被我注释掉了可见一斑),踩坑点在于:

(a)控制多个舵机时如果需要控制每个舵机的转动角度,那么需要给它们一个个编号,切记改ID时总线上只能连你想改的那个舵机,使用#255PID001!改动。如果连着多个舵机那么这条指令会让所有ID都变成001

(b)每个舵机在开始设定的中值是一样的,但是由于舵机连着的齿轮有精度差异,可能需要一个一个调试中值,可以看下一个代码

  1. 看到上面那个官方例程就会发现:除了初始化一切控制都很不方便,因为它使用了字符串进行控制,在交互方面会出现许多意想不到的bug,万幸的是还有第二个官方例程,于是我就按照第二个程序的思路进行修改
#include <Servo.h>
#include <SoftwareSerial.h>    //包含软串口头文件,硬串口通信文件库系统自带String uart1_receive_buf = "";
/*******************************一些宏定义****************************************/
SoftwareSerial mySerial(A4,A5); //创建一个软串口的类,模拟引脚4,5分别代表 RX, TX引脚 AR多功能板
Servo myServo;
int angle;
int myId, myPwm, myTime, destination;
char cmd_return[100];//这里的cmd_return的字符长度要足够的大,根据舵机个数定,大小 = 15*个数+10
String inputString = "";  
boolean stringComplete = false;  

void setup() {
    Serial.begin(9600);           //硬件串口
    mySerial.begin(9600);         //设置软串口波特率 <--原装波特率默认为115200,这里是使用initialize修改后的波特率
    Serial.println("请输入舵机ID和角度(格式:ID,角度):");      
}

void loop() {
                
        while (Serial.available()>0) {
        char inChar = (char)Serial.read(); 
        if (inChar == '\n') { 
            stringComplete = true;
        } else {
            inputString += inChar; 
        }
        }

        if (stringComplete){
          int comma_index = inputString.indexOf(',');
          if (comma_index > 0){
            String id_string = inputString.substring(0, comma_index);
            String angle_string = inputString.substring(comma_index + 1); 

            myId = id_string.toInt(); 
            angle = angle_string.toInt(); 

            if (angle >= 40 && angle <= 140) {  

              destination = angle/9.0*100 + 500;
              Serial.print("舵机");
              Serial.print(myId);
              Serial.print("旋转到角度:");
              Serial.println(angle);
              sprintf(cmd_return, "#%03dP%04dT%04d!", myId, destination, 1000);
              Serial.print(cmd_return);
              mySerial.print(cmd_return);

            } else if(angle<40){
                angle = 40;
                destination = angle/9.0*100 + 500;
                sprintf(cmd_return, "#%03dP%04dT%04d!", myId, destination, 1000);
                Serial.print(cmd_return);
                mySerial.print(cmd_return);
            } else {
              angle = 140;
              destination = angle/9.0*100 + 500; //由于我设置的是0-180度范围,而舵机控制是0500-2500,这里是把角度转换为舵机可接受的信号
              sprintf(cmd_return, "#%03dP%04dT%04d!", myId, destination, 1000);
              Serial.print(cmd_return);
              mySerial.print(cmd_return);
            }
          }else{
            Serial.println("输入格式无效,请使用格式:ID,角度");
          }
          inputString = "";
          stringComplete = false;
          Serial.println("请输入舵机ID和角度(格式:ID,角度):");

          while (Serial.available() > 0) { //用于清除串口输入,在没有加这个while循环之前有可能无法进行输入,导致舵机无法驱动
            Serial.read();
          }
        }
}

控制程序到这里就基本结束,除了交互还有一些意想不到的bug:

例如:写完程序已正常运行过,但是没有修改过程序舵机突然不会转了
解决方法:
1.看看舵机接口蓝灯有没有闪烁,如果没有拔掉线重新接上试试。我遇到了上一个灭了不能动下一个灯亮还能动的情况
2.让它休息休息,第二天来保不准能动了,,(真实情况
3.实在解决不了怎么办?call 客服 :sob:

希望对看到这里的你有所帮助 :smiling_face_with_three_hearts:

所需材料链接:GitHub - Chaos1009/Servo: Learning and programming materials for beginners
全部材料链接(有一些已经写好的图形化调试程序):
链接: 百度网盘 请输入提取码 提取码: 5485

1 个赞

后面换一家的舵机使用,基本思路不变,实现方法有些许变化,可参考各厂家提供的例程,这里使用的是幻尔的舵机。

代码也放在github仓库了 :partying_face: