Fyzikální kabinet FyzKAB

Ovládáme servo modulem ESP32

Dnes se podíváme na další základní úkol domácí automatizace – tedy na ovládání servomotoru (opět pomocí vývojové desky s modulem ESP32). Nejdříve se podíváme na základy ovládání servomotoru, protože abychom porozuměli propojovacímu obvodu a řídicímu programu, musíme nejprve porozumět jeho základnímu fungování.

Servomotor (zkráceně servo) je motor pro pohony, u kterých lze na rozdíl od běžného motoru nastavit přesnou polohu natočení osy. Ovládají se jím například posuvy CNC strojů, nastavení čtecí hlavičky u pevného disku, RC modely používají modelářská serva pro své ovládání… apod.

Servomotor je řízen sérií pulzů na ovládacím pinu. Téměř všechna serva používaná pro hobby projekty pracují na základní frekvenci 50 Hz (doba mezi dvěma pulzy 20 ms). Poloha hřídele je určena šířkou řídicího signálu, tzv. PWM signálu (Pulse Width Modulation – Pulzně šířková modulace), jehož šířka se pohybuje v rozmezí 1 ms pro krajní levou polohu do 2 ms pro krajní pravou polohu (1,5 ms odpovídá střední poloze). Servo se obvykle může otáčet od 0 do 180 stupňů, níže uvedený obrázek č. 1 ilustruje vztah mezi PWM signálem a polohou hřídele:

Poloha servomotoru ESP32

zdroj obrázku: https://howtomechatronics.com/how-it-works/how-servo-motors-work-how-to-control-servos-using-arduino/

Obrázek 1 – Vliv šířky PWM signálu na polohu serva

Připojení serva k modulu ESP32

O generování řídicího signálu se při použití modulu ESP32 vlastně nebudeme muset příliš starat, protože pro řízení serva použijeme knihovnu Servo (speciálně pro ESP32!!!), takže se nyní nejdříve zaměříme na elektrické připojení serva k modulu ESP32.

Připojovací kabel servomotoru je tvořen třemi vodiči: (viz obrázek č. 2)

  • Napájecí vodič Ucc (obvykle červená barva),
  • Zemnící vodič GND (obvykle černý nebo hnědý),
  • Řídicí PWM signál (obvykle má oranžovou, žlutou nebo bílou barvu).

Pinout servomotoru esp32

zdroj obrázku: https://microcontrollerslab.com/esp32-servo-motor-web-server-arduino/

Obrázek 2 – Zapojení pinů serva

A zase ta elektřina…

Před samotným připojením k modulu ESP32 se musíme ujistit, jak velký elektrický proud je nutný pro provoz zvoleného servomotoru. (Na trhu jsou k dispozici různé servomotory.) Pokud používáme servomotor s malým výkonem, jako jsou modelářská serva typu S0009, SG90, SG92R…, můžeme jej přímo připojit k desce ESP32. Pokud však chceme s modulem ESP32 používat výkonnější servomotor, musíte použít proudově posilující ovladač motoru, jako je např. UNL2003. Obdobně pokud bychom chtěli s ESP32 používat více serv, musíme též použít servo „driver“ (např. PCA9685 – viz dále) nebo nějak jinak vyřešit externí napájení.

Na většině internetových stránek, které se zabývají připojením serva k modulu ESP32 najdeme následující nebo obdobné zapojení (lišící se v použitém řídicím GPIO pinu) – viz následující obrázek č. 3

zapojení servomotoru s ESP32

zdroj obrázku: https://microcontrollerslab.com/esp32-servo-motor-web-server-arduino/

Obrázek 3 – Připojení serva k modulu ESP32

Ve schématu je použita vývojová deska ESP32 DOIT DEVKIT ve své 30pinové verzi, ale je možné použít i 36pinovou verzi nebo jinou desku ESP32. Servo je napájeno napětím 5 V, je tedy připojeno na desce ESP32 k pinu Vin a GND. Řídicí pin je připojen k libovolnému výstupnímu GPIO pinu, který podporuje PWN výstup – zde kupříkladu pin GPIO 13.

A máme zde opět problém spojení dvou zařízení, kdy jedno pracuje na 5 V (servo) a druhé na 3,3 V (ESP32). Již jsme v předešlých článcích viděli, někdy to může být problém, jindy ne. Také jsme již viděli, že na internetu můžeme najít několik zapojení, která jsou chybná a svým provozem ohrožují modul ESP32.
Bude tomu i v případě řízení servomotoru?

Opět se musíme obrátit k elektronickému schématu. V tomto případě jsme se zaměřili na servo SG90. V případě jiného typu je nutné si sehnat schéma řídicí elektroniky daného typu serva. Následující obrázek č. 4 ukazuje schéma řídicí elektroniky serva SG90, která je postavena na obvodu AA51880. Jedná se téměř o katalogové zapojení (červeně jsou vyznačeny změny oproti katalogovému zapojení).

schema obvodu AA51880

Obrázek 4 – Vnitřní schéma elektroniky serva SG90

Z tohoto zapojení však není jasné, zda se na řídicím pinu (14) neobjevuje napájecí napětí 5 V. Tuto otázku nám bohužel nezodpoví ani další informace plynoucí z katalogového listu tohoto obvodu. Nezbývá nám tedy nic jiného, než připojit na tento pin voltmetr a změřit, jaké je na něm napětí proti zemi. Při našem měření se ukázalo, že tento pin je asi skutečně čistě vstupní (žádný pull-up rezistor proti napájecímu napětí a podobně), protože je normálně na tomto pinu napětí 0 V – viz obrázek č. 5 ukazující měření.

mereni napeti na PWM pinu

Obrázek 5 – Měření napětí na PWM stupu serva při zapnutém napájení

Na základě tohoto zjištění lze tedy říci, že „třívoltový“ modul ESP32 je možné schématu z internetu věřit a tedy lze bezproblémově připojit k pětivoltovému servu SG90.

Pokud Vám připadá náš přístup poněkud opatrný (až paranoidní), přečtěte si příspěvky o připojení I2C LCD displeje, sonarového čidla nebo čidla BMP180. 😉

 

TAK: Víme-li, jak lze servo připojit ke zvolené vývojové desce s modulem ESP32, můžeme se vrhnout na programování.

Program pro ovládání serva modulem ESP32 (v prostředí Arduino IDE)

Jak jsme uvedli v úvodu, pro řízení serva použijeme ovládací knihovnu. Pro milovníky něčeho, co bychom mohli v nadsázce nazvat „RAW programování“, zde ale máme i ukázku řídicího kódu bez použití této knihovny. Proč si nezkusit ověřit, zda to povídání o PWM signálu (ne)byla skutečně pravda! 😎 Využijeme vhodné nastavení PWM kanálu, který se spíše používá pro PWM regulaci svitu LED. Ale to nám přece nemusí vadit! Nastavíme frekvenci PWM kanálu na 50 Hz a začneme měnit šířku pulzů v rozmezí 1–2 ms. Výhoda modulu ESP32 (např. oproti modulu Arduino) je to, že lze měnit frekvenci generovaného PWM výstupu. Následující kód znázorňuje řízení serva bez obslužné knihovny (princip je vysvětlen v kometářích kódu).

/* SERVO kyva sem-tam */

const int servoPin = 13;   // servo pripojeno na GPIO13

int dutyCycle = 0;

/* Nastaveni PWM vlastnosti */
const int PWMFreq = 50;   // frekvence PWM signalu
const int PWMChannel = 0;   // cislo PWM kanalu
const int PWMResolution = 8   // rozliseni vstupni hodnoty (0-256);

// funkce SETUP se spusti jednou pri stisknuti tlacitka reset nebo pri zapnuti desky.
void setup() {
  ledcSetup(PWMChannel, PWMFreq, PWMResolution);   // nastaveni PWM vystupu
  ledcAttachPin(servoPin, PWMChannel);   // pripojeni LED PWM kanalu k GPIO pinu
}

// funkce LOOP bezi stale dokola.
void loop() {
  for(dutyCycle = 5; dutyCycle <= 32; dutyCycle++) {   // nataceni vpravo
    ledcWrite(PWMChannel, dutyCycle);   // nastaveni vystupni hodnoty na vystup
    delay(100);
  }

  for(dutyCycle = 32; dutyCycle >= 5; dutyCycle--) {   // nataceni vlevo
    ledcWrite(PWMChannel, dutyCycle);   // nastaveni vystupni hodnoty na vystup
    delay(100);
  }

}

Všimněme si, že natočení serva zcela vlevo odpovídá hodnotě 5 v proměnné dutyCycle, naopak maximální výchylka vpravo odpovídá hodnotě 32. Pokud bychom chtěli zadávat natočení serva ve stupních (například pomocí proměnné vstupni_uhel), musí se „přemapovat“ interval vstupních hodnot 0–180 (stupňů) na interval hodnot 5–32. To bychom provedli následujícím příkazem:

dutyCycle = map(vstupni_uhel, 0, 180, 5, 32);

Takže ono to občas asi jde i bez knihoven, ale my se dále odebereme do pohodlí, které nám ovládací knihovna poskytne.

Knihovna Servo pro ESP32

Pro řízení serva modulem ESP32 lze použít hned několik knihoven.

  • První knihovnu pro servo a modul ESP32 lze najít přímo v manažeru knihoven prostředí Arduino IDE. Jmenuje se ESP32Servo a je od autorů Kevina Harringtona a Johna Bennetta.
  • Druhou knihovnou je knihovna ServoESP32 od českého vývojáře Jaroslava Párala, kterou též můžeme stáhnout přímo v manažéru knihoven.


   Poznámka:
Knihovna Servo určená pro modul Arduino NELZE POUŽÍT pro modul ESP32! Je třeba nainstalovat knihovnu primárně určenou pro modul ESP32.
 

Budeme trochu patrioty a naistalujeme si knihovnu ServoESP32 českého vývojáře, v následujícím kódu tedy použité příkazy pro řízení serva vycházejí z této knihovny. Následující příklad je principiální obdobou předešlého kódu, který byl ale vytvořen bez obslužné knihovny.

Myslíme, že postup instalace potřebné knihovny byl již v předchozích článcích uveden tolikrát, že zde asi nemá cenu opět opakovat tento postup.

manazar knihoven v Arduino IDE

Obrázek 6 – Použití knihovny ServoESP32 od vývojáře Jaroslava Párala

programový kód: (otáčení serva „sem a tam“)

/* SERVO kyva sem-tam (knihovna Servo) */

#include <Servo.h>   // POZOR nejedna se o knihovnu Servo.h pro Arduino!!!

static const int servoPin = 13;   // servo pripojeno na GPIO13

Servo servo1;   // vytvoreni objektu pro servo

// funkce SETUP se spusti jednou pri stisknuti tlacitka reset nebo pri zapnuti desky.
void setup() {
  servo1.attach(servoPin);   // propojeni GPIO pinu s objektem servo
}

// funkce LOOP bezi stale dokola.
void loop() {
  for(int posDegrees = 0; posDegrees <= 180; posDegrees++) {   // nataceni od 0 do 180 stupnu
    servo1.write(posDegrees);   // nastaveni vystupu serva
    delay(100);
  }

  for(int posDegrees = 180; posDegrees >= 0; posDegrees--) {   // nataceni od 180 do 0 stupnu
    servo1.write(posDegrees);   // nastaveni PWM signalu na servo
    delay(100);
  }

}


Natáční dle polohy potenciometru

Další kód pak ukazuje natáčení serva dle natočení potenciometru. Toto zapojení zde uvádíme nejen kvůli kódu, ale především kvůli schématu zapojení (viz obr. 7).

zapojeni serva s potenciometrem

Obrázek 7 – Připojení serva a potenciometru k modulu ESP32

Všimněme si, že servo je zapojeno na napájecí napětí 5 V, ale potenciometr je zapojen mezi napěťové piny 3V3 a GND. Hodnota napětí na jezdci potenciometru se tedy bude měnit v rozmezí 0–3,3 V. To je důležité! (Vzpomeňme si na povolené maximální napětí na pinech modulu ESP32!)

Na internetu lze najít i zapojení, kde je potenciometr zapojen mezi vodiče napájecího napětí serva, tedy mezi GND a 5 V. Pětivoltové napětí však při natočení potenciometru do maximální polohy zničí analogový vstup modulu ESP32. V případě třívoltového serva společné spojení potenciometru s napájením serva pochopitelně nevadí. Ale pokud budeme používat pětivoltové servo, musíme napájení serva (5 V) a maximální napětí na potenciometru (3,3 V) jasně oddělit!

Tato chyba patrně vznikla převzetím schématu pro případ serva napájeného napětím 3,3 V a jeho nepromyšleným použitím na případ serva pětivoltového.

Pokud máme potenciometr a servo správně připojené, můžeme použít následující kód:

programový kód: (natáčení serva dle polohy potenciometru)

/* SERVO kyva podle potenciometru */

#include <Servo.h>   // POZOR nejedna se o knihovnu Servo.h pro Arduino!!!

static const int servoPin = 13   // servo pripojeno na GPIO13
static const int potentiometerPin = 32;   // potenciometr na GPIO32

Servo servo1;   // vytvoreni objektu pro servo

// funkce SETUP se spusti jednou pri stisknuti tlacitka reset nebo pri zapnuti desky.
void setup() {
  servo1.attach(servoPin);   // propojeni GPIO pinu s objektem servo
}

// funkce LOOP bezi stale dokola.
void loop() {
  int servoPosition = map(analogRead(potentiometerPin), 0, 4096, 0, 180);   // nacteni a namapovani analogového vstupu (0-4096) na hodnoty 0-180
  servo1.write(servoPosition);   // nastaveni PWM signalu na servo
  delay(100);
}

 


16kanálový PWM modul PCA9685

PCA96845 je 16kanálový modul PWM řadiče, který lze použít se servomotory, LED diodami a vším, co můžete ovládat pomocí PWM pulzů. Modul je I2C zařízením (o sběrnici I2C jsme si povídali v člálnku Rozhraní I2C a displej LCD s ESP32), takže veškerá práce s nastavením a generováním PWM signálů se provádí v modulu PCA96845, tím se řídicí zařízení (v našem případě modul ESP32) „osvobodí“ od nutnosti se provozem PWM signálu zabývat.

Modul PCA96845 má šest volitelných adresových bitů, takže je lze vytvořit až 26 = 64 různých adres. Díky tomu, že každý modul ovládá až 16 PWM „spotřebičů“ můžeme na jediné sběrnici I2C ovládat až 64·16 = 1024 servomotorů! A to nám asi stačí, ne? 😉

Modul PCA96845 ukazuje obrázek č. 8. Vidíme, že na modulu PCA9685 jsou duplicitní ovládací piny (na obou koncích), což usnadňuje připojení řídicího modulu nebo řetězení více modulů různé adresy (např. pomocí pravoúhlých konektorů Dupont samec a samice).

PCA9685 nahled

Obrázek 8 – Pohled na modul PCA96845

Zapojení PCA9685 k ESP32

PCA9685 je I2C zařízení a může pracovat s 3,3 V nebo 5 V logikou a napájením. Při připojení k modulu ESP32 budeme používat 3,3voltovou logiku a modul budeme napájet přímo z ESP32.

Připojení I2C k ESP32 je následující: (viz obrázek 9)

  • SDA – GPIO 21
  • SCL – GPIO 22

Ve skutečnosti můžete použít libovolné dva piny na ESP32 pro vaše připojení I2C a definovat je v programu, ale piny GPIO 21 a 22 jsou výchozí, tak je využijeme.

Servo PCA9685 ESP32

Obrázek 9 – propojení modulu ESP32 s modulem PCA9685 a připojení serva

V některých zapojeních, která můžeme najít na internetu, jsou vodiče SDA a SCL ještě připojeny pomocí externích pull-up rezistorů k napájení 3,3 V. Myslíme si, že je to zbytečné, protože, jak ukazuje schéma z dokumentace modulu PCA9685, tento I2C modulu již pull-up rezistory obsahuje (červeně vyznačeno v obrázku č. 10)

PCA9685 schema

Obrázek 10 – Elektronické schéma modulu PCA9685

Připojit servomotor nebo více servomotorů lze ke kterémukoliv z výstupních kanálů. Když se podíváme na programový kód (viz dále), uvidíte tam, jak připojení (servo)motoru definovat a jak (servo)motor adresovat.

Pro napájení PWM spotřebiče (v našem případě serva) je třeba využít napájecí svorkovnice v horní části modulu PCA9685. Třívoltové napětí z modulu ESP (připojeno na postranní konektor) a napájecí napětí serva jsou odděleny (kromě společné země), takže lze použít téměř jakýkoliv PWM spotřebič a nehrozí poškození modulu ESP32. Koneckonců k tomuto účelu byl asi modul PCA9685 vymyšlen! 😉

My si ukážeme připojení jednoho serva typu SG90, ale už víme, že jeden modul PCA9685 nám umožní připojit takových serv šestnáct.

Kód ovládání modulu PCA9685 pomocí ESP32

Modul PCA9685 pochází od společnosti Adafruit. Kdo zná společnost Adafruit a její výrobky, jistě ví, že nejenže neprodávají nic bez rozsáhlé dokumentace, ale především i bez podpůrných knihoven. Takže je jasné, že pro ovládání modulu PCA9685 využijeme knihovnu Adafruit PWM Servo Driver od Adafruit, která funguje jak s modulem Arduinem, tak s modulem ESP32.

Knihovnu Adafruit pro PCA9685 Adafruit PWM Servo Driver můžeme získat přímo v manažéru knihoven v prostředí Arduino IDE, stejně jako knihovnu Wire, což je knihovna pro práci s I2C. Jak bylo zmíněno dříve, způsob, jak stáhnout v prostředí Arduino IDE knihovnu pomocí manažéru knihoven je popsán v předešlých článcích, proto to ani zde to již neuvádíme.

manazer knihoven PCA9685

Obrázek 11 – Použití knihovny Adafruit PWM Servo Driver od Adafruit

Následující program je ukázkou řízení serva připojeného na kanálu 0 modulu PCA9685. (Schéma je obrázku č. 9)

/* ESP32 a PCA9685 (Servo Control) */

#include <Wire.h>   // vlozeni knihovny pro I2C komunikaci
#include <Adafruit_PWMServoDriver.h>   // vlozeni knihovny modul PCA9685

Adafruit_PWMServoDriver pca9685 = Adafruit_PWMServoDriver(0x40);   // objekt pro PCA9685 (vychozi adresa)

// Definice maximalni a minimalni sirky PWM pro servomotory (celkovy rozsah 0-4095)
// hodnota 80 je pro 1ms, 600 je pro sirku pulzu 2ms
#define SERVOMIN  80   // Minimalni hodnota
#define SERVOMAX  600   // Maximalni hodnota

// Definice pripojeni servomotoru (pro vice serv lze rozsirit)
#define SER0  0   // Servo0 pripojene na vystupnim kanalu 0
int pwm0;   // Promenna pro polohu Serva 0

// funkce SETUP se spusti jednou pri stisknuti tlacitka reset nebo pri zapnuti desky.
void setup() {
  pca9685.begin();   // Inicializace PCA9685
  pca9685.setPWMFreq(50);   // Nastaveni frekvence PWM na 50 Hz
}

// funkce LOOP bezi stale dokola.
void loop() {
  for (int posDegrees = 0; posDegrees <= 180; posDegrees++) {   // Natoceni Serva0 z 0 na 180 stupnu
    pwm0 = map(posDegrees, 0, 180, SERVOMIN, SERVOMAX);   // Prevod stupnu na sirku pulzu PWM
    pca9685.setPWM(SER0, 0, pwm0);   // zapis na modul PCA9685
    delay(100);
  }

  for (int posDegrees = 180; posDegrees >= 0; posDegrees--) {   // Natoceni Serva0 z 180 na 0 stupnu
    pwm0 = map(posDegrees, 0, 180, SERVOMIN, SERVOMAX);   // Prevod stupnu na sirku pulzu PWM
    pca9685.setPWM(SER0, 0, pwm0);   // zapis na modul PCA9685
    delay(100);
  }

}

V kódu si všimněme nastavení konstant SERVOMIN a SERVOMAX, které určují maximální a minimální šířku generovaného PWM pulzu. Tyto hodnoty vycházení z následující úvahy:

Na modulu PCA9685 je určena základní frekvenci pulzů (v našem případě stanoveno na 50 Hz). Každý úsek mezi začátky následujících pulzů je rozdělen na 4096 úseků. Příkazem pca9685.setPWM() nastavíme počet těchto časových úseků, určující délku PWM pulzu (tj. po které bude výstup ve stavu HIGH).
  • Například, aby měl generovaný PWM pulz 50% délku pracovního cyklu, nastavíme hodnotu 2048 (2048 úseků bude na úrovni HIGH a zbylých 2048 úseků bude na úrovni LOW).
  • Pro 25% délku pracovního cyklu zapíšeme jen hodnotu 1024.

Konstanty SERVOMIN a SERVOMAX tedy představují počet úseků pro minimální a maximální šířku pulzu. Na tyto hodnoty se pak „přemapovává“ hodnota krajních poloh zadaných ve stupních – tedy 0 až 180 stupňů.

otacejici se servo

Obrázek 12 – Pohyb serva v rozsahu 0 až 180 stupňů.


Závěr

Opět jsme si ukázali další periférii, kterou můžeme připojit k některé z vývojových desek s modulem ESP32. Vysvětlili jsme si princip řízení servomotoru, ukázali jsme si jeho možné připojení k desce ESP32. Ovládání jsme si ukázali pomocí PWM kanálu, nebo pomocí obslužné knihovny.

V druhé části článku jsme si představili zajímavý modul PCA9685, který je určen pro PWM řízení. My jste to zde využili pro řízení serva. V některém z následujících článků bychom se k tomuto modulu ještě rádi vrátili a ukázali si jeho použití pro řízení DC motorů, což se dá například použít pro řízení ovládání robotického podvozku.

Do budoucna bychom chtěli Vám začít přinášet i některé ukázky konkrétních projektů, takže se jistě s připojením serva k modulu ESP32 nevidíme naposledy.

Reklama:
UPOZORNĚNÍ:
Nesouhlasíme s vyřazením Newtonových zákonů, Ohmova zákona a zákona zachování energie z učiva fyziky základních škol v České republice!