Lekcia 97-3: Ovládanie servomotora pomocou rotačného enkodéra a zobrazenie uhla na LCD
Tento projekt demonštruje, ako zostaviť presný regulátor polohy servomotora pomocou rotačného enkódera, s meraním uhla v reálnom čase zobrazeným na I2C LCD. Namiesto potenciometra, ktorý má fyzické obmedzenia a môže sa časom opotrebovať, tento návrh používa mechanický rotačný enkóder, ktorý sa otáča nepretržite, čo ponúka vyššiu odolnosť a flexibilnejšie ovládanie. Tento projekt je ideálny pre každého, kto potrebuje presné a opakovateľné polohovanie vo svojich projektoch s Arduinom.
Toto zapojenie je ideálne pre širokú škálu praktických aplikácií:
- Stavba diaľkovo ovládaného pan-tilt držiaka kamery, kde potrebujete presné uhlové ovládanie.
- Vytvorenie kĺbu robotického ramena s manuálnym ovládaním pre jemné polohovanie.
- Vývoj testovacieho zariadenia pre kormidlá modelárskej plachetnice alebo lietadla.
- Konštrukcia nastaviteľného sledovača solárnych panelov, ktorý možno manuálne polohovať.
- Výroba vlastného ovládacieho gombíka alebo vstupného zariadenia pre 3D tlačiareň alebo CNC stroj na úpravu nastavení.
Potrebný hardvér
- Arduino Uno (alebo podobná doska)
- Modul rotačného enkódera (verzia s PCB alebo holý enkóder s rezistormi)
- Servomotor (akýkoľvek štandardný typ, napr. s kovovými alebo malými plastovými prevodmi)
- I2C LCD (16x2 znakov)
- Prepojovacie vodiče
- Nepájivé pole (voliteľné, pre enkóder bez PCB)
- Tri rezistory 1kΩ až 100kΩ (ak používate holý rotačný enkóder)
Schéma zapojenia
Tento projekt má tri hlavné komponenty na pripojenie: rotačný enkóder, servomotor a I2C LCD. Schéma zapojenia nižšie zobrazuje všetky potrebné pripojenia. (vo videu o 05:35)
Modul rotačného enkódera je primárny vstup. Jeho piny CLK a DT sa pripájajú na digitálne piny 2 a 3 Arduina. Pin "+" sa pripája na 3,3V a pin "GND" na zem. Ak používate holý enkóder, musíte pridať tri pull-up rezistory (medzi 1kΩ a 100kΩ) z dvoch dátových pinov enkódera a jeho spínacieho pinu na 3,3V, ako je znázornené na schéme. (vo videu o 07:03)
Servomotor má tri vodiče. Signálny vodič (zvyčajne žltý alebo oranžový) sa pripája na pin s podporou PWM, čo je v tomto príklade pin 9. Napájací vodič (zvyčajne červený) sa pripája na 5V a uzemňovací vodič (zvyčajne hnedý alebo čierny) na zem. Pre servomotory s vysokým krútiacim momentom sa odporúča použiť externý 5V napájací zdroj, aby nedošlo k preťaženiu napäťového regulátora Arduina. (vo videu o 06:03)
I2C LCD vyžaduje štyri pripojenia. Pin VCC sa pripája na 5V, GND na zem, SDA na pin A4 Arduina a SCL na pin A5. Alternatívne môžete LCD napájať z 5V pinu na ICSP konektore. (vo videu o 06:31)
Inštalácia potrebných knižníc
Pred nahratím kódu musíte nainštalovať dve knižnice. Prvá je knižnica LiquidCrystal_I2C, ktorú môžete pridať stiahnutím poskytnutého ZIP súboru a použitím ponuky Sketch → Include Library → Add .ZIP Library. (vo videu o 13:28)
Druhá je knižnica Encoder od Paula Stoffregena. Tú možno nainštalovať priamo cez Správcu knižníc prechodom na Sketch → Include Library → Manage Libraries, vyhľadaním "encoder" a kliknutím na inštalovať. (vo videu o 13:59)
Vysvetlenie kódu
Kód je navrhnutý tak, aby bol vysoko konfigurovateľný. Kľúčové parametre sú definované na začiatku náčrtu, čo vám umožňuje ľahko prispôsobiť správanie bez hlbšieho skúmania logiky. (vo videu o 17:52)
const int SW_PIN = 4;//definuje pin pre spínač rotačného enkódera
const int PIN_A =2;
const int PIN_B =3;
const int homePosition = 90; //počiatočná poloha
const int stepValue = 3;//ako rýchlo by sa mal servomotor otáčať pri otáčaní gombíka
const int servoPin = 9;//~musí byť pin označený symbolom ~
SW_PIN,PIN_AaPIN_B: Tieto konštanty definujú piny Arduina pripojené k spínaču, CLK a DT pinom enkódera. Ak používate iné piny, zmeňte tieto hodnoty.homePosition: Toto je uhol (v stupňoch), do ktorého sa servomotor presunie po stlačení tlačidlového spínača enkódera. Môžete ho zmeniť na akúkoľvek hodnotu medzi 0 a 180.stepValue: Toto riadi citlivosť ovládania. Určuje, o koľko stupňov sa zmení uhol servomotora pri každom zaskočení (kliknutí) enkódera. Vyššia hodnota spôsobí rýchlejší pohyb servomotora, zatiaľ čo nižšia hodnota umožňuje jemnejšie ovládanie.servoPin: Toto je PWM pin, na ktorý je pripojený signálny vodič servomotora. Uistite sa, že tento pin má na vašej doske Arduina vedľa seba symbol "~", pretože iba tieto piny môžu generovať potrebný PWM signál.
Kód obsahuje aj vlastnú funkciu lcdAngel(int angel). Táto funkcia je zodpovedná za aktualizáciu hodnoty uhla na LCD. Najprv vymaže predchádzajúce číslo z displeja, potom vytlačí nový uhol nasledovaný symbolom stupňa (°). Táto funkcia sa volá automaticky vždy, keď sa zmení uhol serva, takže s ňou nemusíte priamo interagovať. (vo videu o 27:56)
Riadenie serva z enkódera je pokryté v Lekcii 97-2: Riadenie servomotora pomocou rotačného enkódera.
Živá ukážka projektu
Po nahratí kódu LCD najprv zobrazí úvodnú obrazovku "Robojax Encoder" a "Servo Test" na dve sekundy, potom ju vymaže a zobrazí aktuálny uhol. (vo videu o 24:10)
Keď otočíte enkóderom, servo sa plynule presunie do svojej novej polohy a uhol sa aktualizuje na LCD. Smer otáčania určuje, či sa uhol zvyšuje alebo znižuje. Ak sa zdá, že je smer obrátený, môžete jednoducho vymeniť pripojenia PIN_A a PIN_B alebo ich definície v kóde. (vo videu o 17:32)
Pohyb serva je ohraničený medzi 0 a 180 stupňami. Ak budete pokračovať v otáčaní enkódera za tieto limity, servo sa zastaví na hranici, čím sa zabráni mechanickému poškodeniu. (vo videu o 25:54)
Stlačením vstavaného tlačidlového spínača enkódera sa servo okamžite vráti do homePosition, ktorú ste definovali. To je užitočné na nastavenie známeho referenčného bodu alebo "domovskej" polohy. (vo videu o 27:13)
Súvisiace projekty z tohto videa
- Lekcia 97-1: Detekcia otáčania rotačného enkódera a stlačenia spínača
- Lekcia 97-2: Riadenie servomotora pomocou rotačného enkódera
Kapitoly
- [00:01] Úvod do riadenia serva pomocou rotačného enkódera
- [01:46] Prečo použiť rotačný enkóder namiesto potenciometra
- [05:35] Zapojenie PCB verzie rotačného enkódera
- [07:03] Zapojenie holého rotačného enkódera s rezistormi
- [12:05] Pripojenie I2C LCD displeja
- [13:28] Inštalácia potrebných knižníc
- [14:54] Pochopenie základného príkladu kódu pre enkóder
- [17:52] Úprava kódu pre servo a spínač
- [20:20] Úplné vysvetlenie kódu pre riadenie serva a LCD
- [30:01] Živá ukážka projektu
/*
* Lesson 97-3: Controlling Servo Motor using Rotary Encoder and Display Angle on LCD
Download and resource page https://robojax.com/RJT453
* Watch full details video: https://youtu.be/6xVLbNlmK-g
This video is part of Arduino Step by Step Course which starts here: https://youtu.be/-6qSrDUA5a8
If you found this tutorial helpful, please support me so I can continue creating
content like this. Make a donation using PayPal by credit card https://bit.ly/donate-robojax
* This code is "AS IS" without warranty or liability. Free to be used as long as you keep this note intact.*
* This code has been downloaded from Robojax.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
* Updated by Ahmad Shamshiri on Jan 23, 2022
* Encoder Library - Basic Example
* http://www.pjrc.com/teensy/td_libs_Encoder.html
*
* This example code is in the public domain.
*/
const int SW_PIN = 4;//define a pin for rotary encode switch
const int PIN_A =2;
const int PIN_B =3;
#include <Encoder.h>
// Change these two numbers to the pins connected to your encoder.
// Best Performance: both pins have interrupt capability
// Good Performance: only the first pin has interrupt capability
// Low Performance: neither pin has interrupt capability
Encoder myEnc(PIN_A, PIN_B);
// avoid using pins with LEDs attached
const int homePosition = 90; //initial position
const int stepValue = 3;//how fast the servo should rotate when turning the knob
const int servoPin = 9;//~must be a pin that that is labeled with ~
#include <Servo.h>
Servo myservo; // create servo object to control a servo
int servoAngel =homePosition;
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
// Set the LCD address to 0x27 or 0x3F for a 16 chars and 2 line display
LiquidCrystal_I2C lcd(0x3F, 16, 2);
void setup() {
Serial.begin(9600);
pinMode(SW_PIN, INPUT);
Serial.println("Robojax Encoder with LCD and Servo");
myservo.attach(servoPin); // attaches the servo on pin
myservo.write(servoAngel);//move servo to initial position
lcd.begin();
// Turn on the blacklight and print a message.
lcd.backlight();
lcd.print("Robojax Encoder");
lcd.setCursor (0,1); // go to start of 2nd line
lcd.print("Servo Test");
delay(2000);
lcd.clear();// clear previous values from screen
lcd.print("Robojax Encoder");
lcd.setCursor (0,1); // go to start of 2nd line
lcd.print("Angle: ");
}
long oldPosition = -999;
void loop() {
long newPosition = myEnc.read();
if (newPosition != oldPosition) {
if(newPosition > oldPosition)
{
int newStep = abs(newPosition - oldPosition);
Serial.print("Angle ");
Serial.println(servoAngel);
servoAngel -= stepValue;
if(servoAngel <0)
servoAngel =0;
myservo.write(servoAngel); //move servo to new angle
lcdAngel(servoAngel);//print on LCD
}
if(newPosition < oldPosition )
{
int newStep = abs(newPosition - oldPosition);
Serial.print("Angle ");
Serial.println(servoAngel);
servoAngel += stepValue;
if(servoAngel >180)
servoAngel =180;
myservo.write(servoAngel); //move servo to new angle
lcdAngel(servoAngel);//print on LCD
}
oldPosition = newPosition;//remember the new position
}
if( digitalRead(SW_PIN) == LOW)
{
Serial.print("Home: ");
Serial.println(homePosition);
servoAngel =homePosition;
myservo.write(servoAngel); //move servo to new angle
lcdAngel(servoAngel);//print on LCD
}
//delay(200);
}
/*
* lcdAngel(int angel)
* prints the angle on LCD
* written by Ahmad Shamshiri
* www.robojax.com
* Jan 27, 2022 at 13:18
* Watch full details video: https://youtu.be/6xVLbNlmK-g
*/
void lcdAngel(int angel)
{
int startChar =7;
for(int i=startChar; i<16; i++)
{
lcd.setCursor (i,1);
lcd.print(" ");
}
lcd.setCursor (startChar,1); // line 1
lcd.print(angel);
lcd.print((char)223);
}
Veci, ktoré by ste mohli potrebovať
-
Amazon
-
Amazon
-
Amazon
-
eBay
-
eBay
-
AliExpressPurchase an LCD1602 from AliExpresss.click.aliexpress.com
Zdroje a referencie
-
ExternéPurchase an LCD1602 from AliExpresss.click.aliexpress.com
-
Externé
-
Externé
-
ExternéPurchase ZK-5DA from Amazon UKamzn.to
Súbory📁
Žiadne súbory nie sú k dispozícii.