Enkodér

ondraN
Příspěvky: 932
Registrován: 08 srp 2019, 20:01
Reputation: 0

Re: Enkodér

Příspěvek od ondraN » 16 dub 2021, 10:14

Nebo si napsat jednoduchý ovladač s použitím interruptu. Ten by měl být tak rychlý, že by mu nevadil ani malý fázový posun průběhů.

Uživatelský avatar
Caster
Příspěvky: 380
Registrován: 11 zář 2019, 09:02
Reputation: 0

Re: Enkodér

Příspěvek od Caster » 16 dub 2021, 10:31

onDraN má pravdu. Použít program bez přerušení je nesmysl.

Sperhak
Příspěvky: 46
Registrován: 22 čer 2018, 19:49
Reputation: 0

Re: Enkodér

Příspěvek od Sperhak » 16 dub 2021, 11:38

Myslíte to čo má arduino iba na pinoch 2,3?

ondraN
Příspěvky: 932
Registrován: 08 srp 2019, 20:01
Reputation: 0

Re: Enkodér

Příspěvek od ondraN » 16 dub 2021, 12:15

Přesně tak, pokud je to UNO nebo jiné s CPU ATMEGA 328P

Uživatelský avatar
gilhad
Příspěvky: 779
Registrován: 07 bře 2018, 11:22
Reputation: 0

Re: Enkodér

Příspěvek od gilhad » 16 dub 2021, 16:16

Lepe receno - Arduino to zminuje jen pro ty dva piny, ale atmega386 umi interrupty pro podstatne vic pinu (skoro vsechny), jen se to dela trosku sloziteji, viz napriklad
https://sites.google.com/site/qeewiki/b ... -atmega328

Sperhak
Příspěvky: 46
Registrován: 22 čer 2018, 19:49
Reputation: 0

Re: Enkodér

Příspěvek od Sperhak » 16 dub 2021, 21:30

Tak som si našiel tento kód

Kód: Vybrat vše


// Used for generating interrupts using CLK signal
const int pinA = 2;

// Used for reading DT signal
const int pinB = 3;

// Keep track of last rotary value
int lastCount = 50;

// Updated by the ISR (Interrupt Service Routine)
volatile int virtualPosition = 50;

// Updated by ISR for each pin
volatile bool pinAStateHigh;
volatile bool pinBStateHigh;

// Old values of pin state so we can compare
bool oldPinAStateHigh;
bool oldPinBStateHigh;

// Delay to counteract switch bounce (milliseconds)
char bounce = 10;

// ------------------------------------------------------------------
// INTERRUPT     INTERRUPT     INTERRUPT     INTERRUPT     INTERRUPT
// ------------------------------------------------------------------
void isrA ()  {
  static unsigned long lastInterruptTimeA = 0;
  unsigned long interruptTimeA = millis();

  // If interrupts come faster than Xms, assume it's a bounce and ignore
  if (interruptTimeA - lastInterruptTimeA > bounce) {

    // We are here because pinA has CHANGED
    pinAStateHigh = !pinAStateHigh;
    //pinAStateHigh = digitalRead(pinA) == HIGH;

    // Don't do this for real!
    //Serial.print("\nPin A state="); Serial.print(pinAStateHigh ? "HIGH" : "LOW");
    //Serial.print(" (Pin B state="); Serial.print(pinBStateHigh ? "HIGH)" : "LOW)");
  }

  // Keep track of when we were here last
  lastInterruptTimeA = interruptTimeA;
}

void isrB ()  {
  static unsigned long lastInterruptTimeB = 0;
  unsigned long interruptTimeB = millis();

  // If interrupts come faster than Xms, assume it's a bounce and ignore
  if (interruptTimeB - lastInterruptTimeB > bounce) {

    // We are here because pinB has CHANGED
    pinBStateHigh = !pinBStateHigh;
    //pinBStateHigh = digitalRead(pinB) == HIGH;

    // Don't do this for real!
    //Serial.print("\nPin B state="); Serial.print(pinBStateHigh ? "HIGH" : "LOW");
    //Serial.print(" (Pin A state="); Serial.print(pinAStateHigh ? "HIGH)" : "LOW)");
  }

  // Keep track of when we were here last
  lastInterruptTimeB = interruptTimeB;
}

// ------------------------------------------------------------------
// SETUP    SETUP    SETUP    SETUP    SETUP    SETUP    SETUP
// ------------------------------------------------------------------
void setup() {
  // Just whilst we debug, view output on serial monitor
  Serial.begin(9600);

  // Rotary pulses are INPUTs
  pinMode(pinA, INPUT);
  pinMode(pinB, INPUT);

  // Set initial state of PinA & PinB by reading the pins
  pinAStateHigh = digitalRead(pinA) == HIGH;
  pinBStateHigh = digitalRead(pinB) == HIGH;
  Serial.print("Initial state Pin A = "); Serial.println(pinAStateHigh ? "HIGH" : "LOW");
  Serial.print("Initial state Pin B = "); Serial.println(pinBStateHigh ? "HIGH" : "LOW");

  // So we remember what the state was (can detect the change)
  oldPinAStateHigh = pinAStateHigh;
  oldPinBStateHigh = pinBStateHigh;

  // Attach the routine to service the interrupts
  attachInterrupt(digitalPinToInterrupt(pinA), isrA, CHANGE);
  attachInterrupt(digitalPinToInterrupt(pinB), isrB, CHANGE);

  // Ready to go!
  Serial.println("Start");
}

// ------------------------------------------------------------------
// MAIN LOOP     MAIN LOOP     MAIN LOOP     MAIN LOOP     MAIN LOOP
// ------------------------------------------------------------------
void loop() {
 
  // Pin A changed? What direction?
  if (pinAStateHigh != oldPinAStateHigh) {

    // Pin A is HIGH
    if (pinAStateHigh) {
      // Pin B is LOW
      if (!pinBStateHigh) {
        // Clockwise
        virtualPosition++;
      }
      else {
        // Anticlockwise
        virtualPosition--;
      }
    } else {
      // Pin A just went low and B is HIGH
      if (pinBStateHigh) {
        // Clockwise
        virtualPosition++;
      }
      else {
        // Anticlockwise
        virtualPosition--;
      }
    }

    // Keep track of state of Pin A
    oldPinAStateHigh = pinAStateHigh;
  }

  // Pin B changed? What direction?
  if (pinBStateHigh != oldPinBStateHigh) {
    if (pinBStateHigh) {
      if (pinAStateHigh) {
        virtualPosition++;
      }
      else {
        virtualPosition--;
      }
    } else {
      // Pin B just went low
      if (!pinAStateHigh) {
        virtualPosition++;
      }
      else {
        virtualPosition--;
      }
    }
    oldPinBStateHigh = pinBStateHigh;
  }

  // If the current rotary switch position has changed then update everything
  if (virtualPosition != lastCount) {

    // Write out to serial monitor the value and direction
    Serial.print(virtualPosition > lastCount ? " Up:" : " Down:");
    Serial.println(virtualPosition);

    // Keep track of this new value
    lastCount = virtualPosition ;
  }

}

Využíva ten interupt. zistil som že ked enkoderom hýbem pomali tak to funguje. No ked skúsim trocha rýchlejšie už to blbne.Potreboval by som rýchlosť len 100rpm čo nieje tak vela ale blbne to už ovela skôr.

Uživatelský avatar
Caster
Příspěvky: 380
Registrován: 11 zář 2019, 09:02
Reputation: 0

Re: Enkodér

Příspěvek od Caster » 16 dub 2021, 23:05

V SETUP máš Serial.begin(9600);

Zkusil bych zvýšit rychlost vypisování na Serial.begin(115200);

Sperhak
Příspěvky: 46
Registrován: 22 čer 2018, 19:49
Reputation: 0

Re: Enkodér

Příspěvek od Sperhak » 17 dub 2021, 06:50

Skúsim ale nemyslim si že to pomôže. Ono niekedy to zmeni smer niekedy to par krat zasebou posle to iste cislo. Keby nestihala komunikacia asi by vynechavalo riadky. Ale skusim zato nic nedam.

ondraN
Příspěvky: 932
Registrován: 08 srp 2019, 20:01
Reputation: 0

Re: Enkodér

Příspěvek od ondraN » 17 dub 2021, 07:05

Všimnul jsem si, že máš ty oscilogramy docela "chlupaté". Zkoušel jsi tam zařadit RC filtr?

Uživatelský avatar
pavel1tu
Příspěvky: 2054
Registrován: 26 říj 2017, 08:28
Reputation: 0
Bydliště: Trutnov
Kontaktovat uživatele:

Re: Enkodér

Příspěvek od pavel1tu » 17 dub 2021, 07:53

Sperhak píše:
17 dub 2021, 06:50
Skúsim ale nemyslim si že to pomôže. Ono niekedy to zmeni smer niekedy to par krat zasebou posle to iste cislo. Keby nestihala komunikacia asi by vynechavalo riadky. Ale skusim zato nic nedam.
Nejde o komunikaci - aby stíhala,
ale dokud to odesílá něco na port, zbytek stojí - jako kdyby jsi použil delay().
UNO, NANO, Mikro, PRO mini, DUE, ESP32S2, RPi PICO
Pavel1TU
"Správně napsaný kod lze číst jako knihu"

Odpovědět

Kdo je online

Uživatelé prohlížející si toto fórum: Žádní registrovaní uživatelé a 5 hostů