搜尋程式碼

第85課:伺服馬達入門 | Arduino 逐步課程

第85課:伺服馬達入門 | Arduino 逐步課程

呢個項目指南會帶你認識連續旋轉舵機嘅世界,即係所謂嘅360度舵機。同標準舵機唔同,標準舵機會移動到特定角度(好似0到180度),而呢啲摩打會向任何一個方向連續旋轉。咁樣令佢哋好適合用嚟整細型機械人、坦克履帶,或者任何需要簡單又平嘅驅動摩打嘅項目。呢個指南會示範點樣用Arduino同幾個按鈕去控制佢,等你親手控制佢嘅方向同速度。

以下係360度舵機嘅幾個實際應用:

  • 整一部細型兩輪機械人車。
  • 整一個可以無限旋轉嘅雲台相機支架。
  • 驅動一條細型輸送帶或者絞盤。
  • 整一個簡單嘅雷達或者感應器掃描平台。

硬件同零件

做呢個項目,你需要以下零件:

  • Arduino板(例如Uno)
  • 連續旋轉舵機(例如FS90R或者類似型號)
  • 三個按鈕
  • 杜邦線
  • 麵包板(可選,方便接線)

接線指南

呢個項目嘅接線好直接。舵機有三條線:通常啡色(地線)、紅色(電源)、同橙色或者黃色(訊號)。按鈕就用簡單嘅配置接線。

以下係連接嘅詳細說明:

  • 舵機:
    • 啡色線(地線)連去Arduino嘅GND腳。
    • 紅色線(電源)連去Arduino嘅5V腳。
    • 橙色/黃色線(訊號)連去Arduino嘅第9腳。
  • 按鈕:
    • 每個按鈕嘅一邊連去Arduino嘅GND腳。
    • 「逆時針」按鈕嘅另一邊連去第2腳。
    • 「停止」按鈕嘅另一邊連去第3腳。
    • 「順時針」按鈕嘅另一邊連去第4腳。

喺影片入面,作者強調舵機嘅訊號線一定要連去Arduino上支援PWM嘅腳位,通常會用波浪號(~)標記。第9腳就係其中一個。按鈕用咗Arduino內部嘅上拉電阻,咁樣就簡化咗接線,唔使外加電阻(影片07:02位置)。

程式碼解釋

呢段程式碼嘅設計係讀取三個按鈕嘅狀態,然後將相應嘅指令傳去舵機。等我哋拆解吓用戶可以設定嘅部分。

設定腳位同指令

喺程式碼最頂部,你會見到腳位同舵機控制值嘅定義。呢度就係你可以自訂項目行為嘅地方。


const int servoPin = 9;    // 舵機訊號嘅PWM腳
const int stopPin = 3;     // 停止按鈕嘅腳
const int cwPin = 4;       // 順時針按鈕嘅腳
const int ccwPin = 2;      // 逆時針按鈕嘅腳

呢啲常數定義咗邊啲Arduino腳連去按鈕同舵機。如果你用唔同嘅腳位嚟接按鈕,就要改呢度嘅數字。servoPin一定要係支援PWM嘅腳位。


const int csServoCommand[3] = {106, 52, 0};  // {逆時針, 停止, 順時針}
const String csServoCommandText[3] = {"逆時針", "已停止", "順時針"};

呢個係最需要理解同調整嘅部分。csServoCommand陣列儲住傳去舵機嘅數值。對連續舵機嚟講,呢啲數值唔代表角度,而係速度同方向。

  • 106 係全速逆時針旋轉嘅數值。
  • 52 係完全停止嘅數值。
  • 0 係全速順時針旋轉嘅數值。

呢啲數值唔係通用嘅。因為製造差異,「停止」數值(52)可能要調整。如果你撳停止按鈕嘅時候舵機仲係慢慢飄移,就要微調呢個數值。影片入面示範咗呢個過程,顯示將數值改做54或者51會點樣影響摩打嘅行為(影片13:45位置)。

你都可以調整旋轉嘅數值嚟改變摩打速度。例如,將逆時針數值設做70,佢就會比106慢啲咁轉(影片12:23位置)。

csServoCommandText陣列儲住會印去Serial Monitor嘅文字字串,用嚟顯示而家嘅指令狀態。

自訂函數:servoCommand()

程式碼用咗一個自訂函數嚟處理指令邏輯。呢個函數接受一個數字(0、1或者2)作為參數,更新狀態文字,然後將相應指令傳去舵機。


void servoCommand(int n) {
  statusText = csServoCommandText[n];
  myservo.write(csServoCommand[n]);
  Serial.println(csServoCommandText[n]);
  Serial.println(csServoCommand[n]);
}

呢個函數喺主循環入面,當有按鈕被撳嘅時候就會被呼叫。佢將更新顯示同控制舵機嘅邏輯集中喺一齊,令程式碼更乾淨同容易修改。

實際項目同示範

喺影片入面,作者示範咗項目實際運作嘅情況。撳「順時針」按鈕會將數值0傳去舵機,令佢向一個方向轉。撳「逆時針」按鈕會將數值106傳過去,令佢向另一個方向轉。「停止」按鈕會傳52,應該會令摩打停低。

序列埠監視器用嚟顯示目前狀態同埋實際傳送去伺服摩打嘅數值。呢個對除錯同搵出你特定摩打嘅完美「停止」數值嚟講係非常寶貴。正如影片入面提到,停止指令可能因為伺服摩打內部電路而唔係完美,你可能會見到緩慢漂移或者震動。呢個係平價連續旋轉伺服摩打嘅常見特性,可以透過喺程式碼入面調整停止數值嚟減到最低(影片 01:15 位置)。

章節

  • [00:05] 360 度伺服摩打介紹
  • [02:02] 零件同硬件概覽
  • [02:40] 詳細接線圖同連接
  • [05:07] 程式碼解釋:常數、陣列同設定
  • [09:56] 程式碼解釋:servoCommand 函數
  • [10:54] 現場示範同序列埠監視器輸出
  • [12:23] 調整伺服摩打速度同停止數值

圖片

SG90 Mini Servo Motor
SG90 Mini Servo Motor
SG90_servo_motor-1
SG90_servo_motor-1
115-Arduino code to control continuous 360° servo from serial monitor command
語言: C++
/* 
 *  
 *  Demonstration of Controlling Continuous Servo (360 servo)
 *  This code allows you to control a 360-degree servo by a command from the Serial Monitor.
* this 350 servo motor is a just for fun. it can't be used for real application where you need exact positioning. get stepper motor or expensive servo motor. 
📚⬇️ Download and resource page https://robojax.com/RJT762
 *  
 * Modified by Ahmad Shamshiri for Robojax.com
 * on Sunday, July 1, 2018, at 11:09 AM in Ajax, Ontario, Canada
 * Watch a video instruction of this project: https://youtu.be/b_xvu6wWafA
 * Get this code from Robojax.com
 * 
 Original code by BARRAGAN <http://barraganstudio.com>
 This example code is in the public domain.
 Modified 8 Nov 2013
 by Scott Fitzgerald
 http://www.arduino.cc/en/Tutorial/Sweep
*/

#include <Servo.h>

Servo myservo;  // create servo object to control a servo
// twelve servo objects can be created on most boards

int pos = 0;    // variable to store the servo position
int incomingByte = 0;   // for incoming serial data

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



void loop() {

        // send data only when you receive data:
        if (Serial.available() > 0) {
                // read the incoming byte:
                incomingByte = Serial.read();

                // say what you got:
                Serial.print("received: ");
                Serial.print (incomingByte);
                if(incomingByte == 108){
                 Serial.println(" sent 0 Rotating CW "); 
                 myservo.write(0); 
                }else if(incomingByte == 114){
                  Serial.println(" sent 180 Rotating CCW "); 
                  myservo.write(180); 
                }else if(incomingByte == 60){
                  Serial.println(" sent Stopped "); 
                  myservo.write(60); 
                }else{
                  Serial.println(" moving Randomly"); 
                  myservo.write(incomingByte); 
                }
                  
                 
        }

  
}
893-Arduino code to control continuous 360° servo from serial monitor command (Code 2)
語言: C++
/* 
 *  
 *  Demonstration of Controlling Continuous Servo (360 servo)
360 Servo -2
 *  This code allows you to control a 360-degree servo by a command from the Serial Monitor.
* this 350 servo motor is a just for fun. it can't be used for real application where you need exact positioning. get stepper motor or expensive servo motor. 
📚⬇️ Download and resource page https://robojax.com/RJT762
 *  
 * Modified by Ahmad Shamshiri for Robojax.com
 * on Sunday, July 1, 2018, at 11:09 AM in Ajax, Ontario, Canada
 * Watch a video instruction of this project: https://youtu.be/b_xvu6wWafA
 * Get this code from Robojax.com
 * 
 Original code by BARRAGAN <http://barraganstudio.com>
 This example code is in the public domain.
 Modified 8 Nov 2013
 by Scott Fitzgerald
 http://www.arduino.cc/en/Tutorial/Sweep
*/

#include <Servo.h>

Servo myservo;  // create servo object to control a servo
// twelve servo objects can be created on most boards

int servoPin = 9;// this pin must be of those with PWM ~
int pos = 0;    // variable to store the servo position
int incomingByte = 0;   // for incoming serial data
int CWBS, CCWBS, SBS;

void setup() {
  Serial.begin(9600);
 pinMode(2,INPUT_PULLUP);// set pin for push button STOP
  pinMode(3,INPUT_PULLUP);// set pin for push button CCW  
  pinMode(4,INPUT_PULLUP);// set pin for push button CW
   
  myservo.attach(servoPin);  // attaches the servo on pin 9 to the servo object
}



void loop() {
    CCWBS = digitalRead(2);// read status of button CCW
    SBS = digitalRead(3);// read status of button STOP
    CWBS = digitalRead(4);// read status of button CW
                 if(CCWBS == LOW){
                 Serial.println(" sent 0 Rotaing CW "); 
                 myservo.write(0); 
                }else if(CWBS == LOW){
                  Serial.println(" sent 180 Rotaing CCW "); 
                  myservo.write(180); 
                }else if(SBS == LOW){
                  Serial.println(" sent Stopped "); 
                  myservo.write(60); 
                }else{
                  Serial.println(" moving Random"); 
                  myservo.write(48); 
                }
                  


  
}// loop 

你可能需要嘅嘢

資源與參考資料

文件📁

其他文件