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

控制原理

  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

结果

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

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

相关推荐
布伦鸽1 小时前
C# Modbus TCP/IP学习记录
开发语言·学习·c#
Jack电子实验室1 小时前
STM32实现智能温控系统(暖手宝):PID 算法 + DS18B20+OLED 显示,[学习 PID 优质项目]
stm32·学习·算法
程序员Linc2 小时前
《数字图像处理》第三章 3.8 基于模糊技术的图像强度变换与空间滤波学习笔记
笔记·学习·数字图像处理·模糊技术·强度变换·空间滤波
张张张3122 小时前
3.25学习总结 抽象类和抽象方法+接口+内部类+API
java·学习
viperrrrrrrrrr72 小时前
大数据学习(88)-zookeeper实现的高可用(HA)
大数据·学习·zookeeper
亭午3 小时前
pyspark学习rdd处理数据方法——学习记录
学习
promising-w4 小时前
【TI MSPM0】PWM学习
单片机·学习·ti 单片机
Wallace Zhang5 小时前
STM32F103_LL库+寄存器学习笔记02 - 开启SysTick(滴答定时器)中断
笔记·stm32·学习
背影疾风6 小时前
C++学习之路:从头搞懂配置VScode开发环境的逻辑与步骤
c++·vscode·学习