Цитата Сообщение от rovki Посмотреть сообщение
Фронты по алгоритму ловятся все ,а не один ,но кроме фронта нужного я еще всегда анализирую потенциал на противоположном входе ,что бы уменьшить влияние помех .
Рад за вас и ваш алгоритм. Но в моей PRU программе используется не ваш алгоритм.

Как и обещал, проверил на случайном вращении "виртуального энкодера".
Забегая вперёд скажу, что проблем не нашлось. Т.е. программа работает верно.

Иными словами, вращение из любого состояния в любом направлении будет отрабатывать правильно.

10'000'000 импульсов эмулируются за 2-4 секунды.

Собственно, класс "эталонного энкодера". Это тот, который выдаёт эталонные A-B импульсы.
Код:
package com.github.vlsi.pru;

import static com.github.vlsi.pru.VirtualAbEncoder.EncoderState.S01;
import static com.github.vlsi.pru.VirtualAbEncoder.EncoderState.S10;
import static com.github.vlsi.pru.VirtualAbEncoder.EncoderState.S11;

public class VirtualAbEncoder {
  private final static EncoderState[] ENCODER_STATES = EncoderState.values();

  enum EncoderState {
    S00,
    S01,
    S11,
    S10,
  }

  private EncoderState state = EncoderState.S00;
  private int count;
  private int position;

  public boolean getA() {
    return state == S10 || state == S11;
  }

  public boolean getB() {
    return state == S01 || state == S11;
  }

  public void reset() {
    state = EncoderState.S00;
    count = 0;
    position = 0;
  }

  public void left() {
    step(true);
  }

  public void right() {
    step(false);
  }

  public void step(boolean left) {
    count++;
    int diff = left ? 1 : -1;
    position += diff;
    state = getStateByOrdinal(state.ordinal() + diff);
  }

  private EncoderState getStateByOrdinal(int i) {
    int length = ENCODER_STATES.length;
    return ENCODER_STATES[(i + length) % length];
  }

  public int getPosition() {
    return position;
  }

  public int getCount() {
    return count;
  }
}
Теперь натравливаем рандомное вращение на исходную PRU программу:

Код:
  @Test
  public void drunkEncoder() {
    PRU_ABZ_ENCODER_CodeGenerator abz = new PRU_ABZ_ENCODER_CodeGenerator();

    Pru cpu = new Pru();
    CodeEmitter ce = new CodeEmitter();
    abz.accept(ce);
    cpu.setCode(ce.visitEnd());

    VirtualAbEncoder encoder = new VirtualAbEncoder();

    ThreadLocalRandom random = ThreadLocalRandom.current();
    for(int i = 0; i < 10_000_000; i++) {
      encoder.step(random.nextBoolean());

      abz.setA(cpu, encoder.getA() ? 1 : 0);
      abz.setB(cpu, encoder.getB() ? 1 : 0);
      executeBlock(cpu);
      assertEquals(abz.getCounter(cpu), encoder.getCount() & 0xffff, "counter");
      assertEquals(abz.getPosition(cpu), encoder.getPosition() & 0xffff, "position");
    }
  }
Ничего особенного не происходит, всё отрабатывает верно.