ESP32 i servo motor SG90: vežba povezivanja i upravljanja

Lekcija 21 od 28 · Arduino i ESP32

U lekciji servo motor sa ESP32 videli smo po čemu se servo na ESP32 razlikuje od Arduina i probali Sweep program. Ovo je praktična vežba: korak po korak povezujemo mali servo motor SG90, zadajemo mu uglove, upravljamo njime potenciometrom i iz Serial Monitora.

ESP32 i servo motor SG90 povezani žicama
Vežba: ESP32 i servo motor SG90

Servo motor SG90

Servo motor SG90: pinovi, unutrašnjost i podaci
Servo motor SG90: pinovi, unutrašnjost i podaci
  • U kućištu su mali DC motor, zupčanici i potenciometar koji meri položaj osovine – zato servo „zna“ gde se nalazi.
  • Ugao se zadaje impulsom koji se ponavlja 50 puta u sekundi: impuls od oko 0,5 ms je 0°, 1,5 ms je 90°, a oko 2,4 ms je 180°.
  • SG90 radi na 4,8–6 V, okreće se oko 180° i ima obrtni moment oko 1,8 kg·cm – dovoljno za rampu, pokazivač ili malu ruku robota.

Povezivanje

Žica servo motoraZnačenjeESP32
smeđa (ili crna)GNDGND
crvenanapajanjeVIN (5 V sa USB-a) ili spoljni izvor 5 V
narandžasta (ili žuta)signalGPIO13
Žice servo motora na pinovima ESP32: GND, VIN i GPIO13
Žice servo motora na pinovima ESP32: GND, VIN i GPIO13
Napajanje: servo u trenutku pokretanja troši i više stotina mA. Ne napajaj ga sa pina 3V3. Za jedan SG90 bez opterećenja dovoljan je pin VIN (5 V sa USB kabla). Za veći teret ili više servo motora koristi spoljni izvor 5 V i obavezno spoj njegov GND sa GND pinom ESP32.
Detalj povezivanja: signalna žica na GPIO13
Detalj povezivanja: signalna žica na GPIO13

Korak 1: zadati uglovi

Instaliraj biblioteku ESP32Servo (Library Manager). Obična biblioteka Servo.h za Arduino na ESP32 ne radi.

// ESP32 – servo motor SG90: zadati uglovi
// Biblioteka: ESP32Servo (Library Manager)
#include <ESP32Servo.h>

const int SERVO_PIN = 13;       // signalna (narandžasta) žica servo motora
Servo servo;

void setup() {
  servo.setPeriodHertz(50);              // standardni servo signal: 50 Hz
  servo.attach(SERVO_PIN, 500, 2400);    // impuls 0,5 ms = 0°, 2,4 ms = 180°
}

void loop() {
  servo.write(0);               // levo
  delay(1000);
  servo.write(90);              // sredina
  delay(1000);
  servo.write(180);             // desno
  delay(1000);
  servo.write(90);
  delay(1000);
}

U attach(pin, 500, 2400) zadajemo najkraći i najduži impuls u mikrosekundama. Ako servo na 0° ili 180° „zuji“ i gura se, smanji opseg (npr. 600 i 2300).

Korak 2: upravljanje potenciometrom

Potenciometar: krajnje nožice na 3V3 i GND, srednja na GPIO34. Okretanjem potenciometra okreće se i servo – kao kod Arduino vežbe „Knob“.

// ESP32 – potenciometar upravlja servo motorom
#include <ESP32Servo.h>

const int SERVO_PIN = 13;
const int POT_PIN = 34;         // srednja nožica potenciometra (ADC1)
Servo servo;

void setup() {
  Serial.begin(115200);
  servo.setPeriodHertz(50);
  servo.attach(SERVO_PIN, 500, 2400);
}

void loop() {
  int vrednost = analogRead(POT_PIN);            // 0 .. 4095
  int ugao = map(vrednost, 0, 4095, 0, 180);     // 0 .. 180 stepeni
  servo.write(ugao);
  Serial.print("Ugao: ");
  Serial.println(ugao);
  delay(20);
}

Ako servo podrhtava iako ne diraš potenciometar, to je šum analognog ulaza. Pomaže da ugao menjaš samo kada se razlikuje od prethodnog za bar 2°.

Korak 3: ugao iz Serial Monitora

U Serial Monitoru upiši broj (npr. 45) i pritisni Enter – servo se okrene na taj ugao. Tako lako proveravamo da li je servo dobro podešen.

// ESP32 – ugao servo motora upisuje se u Serial Monitor
#include <ESP32Servo.h>

const int SERVO_PIN = 13;
Servo servo;

void setup() {
  Serial.begin(115200);
  servo.setPeriodHertz(50);
  servo.attach(SERVO_PIN, 500, 2400);
  servo.write(90);
  Serial.println("Upisi ugao od 0 do 180 i pritisni Enter:");
}

void loop() {
  if (Serial.available() > 0) {
    int ugao = Serial.parseInt();          // čita ceo broj iz poruke
    while (Serial.available() > 0) {
      Serial.read();                       // odbacujemo ostatak reda (Enter)
    }
    if (ugao >= 0 && ugao <= 180) {
      servo.write(ugao);
      Serial.print("Servo je na ");
      Serial.print(ugao);
      Serial.println(" stepeni");
    } else {
      Serial.println("Ugao mora biti od 0 do 180!");
    }
  }
}

Serial.parseInt() čita cifre iz poruke i pretvara ih u broj. Pošto na kraju poruke stoji znak za novi red, ostatak čitamo i odbacujemo.

Servo motor tokom Sweep programa
Servo motor tokom Sweep programa

Pregled vežbe

Pregled vežbe: servo motor SG90 i ESP32 na jednoj strani
Cela vežba na jednoj strani (pogodno za štampu)

Zadaci za vežbu

  1. Napiši funkciju idiNa(od, do, pauza) koja pomera servo sporo, stepen po stepen.
  2. Dodaj taster na GPIO15: svaki pritisak okreće servo za 30° više (posle 180° vraća se na 0°).
  3. Napravi „merač“: servo pokazuje osvetljenje sa LDR senzora (mrak = 0°, svetlo = 180°).
  4. Upravljaj servo motorom nagibom – uz akcelerometar iz lekcije akcelerometar i magnetometar.
Rešenje: sporo pomeranje servo motora
// Zadatak – servo se pomera sporo, korak po korak, i javlja položaj
#include <ESP32Servo.h>

const int SERVO_PIN = 13;
Servo servo;

void idiNa(int odUgla, int doUgla, int pauzaMs) {
  int korak = (doUgla > odUgla) ? 1 : -1;
  for (int u = odUgla; u != doUgla + korak; u += korak) {
    servo.write(u);
    delay(pauzaMs);             // veća pauza = sporije kretanje
  }
}

void setup() {
  Serial.begin(115200);
  servo.setPeriodHertz(50);
  servo.attach(SERVO_PIN, 500, 2400);
}

void loop() {
  idiNa(0, 180, 15);
  Serial.println("Stigao na 180");
  delay(500);
  idiNa(180, 0, 30);            // nazad duplo sporije
  Serial.println("Stigao na 0");
  delay(500);
}

Proveri znanje

Otvori kviz

Kviz: servo motor SG90 i ESP32

1. Koja žica servo motora SG90 je signalna?




2. Koju biblioteku koristimo za servo na ESP32?




3. Odakle napajamo servo motor?




4. Šta radi map(vrednost, 0, 4095, 0, 180)?