Объясните как для чайника

vat712
Offline
Зарегистрирован: 24.07.2020

Добрый день! 
Товарищи, помогите - объясните для чайника кусок кода ниже. Этот код обрабатывает поворот энкодера, но тут задействованы байтовые операции. Совершенно не могу понять как он работает.

#define CLK 4 
#define DT 2 // Тут мы объявили пины энкодера;
long pos = 0;
byte lastState = 0; // Ввели переменные
 
const int8_t increment[16] = {0, -1, 1, 0, 1, 0, 0, -1, -1, 0, 0, 1, 0, 1, -1, 0}; // Зачем нужен этот странный массив?
 
void setup() {
  Serial.begin(9600); // подключаем порт.
}
void loop() {
  byte state = digitalRead(CLK)| (digitalRead(DT) << 1); // что происходит в этих байтовых опреациях?
  if (state != lastState) {
    pos += increment[state | (lastState << 2)]; // опять таки ,что тут происходит?
    lastState = state;
    Serial.println(pos);
  }
}
Alexander
Offline
Зарегистрирован: 25.04.2010
vat712
Offline
Зарегистрирован: 24.07.2020
#define CLK 4
#define DT 2
long pos = 0;
byte lastState = 0;
const int8_t increment[16] = {0, -1, 1, 0, 1, 0, 0, -1, -1, 0, 0, 1, 0, 1, -1, 0};
void setup() {
  Serial.begin(9600);
}
void loop() {
  byte state = digitalRead(CLK)| (digitalRead(DT) << 1);
  if (state != lastState) {
    pos += increment[state | (lastState << 2)];
    lastState = state;
    Serial.println(pos);
  }
}

 

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

vat712 пишет:

 тут задействованы байтовые операции. 

Какие?

sadman41
Offline
Зарегистрирован: 19.10.2016

Сравнение байтовое вижу я.

asam
asam аватар
Offline
Зарегистрирован: 12.12.2018

ЕвгенийП пишет:

vat712 пишет:

 тут задействованы байтовые операции. 

Какие?

Cдвиг  влево. 2 штуки.

Kakmyc
Offline
Зарегистрирован: 15.01.2018

За такую обработку сигналов энкодера, да ещё и в общий доступ выложенную, карать нужно анально.

У энкодера весь код:
Если изменился сигнал на одном из выводов, то смотрим:
Сигналы стали равны - одно направление
Сигналы разноименные-другое направление.

А тут очень сложный, избыточный код, не факт что правильный и рабочий

svm
Offline
Зарегистрирован: 06.11.2016

Kakmyc пишет:
За такую обработку сигналов энкодера, да ещё и в общий доступ выложенную, карать нужно анально. У энкодера весь код: Если изменился сигнал на одном из выводов, то смотрим: Сигналы стали равны - одно направление Сигналы разноименные-другое направление. А тут очень сложный, избыточный код, не факт что правильный и рабочий

Может какой-то энкодер нестандартный, мало-ли. А так в массиве записаны все варианты состояния ног, вернее соответствующие им действия. Но разбираться с этим в пятницу, если честно лень просчитывать шестнадцать вариантов. Если все работает, то и хорошо. Если нет пробуйте другие алгоритмы. 

Izvekoff
Offline
Зарегистрирован: 02.03.2020

и здесь радужные отметились )))

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

asam пишет:

Cдвиг  влево. 2 штуки.

Это теперь "байтовые операции". Буду знать.

asam
asam аватар
Offline
Зарегистрирован: 12.12.2018

ЕвгенийП пишет:

asam пишет:

Cдвиг  влево. 2 штуки.

Это теперь "байтовые операции". Буду знать.

 

Вот же глаз замылился,  прочитал у ТС как "битовые"

BOOM
BOOM аватар
Offline
Зарегистрирован: 14.11.2018

Битовые, байтовые. Проще сначала код из «сокращённого» в «развёрнутый» переписать, тогда и понятен будет и нагляднее. 

Kakmyc
Offline
Зарегистрирован: 15.01.2018

Энкодер самый что ни на есть обычный.

Код избыточный просто.

Считывание состояния входов, сравнение с предыдущими, если изменилось, то тогда битовый сдвиг предыдущих, сложение с текущими, и полученное значение используется как элемент массива с направлением движения.

Можно записать это как то так, если не знаком с битовыми операциями:

#define CLK 4 
#define DT 2 
long pos = 0; 
byte lastState = 0; 
const int8_t increment[16] = {0, -1, 1, 0, 1, 0, 0, -1, -1, 0, 0, 1, 0, 1, -1, 0}; 
void setup() { Serial.begin(9600); } 
void loop() { 

/*альтернативный код
byte clkVal=0,dtVal=0;
clkVal=digitalRead(CLK);
if(digitalRead(DT)==1){dtVal=2;}
byte state=clkVal+dtVal;
//после чтения получим значение от 0 до 3 в зависимости от состояния входов 
*/

byte state = digitalRead(CLK)| (digitalRead(DT) << 1); 

if (state != lastState) { //если текущее состояние не равно предыдущему(что то поменялось)

/*альтернативный код
lastState=lastState*4;//равнозначно битовому сдвигу на две позиции влево
pos+=increment[state+lastState];
*/

pos += increment[state | (lastState << 2)];
 lastState = state; 
Serial.println(pos); 
} 
}