MATLAB+Arduino控制小车直行+转向
1 硬件
两轮车+arduino板子
硬件连接
注意:电机连线。
这个小车的电机电流小,可以用arduino板子直接驱动,如果是大电流的,需要你自带电池,供电用用你的电池(如移动电源),控制信号,PWM接arduino的pwm口。
端口分配:
D10: 左轮 PWM
D11:右轮PWM
2 servo信号校正
按理0.5V应该是电机停止命令,但我的小车不标准。
用资源管理器调整
左右轮的零点分别你是0.55 和0.51. 所以发中位时,需要用实际的0点值。
其次:两个电机的方向还需要注意。如 左轮为顺时针,右轮为逆时针。
轮 | 顺时针 | 逆时针 |
左轮 | >0.55 | <0.55 |
右轮 | <0.51 | >0.51 |
在 MATLAB 中控制 Arduino 板的伺服电机(Servo Motor)是通过 MATLAB 的 Arduino
支持包实现的。
控制原理
-
伺服电机:
-
伺服电机是一种可以精确控制角度的电机,通常角度范围为 0° 到 180°。
-
通过 PWM(脉宽调制)信号控制伺服电机的位置,PWM 信号的占空比决定了电机的角度。
-
-
Arduino 控制伺服电机:
-
Arduino 通过数字引脚输出 PWM 信号来控制伺服电机。
-
MATLAB 通过
Arduino
支持包与 Arduino 通信,发送控制命令。
-
-
MATLAB 控制原理:
-
MATLAB 通过串口与 Arduino 通信,发送指令来控制伺服电机。
-
MATLAB 的
servo
函数封装了底层 PWM 信号生成的细节,用户只需指定角度即可。
-
MATLAB 函数
以下是 MATLAB 中用于控制伺服电机的主要函数:
-
servo
:-
创建一个伺服电机对象。
-
语法:
s = servo(a, pin)
-
a
:Arduino 对象。 -
pin
:伺服电机连接的引脚(例如'D9'
)。
-
-
-
writePosition
:-
设置伺服电机的位置(角度)。
-
语法:
writePosition(s, position)
-
s
:伺服电机对象。 -
position
:目标位置,范围为[0, 1]
,对应0°
到180°
。
-
-
-
readPosition
:-
读取伺服电机的当前位置。
-
语法:
position = readPosition(s)
-
s
:伺服电机对象。 -
position
:当前位置,范围为[0, 1]
。
-
-
-
clear
:-
清理伺服电机对象。
-
语法:
clear s
-
% MATLAB 代码:控制伺服电机
% 创建 Arduino 对象
a = arduino('COM3', 'Uno'); % 根据实际情况修改 COM 端口
% 创建伺服电机对象
s = servo(a, 'D9'); % 伺服电机连接到 D9
% 主循环
disp('控制伺服电机:');
disp('输入角度(0-180),或输入 q 退出');
try
while true
% 获取用户输入
command = input('请输入角度(0-180):', 's');
% 退出条件
if strcmpi(command, 'q')
break;
end
% 将输入转换为角度
angle = str2double(command);
if isnan(angle) || angle < 0 || angle > 180
disp('无效输入,请输入 0-180 之间的角度');
continue;
end
% 设置伺服电机位置
position = angle / 180; % 将角度转换为 [0, 1] 范围
writePosition(s, position);
% 读取当前角度
currentPosition = readPosition(s);
currentAngle = currentPosition * 180;
fprintf('当前角度:%.1f°\n', currentAngle);
end
catch
% 清理
clear s;
clear a;
disp('程序结束');
end
3 小车行走控制代码
用键盘来选择前进后退。
由于两个轮子是相对安装的,给同一个增量值时,它们的转向是反向的。因此,我们需要在代码中对左右电机的增量值进行反向处理。
具体代码如下:
% MATLAB 代码:控制小车行驶
clear
% 创建 Arduino 对象
a = arduino('COM5', 'Uno'); % 根据实际情况修改 COM 端口
% 定义电机零转速
leftMotorZero = 0.55; % 左电机零转速
rightMotorZero = 0.51; % 右电机零转速
% 创建伺服电机对象(用于生成 PWM 信号)
leftMotor = servo(a, 'D10'); % 左电机连接到 D10
rightMotor = servo(a, 'D11'); % 右电机连接到 D11
% 初始化电机速度
writePosition(leftMotor, leftMotorZero); % 左电机停止
writePosition(rightMotor, rightMotorZero); % 右电机停止
% 主循环
disp('控制小车行驶:');
disp('1 - 前进');
disp('2 - 后退');
disp('3 - 左转');
disp('4 - 右转');
disp('0 - 停止');
disp('q - 退出');
try
while true
% 获取用户输入
command = input('请输入命令:', 's');
% 根据命令控制小车
switch command
case '1' % 前进
% 左电机正转,右电机正转(增量值反向)
writePosition(leftMotor, leftMotorZero + 0.1); % 左电机正转
writePosition(rightMotor, rightMotorZero - 0.1); % 右电机正转
disp('小车前进');
case '2' % 后退
% 左电机反转,右电机反转(增量值反向)
writePosition(leftMotor, leftMotorZero - 0.1); % 左电机反转
writePosition(rightMotor, rightMotorZero + 0.1); % 右电机反转
disp('小车后退');
case '3' % 左转
% 左电机反转,右电机正转(增量值反向)
writePosition(leftMotor, leftMotorZero - 0.1); % 左电机反转
writePosition(rightMotor, rightMotorZero - 0.1); % 右电机正转
disp('小车左转');
case '4' % 右转
% 左电机正转,右电机反转(增量值反向)
writePosition(leftMotor, leftMotorZero + 0.1); % 左电机正转
writePosition(rightMotor, rightMotorZero + 0.1); % 右电机反转
disp('小车右转');
case '0' % 停止
writePosition(leftMotor, leftMotorZero); % 左电机停止
writePosition(rightMotor, rightMotorZero); % 右电机停止
disp('小车停止');
case 'q' % 退出
break;
otherwise
disp('无效命令');
end
end
catch
% 清理
writePosition(leftMotor, leftMotorZero); % 左电机停止
writePosition(rightMotor, rightMotorZero); % 右电机停止
clear leftMotor rightMotor a;
disp('程序结束');
end
结果
能按照要求做基本的控制,只是没有做运动学关系的控制,因为我的小车没有速度反馈。
把小车立起来调试,结果表明可以实现小车前进后退和转向控制。实际使用时,可以在电机输出部分做一个斜坡,避免速度突变。