搜尋程式碼

第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接線:伺服摩打加電位器
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設為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] 調整伺服馬達響應速度

圖片

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
}
 

你可能需要嘅嘢

資源與參考資料

文件📁

其他文件