Есть вопрос. Можно ли обрабатывать нажатие на энкодер в функции прерывания?
Есть вопрос. Можно ли обрабатывать нажатие на энкодер в функции прерывания?
Можно конечно.
У меня есть код для энкодера с обработкой нажатия и использует всего 1 прерывание
Последний раз редактировалось Chip; 19.04.2018 в 23:16.
Нет не одну, но прерываний не бывает много их всегда не хватаетАрдуина может обрабатывать только одну функцию прерывания ?
Скетч взял от стробоскопа http://cyber-place.ru/showthread.php?t=2703
Энкодер можно вращать без нажатия изменяя чавстоту стробоскопа и вращать с нажатием изменяется длительность импульса
Визуально изменения можно наблюдать на светодиоде D13
Если что то будет не понятно, разъясню
PHP код:
//Скетч от Cyber-Place.ru
// Выводы ЭНКОДЕРА
#define CLK 3 // Clock Подключаем к INT1, нельзя переназначать
#define DT 4 // второй вывод энкодера
#define SW 5 // switch кнопка энкодера
#define Min 1 // минимальное значение
#define Max 20000 //максимальное значение
#define led_pin 12 // подключен светодиод
#define coil_pin A0
#define step_freq 1 // шаг изменения частоты плавно 0,1гц
#define step_timelght 100 // шаг приращивания в мкс
volatile int freq = 250; // частота в Гц умноженная на 10, для более плавной настройки
volatile uint32_t paus, time_light=2000; // время свечения светодиода в мкс
uint32_t oldcount;
boolean DT_last; // последнее состояние энкодера
void setup()
{
pinMode(CLK,INPUT_PULLUP); // Clock Подключаем к INT1, нельзя переназначать
pinMode(DT, INPUT_PULLUP); // второй вывод энкодера
pinMode(SW, INPUT_PULLUP); // кнопка энкодера
pinMode(led_pin, OUTPUT); // управление симистором
pinMode(coil_pin, OUTPUT);
attachInterrupt(1, encoderTick, CHANGE); // прерывания от Энкодера
DT_last = digitalRead(CLK); // считываем положение CLK
}
void loop()
{
paus=5000000/freq;
digitalWrite(coil_pin, 1);
digitalWrite(led_pin, 1);
oldcount = micros();
while( (micros() - oldcount) < time_light){} // длительность импульса выдержки
digitalWrite(led_pin, 0);
while( (micros() - oldcount) < paus){} // положительный полупериод
digitalWrite(coil_pin, 0);
oldcount = micros();
while( (micros() - oldcount) < paus){} //отрицательный полупериод
}
//********************обработчики прерываний Энкодера*******************************
void encoderTick() // Обратка прерываний от Энкодера
{
uint8_t DT_now = digitalRead(CLK); // считываем текущее положение CLK
if (DT_now != DT_last && digitalRead(SW)) // если предыдущее и текущее положение не равны, значит был поворот
{
if (digitalRead(DT) != DT_now) // если DT не равен CLK, значит вращение по часовой стрелке
{
if( freq < Max ) freq += step_freq; // прибавить
} else { // если DT равен CLK, значит вращение против часовой
if( freq > Min ) freq -= step_freq; // убавить
}
} else
if (DT_now != DT_last && !digitalRead(SW)) //если нажата кнопка и было вращение
{
if (digitalRead(DT) != DT_now) // если DT не равен CLK, значит вращение по часовой стрелке
{
if( time_light < paus ) { time_light += step_timelght; } // убавить длительность
} else if( time_light > 0 ) time_light -= step_timelght; // прибавить длительность импульса выдержки/
}
DT_last = DT_now; // сохранить положение CLK для следующей проверки
}
Последний раз редактировалось Chip; 20.04.2018 в 11:34.
А если нужно отработать нажатие на вал энкодера как на кнопку (нажал - отпустил) , функция прерывания будет вызываться только при изменении DT . Значит кнопку энкодера нужно тоже подключить к прерыванию?
PHP код:
#define CLK 4
#define DT 3
#define SW 2
long count = 0;
boolean DT_1, DT_2;
void setup() {
Serial.begin (9600);
pinMode (CLK, INPUT);
pinMode (DT, INPUT);
pinMode (SW, INPUT_PULLUP);
attachInterrupt(1, encoder, CHANGE);
attachInterrupt(0, encoderPress, CHANGE); // если обозначить новое прерывание таким способом ( выдаёт ошибку)
DT_2 = digitalRead(DT);
}
void loop() {
Serial.println(count);
}
void encoder() {
DT_1 = digitalRead(DT);
if (DT_1 != DT_2) {
if (digitalRead(CLK) != DT_1) {
count ++;
} else {
count --;
}
}
DT_2 = DT_1;
}
void encoderPress() {
if(!digitalRead(SW)) {
count += 10;
}
}
Можно подключить к прерыванию, но можно и в главном цикле обрабатывать
Вот , как ввести 2-ю функцию прерывания параллельно первой ?
Прерывание INT0 INT1 работают независимо друг от друга
Эту тему просматривают: 5 (пользователей: 0 , гостей: 5)