#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <Keypad.h>
// Настройки OLED дисплея
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define OLED_RESET -1
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
// Настройки матрицы кнопок
const byte ROWS = 4; // 4 строки
const byte COLS = 5; // 5 колонок
char keys[ROWS][COLS] = {
{'1', '2', '3', 'A', 'B'},
{'4', '5', '6', 'C', 'D'},
{'7', '8', '9', 'E', 'F'},
{'*', '0', '#', 'G', 'H'}
};
byte rowPins[ROWS] = {39, 37, 16, 40}; // Подключите строки матрицы к этим пинам
byte colPins[COLS] = {38, 36, 34, 21, 15}; // Изменён пин с 21 на 19
Keypad keypad = Keypad(makeKeymap(keys), rowPins, colPins, ROWS, COLS);
// Настройки энкодеров
#define ENCODER1_CLK 3
#define ENCODER1_DT 5
#define ENCODER1_SW 7
#define ENCODER2_CLK 9
#define ENCODER2_DT 11
#define ENCODER2_SW 12
#define ENCODER3_CLK 1
#define ENCODER3_DT 2
#define ENCODER3_SW 4
// Переменные для хранения состояний энкодеров
volatile int encoder1Pos = 0;
volatile int encoder2Pos = 0;
volatile int encoder3Pos = 0;
// Хранилище предыдущих состояний для энкодеров
volatile int lastEncoder1Pos = 0;
volatile int lastEncoder2Pos = 0;
volatile int lastEncoder3Pos = 0;
volatile int lastEncoder1CLKState = LOW;
volatile int lastEncoder2CLKState = LOW;
volatile int lastEncoder3CLKState = LOW;
// Хранилище последнего нажатого ключа
char lastKey = '\0'; // Хранение последнего нажатого ключа
bool keyChanged = false; // Флаг для отслеживания изменений ключа
void setup() {
Serial.begin(115200);
// Инициализация OLED дисплея
if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { // Используется SSD1306_SWITCHCAPVCC
Serial.println(F("SSD1306 allocation failed"));
for (;;);
}
display.display();
delay(2000);
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(SSD1306_WHITE);
// Настройка пинов для энкодеров
pinMode(ENCODER1_CLK, INPUT_PULLUP);
pinMode(ENCODER1_DT, INPUT_PULLUP);
pinMode(ENCODER1_SW, INPUT_PULLUP);
pinMode(ENCODER2_CLK, INPUT_PULLUP);
pinMode(ENCODER2_DT, INPUT_PULLUP);
pinMode(ENCODER2_SW, INPUT_PULLUP);
pinMode(ENCODER3_CLK, INPUT_PULLUP);
pinMode(ENCODER3_DT, INPUT_PULLUP);
pinMode(ENCODER3_SW, INPUT_PULLUP);
// Настройка прерываний для энкодеров
attachInterrupt(digitalPinToInterrupt(ENCODER1_CLK), readEncoder1, CHANGE);
attachInterrupt(digitalPinToInterrupt(ENCODER2_CLK), readEncoder2, CHANGE);
attachInterrupt(digitalPinToInterrupt(ENCODER3_CLK), readEncoder3, CHANGE);
}
void loop() {
// Обработка матрицы кнопок
char key = keypad.getKey();
if (key != lastKey) { // Проверяем, изменился ли нажатый ключ
lastKey = key;
keyChanged = true;
}
// Проверка изменений значений энкодеров
if (encoder1Pos != lastEncoder1Pos || encoder2Pos != lastEncoder2Pos || encoder3Pos != lastEncoder3Pos) {
lastEncoder1Pos = encoder1Pos;
lastEncoder2Pos = encoder2Pos;
lastEncoder3Pos = encoder3Pos;
keyChanged = true;
}
// Обновление дисплея
if (keyChanged) {
display.clearDisplay();
display.setCursor(0, 0);
display.print("Encoder 1: ");
display.print(encoder1Pos);
display.setCursor(0, 10);
display.print("Encoder 2: ");
display.print(encoder2Pos);
display.setCursor(0, 20);
display.print("Encoder 3: ");
display.print(encoder3Pos);
// Отступ для отображения нажатых кнопок
int offset = SCREEN_WIDTH / 2 + 20; // увеличен отступ
display.setCursor(offset, 0);
display.print("Key: ");
display.print(lastKey);
display.display(); // Обновляем дисплей только при изменении
keyChanged = false; // Сбрасываем флаг изменения ключа
}
}
void readEncoder1() {
int clkState = digitalRead(ENCODER1_CLK);
int dtState = digitalRead(ENCODER1_DT);
if (clkState != lastEncoder1CLKState) {
if (dtState != clkState) {
encoder1Pos++;
} else {
encoder1Pos--;
}
lastEncoder1CLKState = clkState;
}
}
void readEncoder2() {
int clkState = digitalRead(ENCODER2_CLK);
int dtState = digitalRead(ENCODER2_DT);
if (clkState != lastEncoder2CLKState) {
if (dtState != clkState) {
encoder2Pos++;
} else {
encoder2Pos--;
}
lastEncoder2CLKState = clkState;
}
}
void readEncoder3() {
int clkState = digitalRead(ENCODER3_CLK);
int dtState = digitalRead(ENCODER3_DT);
if (clkState != lastEncoder3CLKState) {
if (dtState != clkState) {
encoder3Pos++;
} else {
encoder3Pos--;
}
lastEncoder3CLKState = clkState;
}
}