#include <LiquidCrystal_I2C.h>
#include <Keypad.h>
#include <EEPROM.h>
#include <etl/vector.h>
const int MAX_NUMS = 10;
etl::vector<int, MAX_NUMS> storedNumbers;
// ---------- Настройка матричной клавиатуры 4x4 ----------
const byte ROWS = 4;
const byte COLS = 4;
char keys[ROWS][COLS] = {
{'1', '2', '3', 'A'},
{'4', '5', '6', 'B'},
{'7', '8', '9', 'C'},
{'*', '0', '#', 'D'}
};
byte rowPins[ROWS] = {5, 4, 3, 2}; // строки (входы с pull-up)
byte colPins[COLS] = {A3, A2, A1, A0}; // столбцы (выходы)
Keypad keypad = Keypad(makeKeymap(keys), rowPins, colPins, ROWS, COLS);
LiquidCrystal_I2C lcd(0x27, 16, 2);
String inputStr = "";
bool isStoring = true;
String currentInput = "";
const int EEPROM_ADDR= 0;
void setup() {
Serial.begin(115200);
lcd.init();
lcd.backlight();
lcd.print("Borders");
delay(1500);
lcd.clear();
loadFromEEPROM();
updateDisplay();
}
void loop() {
char key = keypad.getKey();
if (key) {
handleKey(key);
}
}
void handleKey(char key) {
if (isStoring) {
if (isdigit(key)) {
if (inputStr.length() < 4) inputStr += key;
updateInputLine();
}
else if (key == 'B') {
if (inputStr.length() > 0) inputStr.remove(inputStr.length()-1);
updateInputLine();
}
else if (key == '#') {
storedNumbers.clear();
inputStr = "";
saveToEEPROM();
lcd.clear();
lcd.print("Full reset");
delay(1000);
showMainScreen();
}
else if (key == '*') {
if (!inputStr.isEmpty() && storedNumbers.size() < MAX_NUMS) {
storedNumbers.push_back(inputStr.toInt());
inputStr = "";
saveToEEPROM();
}
if (storedNumbers.size() > 0) {
sortStored();
isStoring = false;
lcd.clear();
lcd.print("Stage 2 switch");
delay(1200);
}
showMainScreen();
}
}
else { // === ЭТАП 2: Поиск интервала ===
if (isdigit(key)) {
if (inputStr.length() < 4) inputStr += key;
updateInputLine();
}
else if (key == 'B') {
if (inputStr.length() > 0) inputStr.remove(inputStr.length()-1);
updateInputLine();
}
else if (key == '#') { // Возврат в Этап 1
isStoring = true;
inputStr = "";
lcd.clear();
lcd.print("Back to Stage 1");
delay(1000);
showMainScreen();
}
else if (key == '*' || key == 'A' || key == 'C' || key == 'D') { // Подтверждение ввода
if (!inputStr.isEmpty()) {
int num = inputStr.toInt();
inputStr = "";
findAndShowInterval(num);
}
}
}
}
void sortStored() {
for (size_t i = 0; i < storedNumbers.size(); ++i) {
for (size_t j = i + 1; j < storedNumbers.size(); ++j) {
if (storedNumbers[i] > storedNumbers[j]) {
int temp = storedNumbers[i];
storedNumbers[i] = storedNumbers[j];
storedNumbers[j] = temp;
}
}
}
}
void updateInputLine() {
lcd.setCursor(0, 1);
lcd.print("Enter: ");
lcd.print(inputStr);
lcd.print(" "); //cleaning
}
void showMainScreen() {
lcd.clear();
if (isStoring) {
lcd.print("Stage 1: Bounds");
lcd.setCursor(0,1);
lcd.print("Numbers: ");
lcd.print(storedNumbers.size());
lcd.print("/10");
} else {
lcd.print("Stage 2: Search");
lcd.setCursor(0,1);
lcd.print("Enter a number:");
}
}
void findAndShowInterval(int num) {
lcd.clear();
lcd.print("Number: ");
lcd.print(num);
if (storedNumbers.empty()) {
lcd.setCursor(0,1);
lcd.print("No bounds!");
delay(2000);
return;
}
lcd.setCursor(0,1);
// Крайние случаи
if (num < storedNumbers[0]) {
lcd.print("Less than [");
lcd.print(storedNumbers[0]);
lcd.print("]");
delay(2500);
return;
}
if (num > storedNumbers.back()) {
lcd.print("More than [");
lcd.print(storedNumbers.back());
lcd.print("]");
delay(2500);
return;
}
// Поиск интервала
for (size_t i = 0; i < storedNumbers.size() - 1; ++i) {
if (num >= storedNumbers[i] && num <= storedNumbers[i+1]) {
lcd.print("[");
lcd.print(storedNumbers[i]);
lcd.print(",");
lcd.print(storedNumbers[i+1]);
lcd.print("]");
delay(3000);
return;
}
}
lcd.print("Not found");
delay(2000);
}
// Работа с EEPROM
void saveToEEPROM() {
int count = storedNumbers.size();
EEPROM.put(EEPROM_ADDR, count);
for (int i = 0; i < count; ++i) {
EEPROM.put(EEPROM_ADDR + 4 + i * sizeof(int), storedNumbers[i]);
}
}
void loadFromEEPROM() {
int count = 0;
EEPROM.get(EEPROM_ADDR, count);
if (count > 0 && count <= MAX_NUMS) {
storedNumbers.clear();
for (int i = 0; i < count; ++i) {
int val = 0;
EEPROM.get(EEPROM_ADDR + 4 + i * sizeof(int), val);
storedNumbers.push_back(val);
}
}
}