bool CLK, DT, prevCLK; // змінні для роботи із сигнальними виходами енкодера
byte counter_R = 0;
byte counter_G = 0;
byte counter_B = 0; // лічильник кроків енкодера
bool currentState, prevState; // змінні стану кнопки енкодера (поточний, попередній)
bool flag = 0; // спец. змінна, що сигналізує про факт натискання кнопки
int sw_counter = 0;
void setup()
{
pinMode(2, INPUT); // вивід енкодера CLK
pinMode(3, INPUT); // вивід енкодера DT
pinMode(4, INPUT_PULLUP); // кнопка SW
pinMode(9, OUTPUT); // вихід синього LED
pinMode(10, OUTPUT); // вихід зеленого LED
pinMode(11, OUTPUT); // вихід червоного LED
Serial.begin(9600);
}
void loop()
{
// Зчитуємо значення виходів енкодера
CLK = digitalRead(2); // CLK підключений до 2 виводу
DT = digitalRead(3); // DT підключений до 3 виводу
// Якщо рівень сигналу CLK низький, а у попередньому циклі він був високим
if (!CLK && prevCLK)
{
switch(sw_counter) {
case 0:
counter_R += DT ? 8 : -8;
break;
case 1:
counter_B += DT ? 8 : -8;
break;
case 2:
counter_G += DT ? 8 : -8;
break;
}
// Друкуємо поточні значення скважності ШІМ кожного з світлодіодів
Serial.println((String)"R: "+counter_R+" G: "+counter_G+" B:"+counter_B);
analogWrite(9, counter_B);
analogWrite(10, counter_G);
analogWrite(11, counter_R);
}
// Збереження поточного стану рівня сигналу CLK для використання в наступному циклі
prevCLK = CLK;
// Наступна частина коду стосується обробки натискання кнопки енкодера
currentState = digitalRead(4); // зчитування стану кнопки
if (currentState != prevState) // перевірка, чи змінився стан кнопки
{
delay(10); // чекаємо, поки не завершиться брязкіт
currentState = digitalRead(4);
}
prevState = currentState;
// при натисканні кнопки виконуємо необхідні дії
// при натисканні кнопка замикає вихід на землю (тобто 0)
if (currentState == LOW && flag == 0)
{
sw_counter++;
if(sw_counter >= 3)
sw_counter = 0;
Serial.print((String)"Натиснута кнопка: ");
switch(sw_counter) {
case 0:
Serial.println("Червона");
break;
case 1:
Serial.println("Синя");
break;
case 2:
Serial.println("Зелена");
break;
default:
Serial.println((String)"Натиснута кнопка: Error");
}
flag=1; // змінюємо значення на протилежне
}
// при відтисканні кнопки тільки змінюємо значення flag на протилежне
// при відтисканні вихід через резистор підтягується до 5В
if (currentState == HIGH && flag == 1)
flag=0; // змінюємо значення на протилежне
// Ця затримка визначає, як часто ми будемо опитувати виходи енкодера для зчитування значень
// 5 мс - це 200 Гц, такої частоти опитування достатньо для механічного енкодера
delay(5);
}