添加Servo代码后小车仅单轮工作的故障排查求助
我给小车写的代码原本包含go_forward()、go_backward()、turn_left()、turn_right()、stop()这些基础功能,在loop()里运行一切正常。但添加了一段舵机相关代码后,小车就只剩单个轮子能正常工作了。
添加的舵机代码如下:
#include <Servo.h> Servo servo = Servo(); void setup() { servo.attach(A5); }
我已经试过更换attach的引脚(比如PWM数字引脚3),也仔细检查过接线确认没问题,但问题还是存在。完整代码如下:
#include <Servo.h> Servo servo = Servo(); int EnA = 3; int In1 = 4; int In2 = 5; int EnB = 9; int In3 = 12; int In4 = 13; void setup() { servo.attach(A5); //turn moter A pinMode(EnA, OUTPUT); pinMode(In1, OUTPUT); pinMode(In2, OUTPUT); //turn moter B pinMode(EnB, OUTPUT); pinMode(In3, OUTPUT); pinMode(In4, OUTPUT); analogWrite(EnA, 150); //lowest - 100 highest - 200 analogWrite(EnB, 150); //servo.write(150); //Serial.begin(9600); } void loop() { // In1 -> HIGH & In2 -> LOW ---- backward go_forward(); //char c = Serial.read(); //Serial.println(c); //delay(1000); //if (c == '1'){ // digitalWrite(13, HIGH); //} //if (c == '2'){ // digitalWrite(13, LOW); //} } void go_forward(){ // In1 -> HIGH & In2 -> LOW ---- backward digitalWrite(In1, HIGH); digitalWrite(In2, LOW); digitalWrite(In3, LOW); digitalWrite(In4, HIGH); } void go_backward(){ // In1 -> HIGH & In2 -> LOW ---- backward digitalWrite(In1, LOW); digitalWrite(In2, HIGH); digitalWrite(In3, HIGH); digitalWrite(In4, LOW); } void stop(){ // In1 -> HIGH & In2 -> LOW ---- backward digitalWrite(In1, LOW); digitalWrite(In2, LOW); digitalWrite(In3, LOW); digitalWrite(In4, LOW); } void turn_left(){ // In1 -> HIGH & In2 -> LOW ---- backward digitalWrite(In1, LOW); digitalWrite(In2, HIGH); digitalWrite(In3, LOW); digitalWrite(In4, HIGH); } void turn_right(){ // In1 -> HIGH & In2 -> LOW ---- backward digitalWrite(In1, HIGH); digitalWrite(In2, LOW); digitalWrite(In3, HIGH); digitalWrite(In4,LOW); }
问题根源
Arduino的Servo库会占用定时器资源,而你用来控制电机速度的analogWrite()同样依赖定时器。比如Uno/Nano这类基于ATmega328P的板子,定时器0负责引脚3、5、6的PWM输出,定时器1负责引脚9、10、11的PWM输出,Servo库默认会占用定时器1。你的EnB引脚是9,正好依赖定时器1,被Servo库占用后,这路电机的PWM输出直接失效,导致对应轮子转不起来。
解决步骤
避开冲突引脚:
把舵机接到不占用电机PWM定时器的引脚,比如数字引脚2、4、7、8、12、13,这些引脚要么不依赖被Servo库占用的定时器,要么本身无PWM功能不会冲突。比如把servo.attach(A5)改成servo.attach(7),测试是否恢复正常。换用不冲突的舵机库:
安装ServoTimer2库,这个库占用定时器2,不会和控制电机的定时器0/1冲突,替换原有的#include <Servo.h>为#include <ServoTimer2.h>即可,用法和原Servo库一致。手动模拟舵机信号(无库方案):
要是不想用库,直接用digitalWrite()和delayMicroseconds()模拟舵机需要的周期信号,完全不占用定时器:// 自定义舵机控制函数,pin为舵机引脚,angle为0-180度 void setServo(int pin, int angle) { int pulseWidth = map(angle, 0, 180, 500, 2500); // 把角度转换成500-2500us的脉冲宽度 digitalWrite(pin, HIGH); delayMicroseconds(pulseWidth); digitalWrite(pin, LOW); delay(20); // 舵机需要20ms的信号周期 }在
setup()里把舵机引脚设为OUTPUT,之后直接调用这个函数控制舵机就行。检查电源供电:
舵机启动时会瞬间拉取较大电流,若电源容量不足,会导致电机供电压降过大无法正常工作。给舵机单独接电源(注意共地),或者更换更大容量的电池,确保总输出电流能同时驱动电机和舵机。
内容的提问来源于stack exchange,提问作者kavindu udhara

