Stránka 2 z 3

Re: Enkodér

Napsal: 16 dub 2021, 10:14
od ondraN
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ů.

Re: Enkodér

Napsal: 16 dub 2021, 10:31
od Caster
onDraN má pravdu. Použít program bez přerušení je nesmysl.

Re: Enkodér

Napsal: 16 dub 2021, 11:38
od Sperhak
Myslíte to čo má arduino iba na pinoch 2,3?

Re: Enkodér

Napsal: 16 dub 2021, 12:15
od ondraN
Přesně tak, pokud je to UNO nebo jiné s CPU ATMEGA 328P

Re: Enkodér

Napsal: 16 dub 2021, 16:16
od gilhad
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

Re: Enkodér

Napsal: 16 dub 2021, 21:30
od Sperhak
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.

Re: Enkodér

Napsal: 16 dub 2021, 23:05
od Caster
V SETUP máš Serial.begin(9600);

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

Re: Enkodér

Napsal: 17 dub 2021, 06:50
od Sperhak
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.

Re: Enkodér

Napsal: 17 dub 2021, 07:05
od ondraN
Všimnul jsem si, že máš ty oscilogramy docela "chlupaté". Zkoušel jsi tam zařadit RC filtr?

Re: Enkodér

Napsal: 17 dub 2021, 07:53
od pavel1tu
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().