第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設為HIGH,令佢當作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
}
你可能需要嘅嘢
-
亞馬遜
-
亞馬遜
-
易贝
-
阿里巴巴速卖通Purchase SG90 servo motor 180 or 360 from AliExpresss.click.aliexpress.com
資源與參考資料
文件📁
其他文件
-
SG90 Seroo 馬達數據表
robojax-servo-SG90_datasheet.pdf0.12 MB