搜索代码

第86课:使用电位器控制伺服电机的位置

第86课:使用电位器控制伺服电机的位置

想象一下,转动一个简单的旋钮,就能看到机械臂精确地跟随你的每一个动作。这就是将电位器与舵机结合的神奇之处。这个项目是Robojax推出的Arduino逐步学习课程的一部分,演示了电子学中一个基础且极其有用的概念:将模拟输入转换为精确的物理运动。你将学习如何读取电位器产生的可变电压,将该值映射到一定角度范围,并命令舵机旋转到精确位置。这是你构建直观且交互式项目(手动控制与自动化相结合)的入门途径。

这项技能的应用广泛且实用。以下是一些想法,供你参考并激发灵感:

  • 机械臂控制:使用电位器手动定位机械臂的每个关节,实现精确的取放操作。
  • 摄像头云台系统:构建一个远程控制的摄像头支架,用于延时摄影或监控,通过旋转拨盘实现平滑的平移和倾斜。
  • 模拟仪表复制:创建一个物理仪表盘(如速度表或温度表),根据传感器数据移动,电位器可作为手动覆盖或校准工具。
  • 互动艺术装置:创建响应观众输入的动态雕塑,转动拨盘即可改变运动部件的位置。
  • 模型车转向控制:远程控制模型车或船的转向角度,提供比数字按钮更直观、更模拟的操控体验。

本指南基于Robojax的视频教程第86课:使用电位器控制舵机位置(视频中00:00处)。它将引导你完成整个过程,从理解接线到解释使其工作的代码。让我们开始吧。

硬件与组件

要跟随本项目操作,你需要以下组件:

  • 一块Arduino开发板(例如Uno、Nano)
  • 一个标准舵机(例如SG90或MG996R)
  • 一个电位器(可变电阻,通常为10kΩ)
  • 跳线
  • 面包板(可选,便于连接)

理解接线

本项目的接线很简单。关键是为舵机和电位器提供正确的电源和信号连接。舵机是功耗较高的设备,因此它直接从Arduino的5V引脚获取电源。电位器充当分压器,我们读取其滑臂(中间引脚)上的电压来确定其位置。(视频中01:05处)

本项目使用的一个巧妙技巧是在数字引脚上创建额外的5V电源来为电位器供电,因为某些Arduino板只有一个专用的5V引脚。这通过在代码中将数字引脚(引脚8)设置为HIGH来实现,该引脚会输出5V。(视频中00:39处)

以下是视频中提到的接线图:

Arduino wiring or servo motor with pot
Arduino接线:舵机与电位器

让我们分解一下连接:

  • 舵机:
    • 电源(红线)→ Arduino 5V引脚
    • 地线(棕/黑线)→ Arduino GND引脚
    • 信号线(橙/黄线)→ Arduino引脚3(支持PWM的引脚)
  • 电位器:
    • 左侧引脚→ Arduino GND引脚
    • 中间引脚(滑臂)→ Arduino模拟引脚A0
    • 右侧引脚→ Arduino引脚8(在代码中定义为VCC2)

代码解释

本项目的代码非常简洁。它利用了几个关键的Arduino函数来读取电位器并控制舵机。让我们重点关注你可以根据自己的项目进行调整的用户可配置部分。(视频中03:00处)

在代码顶部,你将定义引脚并创建舵机对象。这些是你根据接线情况需要更改的主要变量:

#include <Servo.h>

Servo myservo;  // 创建舵机对象以控制舵机

int potpin = A0;  // 用于连接电位器的模拟引脚
int servoPin = 3; // 定义舵机的数字引脚(带PWM)。只能使用引脚3、5、6、9、10、11
int VCC2 = 8;// 为电位器定义额外的VCC
int val;    // 用于读取模拟引脚值的变量

以下是各部分的作用:

  • Servo myservo;:此行创建一个名为myservo的对象,我们将使用它来控制特定的舵机。你可以重命名它,但必须在代码后面使用相同的名称。
  • int potpin = A0;:这定义了电位器滑臂连接的模拟引脚。如果将线移到不同的模拟引脚,必须更新此编号。
  • int servoPin = 3;:这设置了舵机信号线的数字引脚。使用支持PWM的引脚(通常是板上标有'~'的引脚)至关重要。注释列出了大多数Arduino板的有效引脚。
  • int VCC2 = 8;:这是我们用作电位器辅助5V电源的引脚。如果你的板有多个5V引脚,可以直接连接并删除这部分代码。

setup()函数中,代码初始化了舵机并设置了额外的电源引脚。myservo.attach(servoPin)函数至关重要,因为它告诉Arduino哪个引脚连接到了舵机的信号线。

void setup() {
  Serial.begin(9600);          //  设置串口
  myservo.attach(servoPin);  // 将舵机连接到引脚3上的舵机对象

  pinMode(VCC2, OUTPUT);// 将引脚8设置为输出
  digitalWrite(VCC2, HIGH);// 将引脚8设为高电平,使其充当5V引脚
}

核心逻辑在loop()函数中。它读取电位器的值,将其缩放为角度,并命令舵机移动。这里两个关键函数是analogRead()map()。(视频中04:27处)

void loop() {
  val = analogRead(potpin);            // 读取电位器的值(介于0和1023之间)
  val = map(val, 0, 1023, 0, 180);     // 缩放以用于舵机(介于0和180之间)
  myservo.write(val);                  // 根据缩放后的值设置舵机位置
  Serial.print(val);
  Serial.println();
  delay(50);                           // 等待舵机到达目标位置
}

工作原理如下:

  • analogRead(potpin):此函数读取电位器滑臂上的电压,并返回介于0(0V)和1023(5V)之间的值。
  • map(val, 0, 1023, 0, 180):这是整个项目的关键。它将电位器的原始值(0到1023)按比例转换为舵机角度(0到180度)。例如,如果电位器读数为511(大约一半),map()函数将返回90,使舵机移动到其中心位置。
  • myservo.write(val):此函数接收计算出的角度(现在存储在val中),并告诉舵机旋转到该位置。
  • delay(50):这在每次循环结束时添加一个小暂停。它控制更新速率。较大的延迟(如200毫秒)会使舵机逐步移动,而较小的延迟(如50毫秒)会使运动非常平滑。您可以调整此值来改变响应速度。(视频中07:26处)

项目现场演示

在视频中,您可以看到项目的实际运行情况。当电位器旋钮转动时,舵机电机的手臂会按比例跟随其位置。串口监视器打印当前角度,确认映射工作正常。当电位器处于最小位置时,舵机位于0度。当您将旋钮转到最大位置时,舵机会平滑旋转到180度。(视频中06:33处)

这种实时反馈回路展示了模拟传感器与数字执行器的无缝集成,创建了一个响应迅速且直观的控制系统。

章节

  • [00:00] 介绍与项目概述
  • [01:05] 原理图与接线图
  • [02:07] 物理接线演示
  • [03:00] 代码解释
  • [06:33] 现场演示与测试
  • [07:26] 调整舵机响应速度

图像

Arduino wiring or servo motor with pot
Arduino wiring or servo motor with pot
SG90_servo_motor-1
SG90_servo_motor-1
SG90_servo_motor-0
SG90_servo_motor-0
892-Lesson 86: Controlling a servo position using a potentiometer (variable resistor)
语言: C++
/*
 * Lesson 88: Controlling Servo motor a with Potentiometer
 * 📚⬇️ Download and resource page https://robojax.com/RJT763
 watch full video tutroial: https://www.youtube.com/watch?v=ntRW77mNFFk
 
 Controlling a servo position using a potentiometer (variable resistor)
 by Michal Rinott <http://people.interaction-ivrea.it/m.rinott>

 modified on 8 Nov 2013
 by Scott Fitzgerald
 http://www.arduino.cc/en/Tutorial/Knob

 Update by Ahmad Shamshiri on Jan 01, 2019  in Ajax, Ontario, Canada


*/

#include <Servo.h>

Servo myservo;  // create servo object to control a servo

int potpin = A0;  // analog pin used to connect the potentiometer
int servoPin = 3; // define a digital pin (with PWM) for servo. Can use only pin 3, 5, 6,9, 10, 11
int VCC2 = 8;// define extra VCC for potentiometer
int val;    // variable to read the value from the analog pin

void setup() {
  //
  Serial.begin(9600);          //  setup serial
  myservo.attach(servoPin);  // attaches the servo on pin 3 to the servo object

  pinMode(VCC2, OUTPUT);// set pin 8 as output
  digitalWrite(VCC2, HIGH);// set pin 8 HIGH so it acts as 5V pin
}

void loop() {
  
  val = analogRead(potpin);            // reads the value of the potentiometer (value between 0 and 1023)
  val = map(val, 0, 1023, 0, 180);     // scale it to use it with the servo (value between 0 and 180)
  myservo.write(val);                  // sets the servo position according to the scaled value
  Serial.print(val);
  Serial.println();
  delay(50);                           // waits for the servo to get there
}
 

|||您可能需要的东西

文件📁

其他文件