MATLAB+Arduino控制小车直行+转向

发布于:2025-03-24 ⋅ 阅读:(33) ⋅ 点赞:(0)

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 支持包实现的。

控制原理

  1. 伺服电机

    • 伺服电机是一种可以精确控制角度的电机,通常角度范围为 0° 到 180°。

    • 通过 PWM(脉宽调制)信号控制伺服电机的位置,PWM 信号的占空比决定了电机的角度。

  2. Arduino 控制伺服电机

    • Arduino 通过数字引脚输出 PWM 信号来控制伺服电机。

    • MATLAB 通过 Arduino 支持包与 Arduino 通信,发送控制命令。

  3. MATLAB 控制原理

    • MATLAB 通过串口与 Arduino 通信,发送指令来控制伺服电机。

    • MATLAB 的 servo 函数封装了底层 PWM 信号生成的细节,用户只需指定角度即可。

MATLAB 函数

以下是 MATLAB 中用于控制伺服电机的主要函数:

  1. servo

    • 创建一个伺服电机对象。

    • 语法:s = servo(a, pin)

      • a:Arduino 对象。

      • pin:伺服电机连接的引脚(例如 'D9')。

  2. writePosition

    • 设置伺服电机的位置(角度)。

    • 语法:writePosition(s, position)

      • s:伺服电机对象。

      • position:目标位置,范围为 [0, 1],对应  到 180°

  3. readPosition

    • 读取伺服电机的当前位置。

    • 语法:position = readPosition(s)

      • s:伺服电机对象。

      • position:当前位置,范围为 [0, 1]

  4. 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

结果

能按照要求做基本的控制,只是没有做运动学关系的控制,因为我的小车没有速度反馈。

把小车立起来调试,结果表明可以实现小车前进后退和转向控制。实际使用时,可以在电机输出部分做一个斜坡,避免速度突变。


网站公告

今日签到

点亮在社区的每一天
去签到