Hľadať kód

Lekcia 97-3: Ovládanie servomotora pomocou rotačného enkodéra a zobrazenie uhla na LCD

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

Zapojenie pre LCD, servomotor a rotačný enkóder bez PCB s pridanými vlastnými rezistormi
Zapojenie pre LCD, servomotor a rotačný enkóder s PCB. 

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_A a PIN_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

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

Obrázky

Rotary encoder PCB wiring breadboard
Rotary encoder PCB wiring breadboard
Rotary encoder wiring breadboard
Rotary encoder wiring breadboard
433-Lesson 97: Controlling a Servo Motor using a Rotary Encoder and Display Angle on an LCD
Jazyk: C++
/*
 * 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);
}

Zdroje a referencie

Súbory📁

Žiadne súbory nie sú k dispozícii.