第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 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] 调整舵机响应速度
/*
* 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
}
|||您可能需要的东西
-
亚马逊
-
亚马逊
-
易趣
-
全球速卖通从AliExpress购买SG90伺服电机180或360。s.click.aliexpress.com
文件📁
其他文件
-
SG90 Seroo 电机数据表
robojax-servo-SG90_datasheet.pdf0.12 MB