Novinky: Pridal som novú sekciu na webe - Turistika
Sitepoint logo

Ako na rotačné enkodéry

Veľmi užitočná súčiastka, ak plánujete zariadenie ktoré treba nejako uživateľsky ovládať a nastavovať. V dnešnej modernej dobe IoT by sa dalo čakať ovládanie cez web/mobilnú aplikáciu, ale veľakrát stačí ručné ovládanie – ušetríme určite aj náklady. Najskôr som bojoval s HW dekodérom, ale skončil som s plne SW riešením.encsČo je rotačný enkodér? Otočný ovládač, ktorý nemá definované krajné polohy ako napr. potenciometer, plus niektoré majú aj funkciu stlačenia ako klasícke tlačítko. Určite to poznáte z autorádia, hifi systémov, alebo inej spotrebenej elektroniky. V prinícpe sú to dva spínače, a podľa smeru otočenia sa zopnú v určitom slede za sebou, pre lepšie pochopenie obrázok.ckt10_31eČasto odporúčané HW riešnie so 7474 obvodom…rotary7474Nech som robil čokoľvek (pull-up, pull-down), nefungovalo. Preto som hľadal riešenie ktoré by používalo prerušenia (INT) a umožnilo súčastné použitie viacerých enkodérov (potreboval som 3). Arduino Playground poskytuje na túto tému množstvo riešení, mne sa však osvedčilo riešenie z Buxtronix.

Zapojenie netreba snáď ani kresliť, spoločný vývod ide na zem, A a B piny sa zapoja na digitálne piny Arduina. Ešte pre vysvetlenie časť kódu v setup(). Jedná sa o priamu manipuláciu registrov MCU. PCICR nastavuje vektory prerušenia pre 3 „banky“ pinov (PCINT23:16, 15:8 a 7:0), PCMSK2 povoľuje prerušenia pre jednotlivé piny v banke 2 (PCINT7:0). Ak by ste chceli použiť iné piny, treba náležite zmeniť PCMSKx register a na záver aj tabuľka pinov (HW pin vs. PCINT).

#include <rotary.h>

Rotary r = Rotary(2, 3);
Rotary r2 = Rotary(4, 5);
Rotary r3 = Rotary(6, 7);

volatile byte mot_spd, srv1pos, srv2pos = 0;    // poloha serva, rychlost motora
byte servo_step = 1;
unsigned long tm = 0;

void setup(){
  Serial.begin(9600);                       // seriovy monitor pre debugovanie
  PCICR |= (1 << PCIE2) | (1 << PCIE1);
  PCMSK2 |= (1 << PCINT18) | (1 << PCINT19) | (1 << PCINT20) | (1 << PCINT21) | (1 << PCINT22) | (1 << PCINT23);
  sei();
  tm = millis();
}
void loop(){
  if (millis() > tm + 1000){                  // kazdu sekundu vypisat aktualny stav na COM port
    tm = millis();
    Serial.print("SRV1 = ");
    Serial.print(srv1pos);
    Serial.print(" SRV2 = ");
    Serial.print(srv2pos);
    Serial.print(" MOT_SPD = ");
    Serial.println(mot_spd);
  }
}

ISR(PCINT2_vect){                             // HW prerusenie - obsluha rotacnych enkoderov
  char result = r.process();
  char result2 = r2.process();
  char result3 = r3.process();
  if (result){
    if (result == DIR_CCW && srv1pos + servo_step <= 180) srv1pos += servo_step;
    if (result == DIR_CW && srv1pos - servo_step >= 0) srv1pos -= servo_step;
  }
  if (result2){
    if (result2 == DIR_CCW && srv2pos + servo_step <= 180) srv2pos += servo_step;
    if (result2 == DIR_CW && srv2pos - servo_step >= 0) srv2pos -= servo_step;
  }
  if (result3){
    if (result3 == DIR_CCW){
     if (mot_spd < 250) mot_spd++;
    } else {
      if (mot_spd > 0) mot_spd--;
    }
  }
}

Knižnica na stiahnutie (originál), plus kópia tu na blogu (ak by originál zmizol).


Categories:


Comments

Jedna odpoveď na na “Ako na rotačné enkodéry”

  1. […] som písal stručne o enkodéroch, a teraz v jednom projekte som ho použil na nastavenie prevádzkových premenných. Potreboval som […]

Pridaj komentár

Vaša e-mailová adresa nebude zverejnená. Vyžadované polia sú označené *