Сообщение от
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");
}
}
Ничего особенного не происходит, всё отрабатывает верно.