当前位置: 首页 > article >正文

Arduino 多舵机控制:状态机实现多舵机同步动作

引言

在 Arduino 的项目开发中,舵机作为一种常见的执行器,广泛应用于机器人、自动化设备等领域。当需要同时控制多个舵机并实现复杂的动作序列时,合理的编程逻辑至关重要。本文将围绕一段使用状态机来控制多个舵机的 Arduino 代码展开,深入分析其原理、功能以及实际应用价值。

代码整体架构与功能概述

上述代码旨在使用 Arduino 控制 3 个舵机(通过 #define num 3 定义),并通过状态机的方式让它们能够同时动作。代码中定义了多个关键变量,如 myServo 数组用于管理舵机对象,targetAngles 数组存储每个舵机的目标角度,currentAngles 数组记录当前角度,state 变量表示当前状态,以及与时间控制相关的 lastUpdateTimeupdateInterval

setup 函数中,完成了舵机的初始化连接,并将每个舵机的当前角度初始化为 0。而 loop 函数则是整个代码的核心,通过状态机的 switch 语句,在不同状态之间切换,实现对舵机角度的更新和控制。

代码详细解析

  1. 变量定义与初始化
#include <Servo.h>
#define num 3
Servo myServo[num];
int targetAngles[num];  
int currentAngles[num]; 
int state = 0;          
unsigned long lastUpdateTime = 0; 
const unsigned long updateInterval = 10; 
- `#include <Servo.h>` 引入舵机控制库,为后续操作舵机提供函数支持。
- `#define num 3` 定义舵机的数量为 3 个。
- `Servo myServo[num];` 创建一个包含 3 个 `Servo` 对象的数组,用于管理 3 个舵机。
- `targetAngles` 和 `currentAngles` 数组分别用于存储每个舵机的目标角度和当前角度。
- `state` 变量用于表示当前状态机的状态,初始化为 0。
- `lastUpdateTime` 记录上次更新舵机角度的时间,初始化为 0。
- `updateInterval` 定义了更新舵机角度的时间间隔,这里设置为 10 毫秒。
  1. setup 函数
void setup() {
  // 初始化舵机连接
  for(int i = 0; i < num; i++){
    myServo[i].attach(i + 22);
    currentAngles[i] = 0;
  }
}

setup 函数中,通过 for 循环将每个舵机对象连接到 Arduino 的 22 到 24 引脚(i + 22),并将每个舵机的当前角度初始化为 0。

  1. loop 函数
void loop() {
  unsigned long currentTime = millis();

  if (currentTime - lastUpdateTime >= updateInterval) {
    lastUpdateTime = currentTime;

    switch (state) {
      case 0:
        // 随机设置每个舵机的目标角度
        for (int i = 0; i < num; i++) {
          targetAngles[i] = random(0, 181);
        }
        state = 1;
        break;
      case 1:
        // 更新舵机角度
        bool allReached = true;
        for (int i = 0; i < num; i++) {
          if (currentAngles[i] < targetAngles[i]) {
            currentAngles[i]++;
            allReached = false;
          } else if (currentAngles[i] > targetAngles[i]) {
            currentAngles[i]--;
            allReached = false;
          }
          myServo[i].write(currentAngles[i]);
        }
        if (allReached) {
          state = 0;
        }
        break;
    }
  }
}
- 首先获取当前时间 `currentTime = millis();`,并与 `lastUpdateTime` 比较,当时间间隔达到 `updateInterval`(10 毫秒)时,执行后续操作。
- **状态 0**:在状态 0 中,通过 `for` 循环为每个舵机随机设置一个 0 到 180 之间的目标角度,然后将状态切换为 1。
- **状态 1**:在状态 1 中,通过 `for` 循环遍历每个舵机。如果当前角度小于目标角度,则将当前角度加 1;如果当前角度大于目标角度,则将当前角度减 1。同时,将 `allReached` 标志设置为 `false`,表示有舵机还未到达目标角度。每次更新角度后,使用 `myServo[i].write(currentAngles[i]);` 来控制舵机转动到新的角度。当所有舵机都到达目标角度时(`allReached` 为 `true`),将状态切换回 0,重新开始设置新的目标角度。

实际应用场景与拓展

  1. 机器人动作控制:可以应用于小型机器人的关节控制,让多个舵机协同工作,实现机器人的各种动作,如行走、转弯、抓取物体等。
  2. 自动化设备:在自动化设备中,如智能窗帘系统,多个舵机可以同时控制窗帘的开合程度,实现更精准的控制。
  3. 拓展方向:可以进一步扩展代码,添加传感器输入,根据传感器的数据来动态调整舵机的目标角度;或者与无线通信模块结合,实现远程控制舵机的动作。

总结

通过状态机的方式来控制多个舵机,能够有效地实现舵机的同步动作,避免了使用 delay 函数带来的阻塞问题,提高了程序的实时性和响应性。本文的代码示例为 Arduino 舵机控制提供了一个良好的基础框架,开发者可以根据具体需求进行修改和扩展,创造出更加复杂和有趣的项目。希望本文能对大家在 Arduino 舵机控制的学习和实践中有所帮助。


http://www.kler.cn/a/543695.html

相关文章:

  • 栈的简单介绍
  • VSCode中出现“#include错误,请更新includePath“问题,解决方法
  • Java网络编程入门
  • 131,【2】 攻防世界 catcat-new
  • SpringBoot中的Javaconfig
  • 【CXX-Qt】1 CXX-Qt入门
  • 2.1 统计语言模型:AI自然语言处理的奠基者与演进启示录
  • java项目之基于web的中国古诗词的设计与实现源码(ssm+mysql)
  • npm无法加载文件 因为此系统禁止运行脚本
  • 网络安全总结
  • C#的DataTable类精简汇总
  • Mysql8.0使用PXC
  • Docker 容器基础:创建、运行、管理
  • python的selenium库模拟输入和点击
  • c++ 多线程知识汇总
  • JavaScript系列(71)--函数式编程进阶详解
  • CEF132编译指南 MacOS 篇 - 获取 CEF 源码 (五)
  • flutter 打包mac应用并安装过程
  • 《手札·行业篇》开源Odoo MES系统与SKF Observer Phoenix API在化工行业的双向对接方案
  • Deepseek 671B + Milvus 搭建个人知识库
  • 华为云的分布式缓存服务适合什么场景
  • 单片机简介
  • 不到一个月,SQLite 3.49.0来了
  • 【分布式理论8】分布式调用之:四种IO模型
  • 记一次Self XSS+CSRF组合利用
  • 【算法学习】蓝耘云智算|利用DeepSeek R1模型提升数据结构与算法学习效率