Здравствуйте!!!
Помогите пожалуйста доработать скетч.
Имеется оптический энкодер с алиэкспресс с разрешением 1000 импульсов (на фото).
Имеется скетч который считывает прерывания пины d2 и d3, выводит значения в порт в виде цифровых значений увеличивая и уменьшая показания на 2 000 в одну и другую сторону.
Помогите пожалуйста дописать скетч, чтобы при плавном перемещении ротора реакции не было.
При скачкообразном перемещении ротора, то есть при скачкообразном изменении значений энкодера появлялся потенциал на пине Д4.
Другими словами если ротор энкодера крутится плавно то все норм, если происходят резкие ускорения то включается функция.
Насколько я понимаю нужно дважды считывать значения энкодера через определенный промежуток времени.
Если значения в указанный период в пределах допустимых значений (установить экспериментально) то цикл повторяем.
Если значения вышли за норму то запускаем digitalwrite (4, high).
Как можно реализовать чтение значений через определенный промежуток времени.
volatile unsigned int temp, counter = 0; //This variable will increase or decrease depending on the rotation of encoder
void setup() {
Serial.begin (9600);
pinMode(2, INPUT_PULLUP); // internal pullup input pin 2
pinMode(3, INPUT_PULLUP); // internalเป็น pullup input pin 3
//Setting up interrupt
//A rising pulse from encodenren activated ai0(). AttachInterrupt 0 is DigitalPin nr 2 on moust Arduino.
attachInterrupt(0, ai0, RISING);
//B rising pulse from encodenren activated ai1(). AttachInterrupt 1 is DigitalPin nr 3 on moust Arduino.
attachInterrupt(1, ai1, RISING);
}
void loop() {
// Send the value of counter
if( counter != temp ){
Serial.println (counter);
temp = counter;
}
}
void ai0() {
// ai0 is activated if DigitalPin nr 2 is going from LOW to HIGH
// Check pin 3 to determine the direction
if(digitalRead(3)==LOW) {
counter++;
}else{
counter--;
}
}
void ai1() {
// ai0 is activated if DigitalPin nr 3 is going from LOW to HIGH
// Check with pin 2 to determine the direction
if(digitalRead(2)==LOW) {
counter--;
}else{
counter++;
}
}
Можно ещё анализировать длительность временного промежутка между изменениями счетчика, например…
Если ориентироваться на кол-во импульсов за период времени, то при болтанке или разовых скачках проблема детектирована не будет.
Огромное спасибо. Не смотря на мои очень скромные познания в програмировании с Вашими подсказками все получилось!!! Пошел пытаться дописывать код. СПАСИБО
volatile unsigned int temp, counter = 0; //This variable will increase or decrease depending on the rotation of encoder
static uint32_t old_millis = 0;
uint32_t interval = 500; // промежуток времени
int counter2;
int counter3;
void setup() {
Serial.begin (9600);
pinMode(2, INPUT_PULLUP); // internal pullup input pin 2
pinMode(3, INPUT_PULLUP); // internalเป็น pullup input pin 3
//Setting up interrupt
//A rising pulse from encodenren activated ai0(). AttachInterrupt 0 is DigitalPin nr 2 on moust Arduino.
attachInterrupt(0, ai0, RISING);
//B rising pulse from encodenren activated ai1(). AttachInterrupt 1 is DigitalPin nr 3 on moust Arduino.
attachInterrupt(1, ai1, RISING);
}
void loop() {
// Send the value of counter
if (millis() - old_millis > interval) {
counter2 = counter;
old_millis = millis();
}
if( counter != temp ){
// Serial.println (counter);
temp = counter;
// Serial.println (counter2);
counter3 = counter - counter2;
Serial.println (counter3);
}
Практические испытания показали, что Вы абсолютно правы. Одного лишь подсчета импульсов за определенный интервал не достаточно. Очень много ложных сработок.
По конструктиву устройства когда ось энкодера с ускорением движется вперед с почти таким же ускорением движется назад.
Другими словами если контролировать не только резкое движение оси вперед, но и контролировать ее движение обратно значительно уменьшится число ложных срабатываний.
Пример данных с порта (это разница значений за период времени counter3 = counter - counter2;).
858
820
0 (то есть ось остановилась и начала двигаться назад)
-42
-104
-179
-255
Подскажите пожалуйста какими командами в этом коде можно реализовать обработку данных движения оси энкодера в обратном направлении?
все просто если экодер без дребезга (оптический), далее обработка прерывания…
void encod(){
stet=millis()-th;// th перменная времени
if(stet>30){ste=1;}else{ste=10;if(stet<8){ste=100;}}//в зависимсти от скорости вращения энкодера , разное приращение
if (digitalRead(4)){val=val+ste;}else{val=val-ste;}// проверка состояния второго выхода энкодера если 1 то плюс иначе минус
encodf=1;// флаг бработки прерывания
}