บทเรียนที่ 91: การควบคุมมอเตอร์เซอร์โวโดยใช้โพเทนชิโอมิเตอร์และการแสดงมุมบนจอ LCD
ในบทช่วยสอน Arduino แบบลงมือปฏิบัตินี้ คุณจะได้เรียนรู้วิธีรวมส่วนประกอบสำคัญสามอย่างเข้าด้วยกันเป็นโปรเจกต์ที่ใช้งานได้จริง: มอเตอร์เซอร์โว โพเทนชิโอมิเตอร์ และจอ LCD แบบ I2C เมื่อจบบทเรียน คุณจะสามารถหมุนปุ่มและดูแขนเซอร์โวขยับแบบเรียลไทม์พร้อมกับเห็นมุมที่แม่นยำแสดงบนหน้าจอ โปรเจกต์นี้เหมาะอย่างยิ่งสำหรับการสร้างอินเทอร์เฟซทางกายภาพที่ใช้งานง่าย ซึ่งคุณต้องการทั้งการตอบสนองทางภาพและการกำหนดตำแหน่งที่แม่นยำ
โปรเจกต์นี้เชื่อมช่องว่างระหว่างอินพุตแบบแอนะล็อกและเอาต์พุตทางกายภาพ โพเทนชิโอมิเตอร์ทำหน้าที่เป็นปุ่มควบคุมแบบแอนะล็อก มอเตอร์เซอร์โวแปลงตำแหน่งของปุ่มนั้นเป็นมุมทางกายภาพ (0 ถึง 180 องศา) และหน้าจอ LCD ให้การยืนยันทางภาพทันทีเกี่ยวกับมุมปัจจุบัน การตั้งค่านี้เป็นพื้นฐานสำหรับการประยุกต์ใช้จริงมากมาย:
- สร้างข้อต่อแขนหุ่นยนต์พร้อมปุ่มควบคุมแบบแมนนวลสำหรับการกำหนดตำแหน่งที่แม่นยำ
- สร้างฐานกล้องแบบแพนและเอียงที่คุณควบคุมทิศทางด้วยปุ่มหมุน
- พัฒนาเกจวัดแบบแอนะล็อกที่แสดงค่าบนหน้าจอสำหรับแผงเครื่องมือวัดที่กำหนดเอง
- สร้างกลไกบังคับเลี้ยวของรถจำลองที่ควบคุมระยะไกลพร้อมการตอบสนองทางภาพ
ส่วนประกอบฮาร์ดแวร์
ในการสร้างโปรเจกต์นี้ คุณจะต้องมีส่วนประกอบต่อไปนี้:
- บอร์ด Arduino (Uno หรือรุ่นใกล้เคียง)
- มอเตอร์เซอร์โว (เซอร์โวงานอดิเรกมาตรฐาน 5V)
- โพเทนชิโอมิเตอร์ (แนะนำ 10kΩ)
- จอ LCD แบบ I2C (16x2 หรือ 20x4)
- เบรดบอร์ดและสายจัมเปอร์
คู่มือการเดินสายไฟ
โปรเจกต์นี้ใช้พินดิจิทัลที่ว่างสองพินบน Arduino อย่างชาญฉลาดเพื่อจ่ายไฟ 5V ให้กับโพเทนชิโอมิเตอร์และ LCD หลีกเลี่ยงความจำเป็นในการใช้รางจ่ายไฟเพิ่มเติมบนเบรดบอร์ด พิน 8 ถูกกำหนดเป็นเอาต์พุตและตั้งค่าเป็น HIGH เพื่อจ่ายไฟให้โพเทนชิโอมิเตอร์ ในขณะที่พิน 4 ทำเช่นเดียวกันสำหรับ VCC ของ LCD เทคนิคนี้มีประโยชน์เมื่อคุณต้องการแหล่งจ่ายไฟ 5V เพิ่มเติมโดยไม่ต้องเพิ่มฮาร์ดแวร์
การเชื่อมต่อสายไฟมีดังนี้ (ในวิดีโอที่ 05:08):
- เซอร์โว: สายสัญญาณไปยังดิจิทัลพิน 3, สายไฟไปยัง 5V, กราวด์ไปยัง GND
- โพเทนชิโอมิเตอร์: พินกลางไปยังแอนะล็อกพิน A0, พินด้านนอกหนึ่งพินไปยังพิน 8 (VCC2), พินด้านนอกอีกพินไปยัง GND
- LCD: VCC ไปยังพิน 4 (VCC3), GND ไปยัง GND, SDA ไปยัง A4, SCL ไปยัง A5
คำอธิบายโค้ด
โค้ดสำหรับโปรเจกต์นี้ต่อยอดจากการควบคุมเซอร์โวมาตรฐานโดยเพิ่มฟังก์ชันการแสดงผลบน LCD มาดูองค์ประกอบสำคัญที่ผู้ใช้สามารถกำหนดค่าได้ซึ่งคุณจะต้องปรับให้เข้ากับการตั้งค่าของคุณ
การกำหนดพิน: พินถูกกำหนดไว้ที่ด้านบนของสเก็ตช์และสามารถเปลี่ยนแปลงได้เพื่อให้ตรงกับการเดินสายของคุณ:
int potpin = A0; // แอนะล็อกพินสำหรับโพเทนชิโอมิเตอร์
int servoPin = 3; // ดิจิทัล PWM พินสำหรับเซอร์โว (3, 5, 6, 9, 10, 11)
int VCC2 = 8; // พิน 5V เพิ่มเติมสำหรับโพเทนชิโอมิเตอร์
int VCC3 = 4; // พิน 5V เพิ่มเติมสำหรับ LCD
การกำหนดค่า LCD: ที่อยู่ I2C มีความสำคัญอย่างยิ่งและต้องตรงกับโมดูล LCD ของคุณ โมดูลหลายตัวใช้ 0x27 แต่โค้ดนี้ใช้ 0x3F คุณอาจต้องรันสเก็ตช์สแกนเนอร์ I2C เพื่อค้นหาที่อยู่ของคุณ:
LiquidCrystal_I2C lcd(0x3F, 16, 2); // ที่อยู่, คอลัมน์, แถว
การปรับความละเอียดเซอร์โว: ค่าที่อ่านได้แบบแอนะล็อกถูกหารด้วย 5 เพื่อลดความผันผวน คุณสามารถปรับค่านี้เพื่อสร้างสมดุลระหว่างความเสถียรและความละเอียด ตัวหารที่สูงกว่า (เช่น 10) ให้ค่าที่อ่านได้เสถียรอย่างสมบูรณ์แต่ลดจำนวนตำแหน่งเซอร์โวที่คุณสามารถทำได้:
val = analogRead(potpin)/5; // หารด้วย 5 เพื่อความเสถียร
การวางตำแหน่งสัญลักษณ์องศา: โค้ดรวมตรรกะในการวางสัญลักษณ์องศา (°) อย่างถูกต้องถัดจากค่ามุม ไม่ว่าจะเป็นตัวเลขหนึ่ง สอง หรือสามหลัก เพื่อให้แน่ใจว่าการแสดงผลดูสะอาดตาและเป็นมืออาชีพเสมอ
การสาธิตโปรเจกต์สด
เมื่อคุณเปิดเครื่องโปรเจกต์ LCD จะแสดง "Servo with Pot." บนบรรทัดแรก เมื่อคุณหมุนโพเทนชิโอมิเตอร์ แขนเซอร์โวจะหมุนเพื่อให้ตรงกับตำแหน่งของปุ่มหมุน และบรรทัดที่สองของ LCD จะแสดงมุมปัจจุบันพร้อมสัญลักษณ์องศา จอภาพอนุกรมยังแสดงค่ามุมเพื่อวัตถุประสงค์ในการดีบักด้วย (ในวิดีโอที่ 05:36)
สิ่งหนึ่งที่คุณจะสังเกตเห็นคือมุมที่แสดงอาจผันผวนเล็กน้อยระหว่างสองค่า เนื่องจากค่าที่อ่านได้แบบแอนะล็อกจากโพเทนชิโอมิเตอร์ไม่เสถียรอย่างสมบูรณ์ โค้ดจัดการกับปัญหานี้โดยการหารค่าดิบด้วย 5 ซึ่งลดความผันผวนลงอย่างมากในขณะที่ยังคงให้ตำแหน่งที่แตกต่างกัน 180 ตำแหน่ง หากคุณต้องการค่าที่อ่านได้เสถียรอย่างสมบูรณ์ คุณสามารถเพิ่มตัวหารได้ แต่คุณจะสูญเสียความแม่นยำบางส่วนในการกำหนดตำแหน่งเซอร์โว
บทต่างๆ
- [00:00] แนะนำโปรเจกต์
- [00:31] ภาพรวมการเดินสายไฟและข้อกำหนดด้านพลังงาน
- [01:05] คำอธิบายโค้ดส่วนที่ 1: การตั้งค่า LCD
- [02:36] คำอธิบายโค้ดส่วนที่ 2: การเริ่มต้น LCD และตรรกะการแสดงผล
- [03:48] คำอธิบายโค้ดส่วนที่ 3: การวางตำแหน่งสัญลักษณ์องศา
- [05:08] แผนภาพการเดินสายไฟและการเชื่อมต่อทั้งหมด
- [05:36] การสาธิตและการทดสอบสด
- [06:14] การแก้ไขความผันผวนของค่าและการปรับความละเอียด
/*
Lesson 91
* S05 Servo with Potentiometer and LCD1602-I2C
*
Controlling a servo position using a potentiometer (variable resistor)
by Michal Rinott <http://people.interaction-ivrea.it/m.rinott>
Watch full instructions on YouTube https://youtu.be/E-H-4igygzA
modified on 8 Nov 2013
by Scott Fitzgerald
http://www.arduino.cc/en/Tutorial/Knob
Update by Ahmad Shamshiri on January 1, 2019 in Ajax, Ontario, Canada
https://robojax.com?vid=robojax-servo-knob
*/
#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
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
// Set the LCD address to 0x27 for a 16 chars and 2 line display
LiquidCrystal_I2C lcd(0x3F, 16, 2);
int VCC3 = 4;// define extra VCC for LCD
int degPos;// degree symbol position
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
// lines bellow are for LCD
pinMode(VCC3, OUTPUT);// set pin 4 as output
digitalWrite(VCC3, HIGH);// set pin 4 HIGH so it acts as 5V pin
lcd.begin(); // initialize the LCD,
// Turn on the backlight and print a message.
lcd.backlight();
}
void loop() {
val = analogRead(potpin)/5; // reads the value of the potentiometer (value between 0 and 1023)
val = map(val, 0, 1023/5, 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();
lcd.clear();
lcd.print("Servo with Pot.");
lcd.setCursor (0,1); // go to start of 2nd line
lcd.print("Angle:");
lcd.setCursor (7,1); // go to 7 char of of 2nd line
lcd.print(val);// print angle
if(val >99)
{
degPos =10;
}else if(val >9)
{
degPos =9;
}else
{
degPos =8;
}
lcd.setCursor (degPos,1); // go to 11 char of of 2nd line
lcd.print((char)223);// degree symbol
delay(500); // waits for the servo to get there
}
สิ่งที่คุณอาจต้องการ
-
อเมซอนBuy LCD1602-I2C from Amazonamzn.to
-
อเมซอน
-
อเมซอน
-
อเมซอนServo motor on Amazonamzn.to
-
อีเบย์Purchase LCD1602-I2C from eBayebay.us
-
อีเบย์
-
อาลีเอ็กซ์เพรสPurchase 10pcs LCD1602-I2C from AliExpresss.click.aliexpress.com
-
อาลีเอ็กซ์เพรสPurchase an LCD1602 from AliExpresss.click.aliexpress.com
-
อาลีเอ็กซ์เพรสPurchase LCD1602-I2C from AliExpresss.click.aliexpress.com
-
อาลีเอ็กซ์เพรสPurchase SG90 servo motor 180 or 360 from AliExpresss.click.aliexpress.com
แหล่งข้อมูลและเอกสารอ้างอิง
-
ภายนอกLCD library from RoboJax (ZIP)robojax.com
-
ภายนอกPurchase an LCD1602 from AliExpresss.click.aliexpress.com
ไฟล์📁
ไฟล์ Fritzing
-
LCD LCD1602-I2C module with 4 wires
LCD1602-I2C.fzpz0.01 MB
ไฟล์อื่น ๆ
-
SG90 Seroo มอเตอร์ แผ่นข้อมูล
robojax-servo-SG90_datasheet.pdf0.12 MB -
LCD1602 LiquidCrystal Library
robojax-LCD1602_LiquidCrystal.zip