این آموزش بخشی است از: کنترل سروو موتور ۱۶ یا ۳۲ با PCA9685
این مجموعه آموزش به همراه ویدیو به شما کمک میکند تا ۳۲ یا تعداد بیشتری سروو موتور را با استفاده از آردوینو UNO، نانو، مینی یا ESP32 کنترل کنید. تمام کدها ارائه شده است.
کنترل ۳۲ سروو از راه Wi-Fi با استفاده از ESP32 و PCA9685 از طریق دسکتاپ یا گوشی موبایل V5
در این آموزش، یاد خواهیم گرفت که چگونه ۳۲ موتور سرو را با استفاده از ماجیول کنترلر PWM PCA9685 متصل به ESP32 از طریق Wi-Fi کنترل کنیم. این تنظیم امکان کنترل هر سرو به صورت جداگانه یا همه آنها بهصورت همزمان از طریق یک رابط وب که از طریق دستگاههای دسکتاپ یا موبایل در دسترس است را فراهم میکند. در پایان این راهنما، شما یک سیستم کاملاً کاربردی خواهید داشت که قادر به مدیریت چندین سرو به راحتی باشد.

ماجیول PCA9685 راهی ساده برای کنترل چندین سروو با استفاده از سیگنالهای PWM فراهم میکند، در حالی که ESP32 وظیفه ارتباط Wi-Fi و عملکرد سرور وب را بر عهده دارد. شما میتوانید زاویه هر موتور سروو را از طریق یک رابط کاربری دوستداشتنی که دکمههایی برای هر سروو نمایش میدهد، تنظیم کنید. برای مرجع بصری، حتماً ویدیو را مشاهده کنید (در ویدیو در 00:00).
توضیح سختافزار
این پروژه عمدتاً از میکروکنترلر ESP32 و کنترلکننده PWM PCA9685 استفاده میکند. ESP32 میکروکنترلر قدرتمندی است که دارای قابلیتهای Wi-Fi داخلی است و آن را برای پروژههای IoT ایدهآل میسازد. PCA9685 یک کنترلکننده PWM 16 کاناله است که میتواند به صورت زنجیرهای برای کنترل حداکثر 64 سروو استفاده شود. این دستگاه از طریق پروتکل I2C با ESP32 ارتباط برقرار میکند که امکان اتصال و آدرسدهی جداگانه چندین کنترلر را فراهم میکند.
هر ماجیول PCA9685 دارای یک آدرس پیشفرض I2C معادل 0x40 است. هنگام استفاده از چندین ماجیول، میتوانید آدرسهای آنها را با لحیمکاری جامپرهای خاص تغییر دهید. به عنوان مثال، ماجیول اول میتواند در 0x40، ماجیول دوم در 0x41 و به همین ترتیب باشد. این قابلیت زنجیرهای اجازه میدهد تا بسیاری از سروها را بدون نیاز به پایههای اضافی بر روی ESP32 کنترل کنید.
همانطور که در تصویر بالا نشان داده شده است، برای بورد PCA9685 شماره ۲ (در سمت چپ)، مطمئن شوید که آن مسیر را لحیم کنید تا آدرس I2C تنظیم شود و با بورد ۱ (در سمت راست) متفاوت باشد.
جزئیات برگه مشخصات
| تولیدکننده | آدافرونت |
|---|---|
| شماره قطعه | PCA9685 |
| ولتاژ منطقی/ورودی و خروجی | ۲.۳ ولت تا ۵.۵ ولت |
| ولتاژ تامین | ۲.۳ ولت تا ۵.۵ ولت |
| جریان خروجی (به ازای هر کانال) | ۲۵ میلی آمپر |
| جریان اوج (برای هر کانال) | 100 میلیآمپر |
| راهنمایی فرکانس PWM | ۴۰ هرتز تا ۱۰۰۰ هرتز |
| آستانههای منطقی ورودی | 0.3 ولت Vcc (پایین) / 0.7 ولت Vcc (بالا) |
| افت ولتاژ / RDS(on)/ اشباع | ۰.۵ ولت حداکثر |
| محدودیتهای دما | حداکثر ۱۲۵ درجه سانتیگراد |
| پکیج | TSSOP-28 |
| یادداشتها / واریانتها | تا ۶۴ سروو با سسکادینگ |
- تأمین منبع تغذیه مناسب (5 ولت، 2 آمپر توصیه میشود).
- در صورت نیاز از مقاومتهای کشش به بالا در خطوط SDA و SCL استفاده کنید.
- هنگام استفاده از چند ماجیول PCA9685، آدرسهای I2C را به دقت بررسی کنید.
- به خنکسازی حرارتی برای کاربردهای پرقدرت توجه کنید.
- سروها را به صورت جداگانه آزمایش کنید تا از عملکرد صحیح آنها اطمینان حاصل شود.
نقشهبرداری پایههای رایج I2C:SDA= GPIO 21،SCL= GPIO 22.
دستورالعملهای سیمکشی

برای اتصال PCA9685 و ESP32، ابتدا باید منبع تغذیه و زمین را وصل کنید. پایه مثبت (V+) از PCA9685 به خروجی ۵ ولت منبع تغذیه خود وصل کنید. زمین (GND) PCA9685 را به زمین ESP32 وصل کنید. مطمئن شوید که هر دو دستگاه یک زمین مشترک دارند.
سپس، برای ارتباط I2C، پایه SDA PCA9685 را به GPIO 21 روی ESP32 و پایه SCL را به GPIO 22 متصل کنید. اگر از چندین ماجیول PCA9685 استفاده میکنید، اطمینان حاصل کنید که آنها به درستی آدرسدهی شدهاند با لحیم کردن جامپر A0 تا آدرس ماجیول دوم به 0x41 تغییر کند و به همین ترتیب. پس از آن، میتوانید موتورها را به پایههای خروجی PWM PCA9685 متصل کنید.
نمونههای شِفر (کود) و راهنمایی
شِفر (کود) با وارد کردن کتابخانههای لازم و راهاندازی دو بورد PCA9685 آغاز میشود. شناسههایی مانندmaximumServoوservoAngleتعداد سرووها و زاویه فعلی را به ترتیب تعریف کنید.
Adafruit_PWMServoDriver board1 = Adafruit_PWMServoDriver(0x40);
Adafruit_PWMServoDriver board2 = Adafruit_PWMServoDriver(0x41);
int maximumServo = 32; // how many servos are connectedاین بخش نحوهی راهاندازی اشیاء PCA9685 را با آدرسهای مربوطهشان نشان میدهد. متغیرmaximumServoتعداد کل سرووهایی که میتوان کنترل کرد را تعیین میکند.
در setup()تابع، بوردها راهاندازی میشوند و اتصال Wi-Fi ایجاد میشود. موقعیت اولیه همه سرووها با استفاده از یک حلقه تنظیم میشود.
void setup() {
board1.begin();
board2.begin();
board1.setPWMFreq(60); // Analog servos run at ~60 Hz updates
board2.setPWMFreq(60);
//initial position of all servos
for(int i=0; i < maximumServo; i++) {
if(i < 16) {
board1.setPWM(i, 0, angleToPulse(allServoPosition[i]));
} else {
board2.setPWM(i-15, 0, angleToPulse(allServoPosition[i]));
}
}
}این شِفر (کود)، بردهای PCA9685 را پیکربندی کرده و فرکانس PWM را تنظیم میکند. همچنین، تمام سرووها را به موقعیتهای ابتدایی خود که تعریف شدهاند، راهاندازی میکند.allServoPositionآرایه.
در نهایت، حلقه اصلی درخواستهای ورودی مشتری را برای کنترل سروها بر اساس ورودی کاربر مدیریت میکند.
void loop() {
server.handleClient();
if (buttonPushed && (servoNumber >= 0 && servoNumber < maximumServo)) {
if (servoNumber < 16) {
board1.setPWM(servoNumber, 0, angleToPulse(allServoPosition[servoNumber]));
} else {
board2.setPWM(servoNumber-15, 0, angleToPulse(allServoPosition[servoNumber]));
}
}
buttonPushed = 0;
}این حلقه به طور مداوم درخواستهای مشتری را پردازش کرده و موقعیتهای سرو را بر اساس دکمهای که فشار داده شده بهروز میکند. متغیرbuttonPushedپس از هر عمل برای اطمینان از کنترل مناسب، دوباره تنظیم میشود.
برای شِفر (کود) کامل، لطفاً به بخش زیر مقاله مراجعه کنید.
نمایش / چه چیزی باید انتظار داشت
زمانی که همه چیز آماده شد، باید بتوانید هر سروو را به طور جداگانه یا همه را به طور همزمان از یک واسط وب کنترل کنید. میتوانید زوایای سرووها را با کلیک بر روی دکمههای مربوط به هر سروو در دستگاه خود تنظیم کنید. سیستم باید به سرعت پاسخ دهد، اما به خاطر داشته باشید که محدودیتهای قدرت میتوانند بر عملکرد تأثیر بگذارند (در ویدئو در ساعت ۱۴:۳۰).
مشکلات رایج شامل اطمینان از اختصاص صحیح آدرسهای I2C و اینکه قدرت کافی به سروها تأمین شده است، میباشد. اگر سروها پاسخ نمیدهند، سیمکشی و اتصالات خود را دوباره بررسی کنید.
برچسبهای زمانی ویدیو
- ۰۰:۰۰ شروع
- ۰۱:۱۹ مقدمه
- تنظیم آدرس I2C 02:32
- 05:07 توضیح سیمکشی
- 07:44 آمادهسازی Arduino IDE برای ESP32
- 09:53 توضیح شِفر (کود) آردوینو
- 25:49 نمایش بر روی دسکتاپ
- نمایش در تلفن همراه 31:52
این آموزش بخشی از: کنترل سروو موتور ۱۶ یا ۳۲ با PCA9685
- شِفر (کود) آردوینو و ویدیو برای کنترلکننده سروو PCA9685، 16 کاناله، 12 بیتی، V1
- کنترل 16 موتور سروو با استفاده از ماجیول PCA9685 و شِفر (کود) آردوینو V2 نمونه #1: یکی یکی
- کنترل ۲۴ موتور سروو با استفاده از ماجیول PCA9685 و شِفر (کود) Arduino V2: کنترل موتور سروو فردی
- Controlling 16 Servo Motors Using a PCA9685 Module and Arduino V2 Sketch #3: All Servos Together
- کنترل یک سروو موتور ۳۲ با استفاده از ماجیول PCA9685 و برنامه آردوینو V3 طرح #۱: همه سرووها با هم
- کنترل یک موتور سرو 32 با استفاده از ماجیول PCA9685 و یک ESP32 V4
/*
* کتابخانه منبع ماجیول PCA9685 اصلی: https://github.com/adafruit/Adafruit-PWM-Servo-Driver-Library
*
* این شِفر (کود) آردوینو PCA6985 کنترلر سروو 32 کاناله است
* برای کنترل 32 موتور سروو از طریق WiFi با استفاده از میکروکنترلر ESP32
* این شِفر (کود) و اتصالات را از ویدیو زیر دریافت کنید: http://robojax.com/RJT365
*
* ویدیو را برای این شِفر (کود) تماشا کنید: https://youtu.be/bvqfv-FrrLM
*
* ویدیوهای مرتبط
* ویدیوی V4 از PCA9685 32 سروو با ESP32: https://youtu.be/JFdXB8Za5Os
* ویدیوی V3 از PCA9685 نحوه کنترل 32 موتور سروو https://youtu.be/6P21wG7N6t4
* ویدیوی V2 از PCA9685 3 روش مختلف برای کنترل موتورهای سروو: https://youtu.be/bal2STaoQ1M
* ویدیوی V1 معرفی PCA9685 برای کنترل 16 سروو https://youtu.be/y8X9X10Tn1k
*
* نوشته احمد شمشیری برای کانال ویدیویی Robojax www.Robojax.com
* تاریخ: 17 فوریه 2020، در اِجَکس، انتاریو، کانادا
*
* یا با استفاده از PayPal کمک مالی کنید http://robojax.com/L/?id=64
*
* این شِفر (کود) "به حالت فعلی" بدون گارانتی یا مسئولیت است. به صورت رایگان قابل استفاده است به شرطی که این یادداشت دست نخورده باقی بماند.*
* این شِفر (کود) از Robojax.com دانلود شده است
* این برنامه نرمافزار رایگان است: شما میتوانید آن را بازتوزیع کنید و/یا تحت شرایط GNU General Public License که توسط
* بنیاد نرمافزار آزاد منتشر شده، تغییر دهید؛ نسخه 3 از لایسنس یا
* (به انتخاب شما) هر نسخه بعدی.
*
* این برنامه با این امید توزیع شده است که مفید خواهد بود،
* اما بدون هیچ گونه تضمینی؛ حتی بدون تضمین ضمنی
* قابلیت فروش یا تناسب برای هدف خاص. جزئیات بیشتر را در
* GNU General Public License ببینید.
*
* شما باید یک نسخه از GNU General Public License را
* همراه با این برنامه دریافت کرده باشید. اگر نه، به <https://www.gnu.org/licenses/> مراجعه کنید.
* /
* ////////////////////// تنظیمات PCA9685 آغاز شد
*/
#include <Wire.h>
#include <Adafruit_PWMServoDriver.h>
// به این شکل نامیده میشود، از آدرس پیشفرض 0x40 استفاده میکند
Adafruit_PWMServoDriver board1 = Adafruit_PWMServoDriver(0x40);
Adafruit_PWMServoDriver board2 = Adafruit_PWMServoDriver(0x41);
int maximumServo = 32; // چند سروو متصل است
// با توجه به نوع سروو موتور شما، حداقل و حداکثر عرض پالس ممکن است متفاوت باشد، شما
// میخواهم اینها تا حد ممکن کوچک/بزرگ باشند بدون اینکه به توقف سخت برخورد کنند.
// برای حداکثر برد. شما باید آنها را به گونهای تنظیم کنید که با سروهای شما مطابقت داشته باشد.
// نداشته باشید!
// ویدیو V1 را تماشا کنید تا دو خط زیر را درک کنید: http://youtu.be/y8X9X10Tn1k
#define SERVOMIN 125 // این تعداد طول پالس 'حداقل' است (از ۴۰۹۶)
#define SERVOMAX 575 // این تعداد طول پالس «حداکثر» است (از ۴۰۹۶)
int servoAngle =0;
int servoStep = 10;
int stepDelay = 50; // 50 میلیثانیه
int servoAngleMin =0;
int servoAngleMax = 180;
// حداقل زاویه هر سرو موتورها
int allServoMin[]={
0, 0, 0, 0, 0, 0, 0, 0, // ۱ تا ۸
0, 0, 0, 0, 0, 0, 0, 0, // ۹ تا ۱۶
0, 0, 0, 0, 0, 0, 0, 0, // ۱۷ تا ۲۴
0, 0, 0, 0, 0, 0, 0, 0}; // ۲۵ تا ۳۲
// حداکثر مقدار هر سروو
int allServoMax[]={
180, 180, 180, 180, 180, 180, 180, 180, // ۱ تا ۸
180, 180, 180, 180, 180, 180, 180, 180, // ۹ تا ۱۶
180, 180, 180, 180, 180, 180, 180, 180, // ۱۷ تا ۲۴
180, 180, 180, 180, 180, 180, 180, 180}; // ۲۵ تا ۳۲
// وضعیت اولیه سرووها
int allServoPosition[] ={
0, 0, 0, 0, 0, 0, 0, 0, // ۱ تا ۸
0, 0, 0, 0, 0, 0, 0, 0, // ۹ تا ۱۶
0, 0, 0, 0, 0, 0, 0, 0, // ۱۷ تا ۲۴
0, 0, 0, 0, 0, 0, 0, 0}; // ۲۵ تا ۳۲
int servoNumber = 100; // سرعت جابهجایی
int buttonPushed =0;
int allServo =0;
void handleServo(); // این نمونهای از تابعی است که در انتهای این شِفر (کود) تعریف شده است.
int angleToPulse(int ang); // این نمونهای از تابعی است که در انتهای این شِفر (کود) تعریف شده است.
// //////////////////////PCA9685 به پایان رسید
#include "PCA9684_32Servo_ESP32.h"
#include <WiFi.h>
#include <WiFiClient.h>
#include <WebServer.h>
#include <ESPmDNS.h>
const char *ssid = "Robojax";
const char *password = "YouTube2020";
WebServer server(80);
const int led = 13;
// ///////////////////////////////////
void handleRoot() {
String HTML_page = pageHeader_p1;
if(allServo)
{
HTML_page.concat("<div class=\"btn\"><a class=\"angleButton colorAll\" href=\"/servo?do=stop\">Stop Servo</a></div>");
}else{
HTML_page.concat("<div class=\"btn\"><a class=\"angleButton colorAll\" href=\"/servo?do=all\">All Servo</a></div>");
}
for (int i=0; i < maximumServo; i++)
{
HTML_page.concat("<div class=\"btn\"><a class=\"angleButton colorBtn\" href=\"/servo?move=");
HTML_page.concat(i);
HTML_page.concat("\">SRV ");
HTML_page.concat(i+1);
HTML_page.concat(" </a></div>");
}
HTML_page.concat("</body>\n</html>");
server.send(200, "text/html", HTML_page);
}
void handleNotFound() {
digitalWrite(led, 1);
String message = "File Not Found\n\n";
message += "URI: ";
message += server.uri();
message += "\nMethod: ";
message += (server.method() == HTTP_GET) ? "GET" : "POST";
message += "\nArguments: ";
message += server.args();
message += "\n";
for (uint8_t i = 0; i < server.args(); i++) {
message += " " + server.argName(i) + ": " + server.arg(i) + "\n";
}
server.send(404, "text/plain", message);
digitalWrite(led, 0);
}
void setup() {
board1.begin();
board2.begin();
board1.setPWMFreq(60); // سرعت بهروزرسانی سرووهای آنالوگ حدود ~60 هرتز است
board2.setPWMFreq(60);
// موقعیت اولیه تمام سروها
for(int i=0; i < maximumServo; i++) {
if(i < 16)
{
board1.setPWM(i, 0, angleToPulse(allServoPosition[i]) );
}else{
board2.setPWM(i-15, 0, angleToPulse(allServoPosition[i]) );
}
} // برای پایان
Serial.begin(115200);
Serial.println("32 channel Servo test!");
// کنترل سروو با استفاده از ESP32 از Robojax.com
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, password);
Serial.println("");
// منتظر اتصال باشید
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.print("Connected to ");
Serial.println(ssid);
Serial.print("IP address: ");
Serial.println(WiFi.localIP());
if (MDNS.begin("robojaxESP32")) {
Serial.print("MDNS responder started at http: // ");
Serial.println("robojaxESP32");
}
server.on("/", handleRoot);
server.on("/servo", HTTP_GET, handleServo);
server.onNotFound(handleNotFound);
server.begin();
Serial.println("HTTP server started");
}
void loop() {
server.handleClient();
if(allServo ){
for( int angle =servoAngleMin; angle <= servoAngleMax; angle +=servoStep){
for(int i=0; i<16; i++)
{
board2.setPWM(i, 0, angleToPulse(angle) );
board1.setPWM(i, 0, angleToPulse(angle) );
}
delay(stepDelay);
}
// رابوجكس PCA9865 کنترل سروو ۳۲ کاناله
delay(100);
} // اگر فشار داده شود
if(false){
Serial.print("Servo #");
Serial.print (servoNumber);
Serial.print(" Angle ");
Serial.println(allServoPosition[servoNumber]);
}
if( buttonPushed && (servoNumber >=0 && servoNumber < maximumServo) ){
if(servoNumber < 16)
{
board1.setPWM(servoNumber, 0, angleToPulse(allServoPosition[servoNumber]) );
}else{
board2.setPWM(servoNumber-15, 0, angleToPulse(allServoPosition[servoNumber]) );
}
}
buttonPushed =0;
}
/*
* handleServo()
* متغیر buttonPushed را بروزرسانی کنید
* هیچ چیزی برنمیگرداند
* نوشته شده توسط احمد شمشیری در 29 دسامبر 2019
* www.Robojax.com
* http://youTube.com/robojaxTV
*/
void handleServo() {
if(server.arg("do") == "all" )
{
allServo =1;
}else{
allServo =0;
}
int servoNumberRequested= server.arg("move").toInt();
if(servoNumberRequested >=0 && servoNumberRequested < maximumServo)
{
buttonPushed = 1;
if(allServoPosition[servoNumberRequested] == allServoMin[servoNumberRequested] ) {
allServoPosition[servoNumberRequested] = allServoMax[servoNumberRequested];
}else{
allServoPosition[servoNumberRequested] = allServoMin[servoNumberRequested];
}
servoNumber =servoNumberRequested;
}
handleRoot();
} // handleServo() پایان
/*
* زاویهToPulse(int ang)
* زاویه را به درجه دریافت کرده و عرض پالس را بازمیگرداند
* همچنین مقدار را در نمایشگر مسلسل چاپ میکند
* نوشته شده توسط احمد شمشیری برای Robojax، Robojax.com
*/
int angleToPulse(int ang){
int pulse = map(ang,0, 180, SERVOMIN,SERVOMAX); // زاویه نقشه را از ۰ تا ۱۸۰ به حداقل و حداکثر سروو نگاشت کنید
// زاویه:
// سریال.چاپ(" پالس: ");سریال.خط.چاپ(pulse);
return pulse;
}
مواردی که ممکن است به آنها نیاز داشته باشید
-
آمازون
-
آمازونموتور سروو در اَمه زونamzn.to
-
ایبیخرید PCA9685 از eBayebay.us
-
علیاکسپرسخرید PCA9685 از علیاکسپرسs.click.aliexpress.com
-
علیاکسپرسموتور سرو SG90 با زاویه ۱۸۰ یا ۳۶۰ را از علیاکسپرس خریداری کنیدs.click.aliexpress.com
-
بنگ گودپیش خرید PCA9685 از بانگودbanggood.com
منابع و مراجع
-
خارجیکتابخانه PAC9685 (از گیتهاب)github.com
فایلها📁
هیچ فایلی موجود نیست.