#define EB_DEB_TIME 50 // таймаут гашения дребезга кнопки (кнопка)
//#include <Mouse.h>
#include "EncButton.h"
//#include "Keyboard.h"
#include <EEPROM.h>
#include <ArduinoJson.h>
// Определение кнопок
struct ButtonDB {
int pin;
String value;
ButtonDB(int p)
: pin(p), value("None") {}
};
ButtonDB buttons[12] = {
ButtonDB(5), ButtonDB(6), ButtonDB(7), ButtonDB(8), ButtonDB(9), ButtonDB(10),
ButtonDB(16), ButtonDB(14), ButtonDB(15), ButtonDB(A2), ButtonDB(2), ButtonDB(3)
};
//, Button(2), Button(3)
Button btns[10] = {
Button(5), Button(6), Button(7), Button(8), Button(9), Button(10),
Button(16), Button(14), Button(15), Button(A2)
};
//Button b0(5);
Button btn_swap(4); // Кнопка для смены профилей
const int joyX = A0; // Пин для оси X джойстика
const int joyY = A1; // Пин для оси Y джойстика
int xAxis, yAxis;
EncButton eb(2, 3, 4);
int currentProfile = 1; // Текущий профиль
// Функция для чтения из EEPROM
String readFromEEPROM(int address) {
String value = "";
char c;
while ((c = EEPROM.read(address++)) != '\0') {
value += c;
}
return value;
}
// Функция для записи в EEPROM
void writeToEEPROM(int address, const String &value) {
for (int i = 0; i < value.length(); i++) {
EEPROM.write(address++, value[i]);
}
EEPROM.write(address, '\0'); // Запись терминального символа
}
// Чтение всех кнопок из EEPROM в button_db для текущего профиля
void loadButtonValues() {
int offset = (currentProfile - 1) * 2400; // Смещение для каждого профиля
for (int i = 0; i < 12; i++) {
buttons[i].value = readFromEEPROM(i * 200 + offset);
}
}
// Запись всех кнопок в EEPROM из button_db для текущего профиля
void saveButtonValues() {
int offset = (currentProfile - 1) * 2400; // Смещение для каждого профиля
for (int i = 0; i < 12; i++) {
writeToEEPROM(i * 200 + offset, buttons[i].value);
}
}
String getButtonValuesAsJson(int profile) {
StaticJsonDocument<1024> doc;
doc["profile"] = profile;
int offset = (profile - 1) * 2400; // Смещение для каждого профиля
for (int i = 0; i < 12; i++) {
doc["button_" + String(i + 1)] = readFromEEPROM(i * 200 + offset);
}
String output;
serializeJson(doc, output);
return output;
}
// Обновление button_db из JSON строки с учетом профиля
void updateButtonValuesFromJson(const String &json) {
StaticJsonDocument<2048> doc;
deserializeJson(doc, json);
if (doc.containsKey("profile")) {
currentProfile = doc["profile"].as<int>();
}
for (int i = 0; i < 12; i++) {
String key = "button_" + String(i + 1);
if (doc.containsKey(key)) {
buttons[i].value = doc[key].as<String>();
}
}
saveButtonValues(); // Сохранение обновленных значений в EEPROM
Serial.println("save_complete");
}
#define INIT_FLAG_ADDRESS 5000 // Адрес в EEPROM для хранения флага инициализации
void initializeEEPROM() {
byte initFlag = EEPROM.read(INIT_FLAG_ADDRESS);
// Если флаг не установлен, значит это первая загрузка
if (initFlag != 0xAA) {
// Инициализация профиля 1
currentProfile = 1;
buttons[0].value = "ctrl + z";
buttons[1].value = "ctrl + shift + z";
buttons[2].value = "ctrl + a";
buttons[3].value = "alt + tab";
buttons[4].value = "None";
buttons[5].value = "None";
buttons[6].value = "None";
buttons[7].value = "None";
buttons[8].value = "None";
buttons[9].value = "None";
buttons[10].value = "[";
buttons[11].value = "]";
saveButtonValues();
// Инициализация профиля 2
currentProfile = 2;
buttons[0].value = "None";
buttons[1].value = "None";
buttons[2].value = "None";
buttons[3].value = "None";
buttons[4].value = "None";
buttons[5].value = "None";
buttons[6].value = "None";
buttons[7].value = "None";
buttons[8].value = "None";
buttons[9].value = "None";
buttons[10].value = "None";
buttons[11].value = "None";
saveButtonValues();
// Возврат к первому профилю
currentProfile = 1;
// Устанавливаем флаг инициализации
EEPROM.write(INIT_FLAG_ADDRESS, 0xAA);
}
}
void setup() {
Serial.begin(9600);
Serial.println("Start");
// Настройка осей джойстика как входов
pinMode(joyX, INPUT);
pinMode(joyY, INPUT);
// Инициализация библиотеки Mouse
//Mouse.begin();
initializeEEPROM(); // Инициализация EEPROM при первой загрузке
loadButtonValues(); // Загрузка значений кнопок из EEPROM для текущего профиля
}
void loop() {
// Обработка входящих данных по Serial
if (Serial.available() > 0) {
String input = Serial.readString();
if (input.startsWith("GET_")) {
String profileStr = input.substring(4); // Get the part after "GET_"
int prof = profileStr.toInt();
Serial.println(getButtonValuesAsJson(prof));
} else if (input.startsWith("{")) {
updateButtonValuesFromJson(input);
}
}
Serial.println("button tick start");
// Обработка нажатий кнопок
for (int i = 0; i < 12; i++) {
btns[i].tick();
if (btns[i].click()) {
Serial.print("btn ");
Serial.print(i + 1);
Serial.print(" click! ");
Serial.println(buttons[i].value);
if (buttons[i].value != "None") {
parseAndPress(buttons[i].value);
}
}
}
Serial.println("button tick end");
eb.tick();
if (eb.left()) { //10 (11 на картинке)
if (buttons[10].value != "None") {
parseAndPress(buttons[10].value);
}
}
if (eb.right()) { //11 (12 на картинке)
if (buttons[11].value != "None") {
parseAndPress(buttons[11].value);
}
}
// Обработка переключения профилей
//btn_swap.tick();
if (eb.release()) {
currentProfile = (currentProfile == 1) ? 2 : 1;
Serial.print("Switched to profile ");
Serial.println(currentProfile);
loadButtonValues(); // Загрузка значений кнопок для нового профиля
}
// Считываем значения осей джойстика
xAxis = analogRead(joyX);
yAxis = analogRead(joyY);
// Проверяем положение джойстика по оси Y
// Диапазон значений может варьироваться в зависимости от конкретного джойстика
if (yAxis < 100) {
// Если джойстик направлен вверх (мышь скроллит вверх)
//Mouse.move(0, 0, -1); // Изменение параметра (3) для скорости скролла
delay(50); // Задержка для стабилизации
} else if (yAxis > 900) {
// Если джойстик направлен вниз (мышь скроллит вниз)
//Mouse.move(0, 0, 1); // Изменение параметра (3) для скорости скролла
delay(50); // Задержка для стабилизации
} else if (xAxis > 900) {
// Если джойстик направлен вверх (мышь скроллит вверх)
//Keyboard.press(KEY_LEFT_CTRL);
//Mouse.move(0, 0, -1); // Изменение параметра (3) для скорости скролла
delay(50); // Задержка для стабилизации
//Keyboard.releaseAll();
} else if (xAxis < 100) {
// Если джойстик направлен вниз (мышь скроллит вниз)
//Keyboard.press(KEY_LEFT_CTRL);
//Mouse.move(0, 0, 1); // Изменение параметра (3) для скорости скролла
delay(50); // Задержка для стабилизации
//Keyboard.releaseAll();
}
// Задержка между итерациями для стабилизации работы
delay(10);
}
void parseAndPress(String keyCombo) {
// Очищаем нажатые клавиши
//Keyboard.releaseAll();
// Обрабатываем комбинации клавиш
if (keyCombo.indexOf("ctrl") != -1) {
//Keyboard.press(KEY_LEFT_CTRL);
}
if (keyCombo.indexOf("alt") != -1) {
//Keyboard.press(KEY_LEFT_ALT);
}
if (keyCombo.indexOf("shift") != -1) {
//Keyboard.press(KEY_LEFT_SHIFT);
}
// Нажимаем основную клавишу
for (char c : keyCombo) {
if (c == ' ') continue; // Игнорируем пробелы
if (c == '+') continue; // Игнорируем знак "+"
// Обработка отдельных символов
if (c >= 'a' && c <= 'z') {
//Keyboard.press(c);
} else if (c >= '0' && c <= '9') {
//Keyboard.press(c);
}
}
// Отпускаем все клавиши
//Keyboard.releaseAll();
}