красота, можно сказать уже готовое утсройство
This commit is contained in:
264
TecktroHack/TecktroHack.ino
Normal file
264
TecktroHack/TecktroHack.ino
Normal file
@@ -0,0 +1,264 @@
|
||||
#include <Wire.h>
|
||||
#include <ctype.h>
|
||||
/*
|
||||
Разъем 6 пинов (2 ряда по 3 пина):
|
||||
|
||||
+--------------+---------+---------+--+
|
||||
|--------------| none | SCL |--| <-- верхний ряд, пины 1 и 2
|
||||
+--------------+---------+---------+--+
|
||||
|--------------| GND | 3.3V |--| <-- нижний ряд, пины 3 и 4
|
||||
+--------------+---------+---------+--+
|
||||
|--------------| none | SDA |--| <-- нижний ряд, пины 5 и 6
|
||||
+--------------+---------+---------+--+
|
||||
|
||||
Пояснения:
|
||||
- SCL = I2C Clock pin
|
||||
- SDA = I2C Data pin
|
||||
- GND = общий минус
|
||||
- 3.3V = питание EEPROM
|
||||
- none = не подключен
|
||||
*/
|
||||
|
||||
#define EEPROM_SIZE 256
|
||||
#define I2C_MIN_ADDR 0x50
|
||||
#define I2C_MAX_ADDR 0x57
|
||||
|
||||
#define SDA_PIN 8
|
||||
#define SCL_PIN 9
|
||||
|
||||
uint8_t eeprom_addr = 0;
|
||||
uint16_t versionAddr = 0x54; // версия начинается с этого адреса
|
||||
uint16_t startAddr = 0x04; // адрес записи строк по умолчанию
|
||||
char moduleStr[32] = {0}; // буфер для модуля
|
||||
char versionStr[32] = {0}; // буфер для версии
|
||||
|
||||
|
||||
bool ensureEEPROM() {
|
||||
if (eeprom_addr == 0) { // 0 - значит еще не найдена
|
||||
return findEEPROM();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool findEEPROM() {
|
||||
Serial.println("Scanning for EEPROM...");
|
||||
|
||||
for (uint8_t addr = I2C_MIN_ADDR; addr <= I2C_MAX_ADDR; addr++) {
|
||||
Wire.beginTransmission(addr);
|
||||
if (Wire.endTransmission() == 0) {
|
||||
eeprom_addr = addr;
|
||||
Serial.print("Found EEPROM at address 0x");
|
||||
Serial.println(eeprom_addr, HEX);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
Serial.println("EEPROM not found!");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
void eepromWriteByte(uint8_t addr, uint8_t data) {
|
||||
if (!ensureEEPROM()) {
|
||||
Serial.println("EEPROM not found! Write aborted.");
|
||||
return;
|
||||
}
|
||||
Wire.beginTransmission(eeprom_addr);
|
||||
Wire.write(addr);
|
||||
Wire.write(data);
|
||||
Wire.endTransmission();
|
||||
delay(5);
|
||||
}
|
||||
|
||||
uint8_t eepromReadByte(uint8_t addr) {
|
||||
if (!ensureEEPROM()) {
|
||||
Serial.println("EEPROM not found! Write aborted.");
|
||||
return 0xFF;
|
||||
}
|
||||
|
||||
Wire.beginTransmission(eeprom_addr);
|
||||
Wire.write(addr);
|
||||
Wire.endTransmission();
|
||||
|
||||
Wire.requestFrom(eeprom_addr, (uint8_t)1);
|
||||
if (Wire.available()) {
|
||||
return Wire.read();
|
||||
}
|
||||
|
||||
return 0xFF;
|
||||
}
|
||||
|
||||
void writeStringToEEPROM(const char* str, uint16_t addr) {
|
||||
if (!ensureEEPROM()) {
|
||||
Serial.println("EEPROM not found! Write aborted.");
|
||||
return;
|
||||
}
|
||||
|
||||
size_t len = strlen(str);
|
||||
if (addr + len + 1 > EEPROM_SIZE)
|
||||
len = EEPROM_SIZE - addr - 1;
|
||||
|
||||
if (addr < versionAddr) {
|
||||
// Очистить всё пространство от addr до versionAddr (не включая versionAddr)
|
||||
for (uint16_t i = addr; i < versionAddr; i++) {
|
||||
eepromWriteByte(i, 0xFF);
|
||||
}
|
||||
} else {
|
||||
// Очистить только область для новой строки (len + 1 — включая нулевой терминатор)
|
||||
for (size_t i = 0; i < len + 1; i++) {
|
||||
eepromWriteByte(addr + i, 0xFF);
|
||||
}
|
||||
}
|
||||
|
||||
Serial.print("Writing to EEPROM @ 0x");
|
||||
Serial.print(addr, HEX);
|
||||
Serial.print(": ");
|
||||
Serial.println(str);
|
||||
|
||||
for (size_t i = 0; i < len; i++) {
|
||||
eepromWriteByte(addr + i, str[i]);
|
||||
}
|
||||
eepromWriteByte(addr + len, 0); // null-терминатор
|
||||
}
|
||||
|
||||
void readModuleFromEEPROM() {
|
||||
if (!ensureEEPROM()) {
|
||||
Serial.println("EEPROM not found! Write aborted.");
|
||||
return;
|
||||
}
|
||||
memset(moduleStr, 0, sizeof(moduleStr));
|
||||
for (size_t i = 0; i < sizeof(moduleStr) - 1; i++) {
|
||||
uint8_t b = eepromReadByte(startAddr + i);
|
||||
if (b == 0 || b == 0xFF) {
|
||||
moduleStr[i] = 0;
|
||||
break;
|
||||
}
|
||||
moduleStr[i] = (char)b;
|
||||
}
|
||||
moduleStr[sizeof(moduleStr)-1] = 0;
|
||||
|
||||
Serial.print("[EEPROM] Module read: ");
|
||||
Serial.println(moduleStr);
|
||||
}
|
||||
|
||||
void readVersionFromEEPROM() {
|
||||
if (!ensureEEPROM()) {
|
||||
Serial.println("EEPROM not found! Write aborted.");
|
||||
return;
|
||||
}
|
||||
memset(versionStr, 0, sizeof(versionStr));
|
||||
|
||||
for (size_t i = 0; i < sizeof(versionStr) - 1; i++) {
|
||||
uint8_t b = eepromReadByte(versionAddr + i);
|
||||
if (b == 0 || b == 0xFF) {
|
||||
versionStr[i] = 0;
|
||||
break;
|
||||
}
|
||||
versionStr[i] = (char)b;
|
||||
}
|
||||
|
||||
versionStr[sizeof(versionStr) - 1] = 0;
|
||||
|
||||
Serial.print("[EEPROM] Version read: ");
|
||||
Serial.println(versionStr);
|
||||
}
|
||||
|
||||
|
||||
void readAndDumpEEPROM() {
|
||||
if (!ensureEEPROM()) {
|
||||
Serial.println("EEPROM not found! Write aborted.");
|
||||
return;
|
||||
}
|
||||
Serial.println("\nDumping full EEPROM contents:\n");
|
||||
|
||||
for (uint16_t base = 0; base < EEPROM_SIZE; base += 16) {
|
||||
char ascii[17] = {0};
|
||||
|
||||
Serial.print("0x");
|
||||
if (base < 0x10) Serial.print('0');
|
||||
Serial.print(base, HEX);
|
||||
Serial.print(": ");
|
||||
|
||||
for (uint8_t i = 0; i < 16; i++) {
|
||||
uint8_t val = eepromReadByte(base + i);
|
||||
if (val < 0x10) Serial.print('0');
|
||||
Serial.print(val, HEX);
|
||||
Serial.print(' ');
|
||||
|
||||
ascii[i] = isPrintable(val) ? (char)val : '.';
|
||||
}
|
||||
|
||||
Serial.print(" |");
|
||||
Serial.print(ascii);
|
||||
Serial.println("|");
|
||||
}
|
||||
}
|
||||
|
||||
void setup() {
|
||||
Serial.begin(9600);
|
||||
while (!Serial);
|
||||
|
||||
setupUI();
|
||||
Wire.begin(SDA_PIN, SCL_PIN);
|
||||
|
||||
bool eeprom_found = findEEPROM();
|
||||
|
||||
if (eeprom_found) {
|
||||
readModuleFromEEPROM();
|
||||
readVersionFromEEPROM();
|
||||
}
|
||||
|
||||
Serial.println("Ready.");
|
||||
Serial.println("Set start address with 'ADDR=<number>'");
|
||||
Serial.println("Set version with 'VER=<version_string>'");
|
||||
Serial.println("Then type string and press ENTER to write it.");
|
||||
Serial.print("Current start address = 0x");
|
||||
Serial.println(startAddr, HEX);
|
||||
}
|
||||
|
||||
|
||||
String inputBuffer;
|
||||
|
||||
void loop() {
|
||||
while (Serial.available()) {
|
||||
char c = Serial.read();
|
||||
if (c == '\n' || c == '\r') {
|
||||
inputBuffer.trim();
|
||||
|
||||
if (inputBuffer.length() > 0) {
|
||||
if (inputBuffer.startsWith("ADDR=")) {
|
||||
String valStr = inputBuffer.substring(5);
|
||||
int val = valStr.toInt();
|
||||
if (val >= 0 && val < EEPROM_SIZE) {
|
||||
startAddr = (uint16_t)val;
|
||||
Serial.print("Start address set to 0x");
|
||||
Serial.println(startAddr, HEX);
|
||||
} else {
|
||||
Serial.println("Invalid address! Must be 0..255");
|
||||
}
|
||||
}
|
||||
else if (inputBuffer.startsWith("VER=")) {
|
||||
String ver = inputBuffer.substring(4);
|
||||
ver.trim();
|
||||
ver.toCharArray(versionStr, sizeof(versionStr));
|
||||
writeStringToEEPROM(versionStr, versionAddr);
|
||||
Serial.print("Version written: ");
|
||||
Serial.println(versionStr);
|
||||
}
|
||||
else {
|
||||
writeStringToEEPROM(inputBuffer.c_str(), startAddr);
|
||||
delay(100);
|
||||
readAndDumpEEPROM();
|
||||
}
|
||||
}
|
||||
|
||||
inputBuffer = "";
|
||||
Serial.println("\nEnter command or string:");
|
||||
} else {
|
||||
inputBuffer += c;
|
||||
}
|
||||
}
|
||||
|
||||
loopUI();
|
||||
}
|
||||
442
TecktroHack/ui_interface.ino
Normal file
442
TecktroHack/ui_interface.ino
Normal file
@@ -0,0 +1,442 @@
|
||||
#include <Wire.h>
|
||||
#include <Adafruit_GFX.h>
|
||||
#include <Adafruit_SSD1306.h>
|
||||
#include <U8g2lib.h>
|
||||
#include <Fonts/FreeSans9pt7b.h>
|
||||
|
||||
#define FONT u8g2_font_8x13_tr
|
||||
#define LITTLE_FONT u8g2_font_5x8_tr
|
||||
#define LINE_SPACING 16
|
||||
|
||||
// OLED дисплей 128x64, I2C адрес по умолчанию — 0x3C
|
||||
#define SCREEN_WIDTH 128
|
||||
#define SCREEN_HEIGHT 64
|
||||
#define OLED_RESET -1
|
||||
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
|
||||
|
||||
// Инициализация дисплея SSD1306 128x64 по I2C
|
||||
// Выбери нужный конструктор в зависимости от контроллера
|
||||
// Этот - для SSD1306, I2C, с аппаратным reset (если нет reset - поставить U8G2_R0 и -1)
|
||||
U8G2_SSD1306_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE);
|
||||
|
||||
|
||||
// Кнопки
|
||||
#define BTN_UP_PIN 3
|
||||
#define BTN_DOWN_PIN 2
|
||||
#define BTN_OK_PIN 1 // #
|
||||
#define BTN_BACK_PIN 0 // *
|
||||
|
||||
extern uint16_t startAddr;
|
||||
extern uint16_t versionAddr;
|
||||
extern void writeStringToEEPROM(const char* str, uint16_t addr);
|
||||
extern void readModuleFromEEPROM();
|
||||
extern void readVersionFromEEPROM();
|
||||
extern char versionStr[32];
|
||||
extern char moduleStr[32];
|
||||
|
||||
|
||||
enum MenuState {
|
||||
MENU_MAIN,
|
||||
MENU_SELECT_MODEL,
|
||||
MENU_SELECT_OPTION,
|
||||
MENU_SELECT_VERSION,
|
||||
MENU_SHOW_EEPROM
|
||||
};
|
||||
|
||||
|
||||
const char* modelList[] = { "MDO5", "MDO4", "MDO3", "MDO2", "MDO1", "DPO5", "DPO4", "DPO3", "DPO2", "DPO1" };
|
||||
const uint8_t modelCount = sizeof(modelList) / sizeof(modelList[0]);
|
||||
|
||||
const char* optionList[] = {
|
||||
"BND", // Bundle (all-in-one)
|
||||
"AERO", // Aerospace serial buses
|
||||
"AFG", // Arbitrary Function Generator
|
||||
"AUDIO", // Audio serial buses
|
||||
"AUTO", // Automotive serial buses
|
||||
"AUTOMAX",// Automotive serial buses
|
||||
"COMP", // Computer serial buses
|
||||
"EMBD", // Embedded systems
|
||||
"ENET", // Ethernet
|
||||
"FLEX", // FlexRay
|
||||
"LMT", // Limit testing and mask testing
|
||||
"MSO", // Mixed Signal Option
|
||||
"PWR", // Power analysis
|
||||
"SA", // Spectrum Analyzer
|
||||
"SA3", // Spectrum Analyzer
|
||||
"SA6", // Spectrum Analyzer
|
||||
"SEC", // Security extension
|
||||
"TRIG", // RF Power Level Trigger
|
||||
"USB", // USB analysis
|
||||
"VID" // Video signal triggering
|
||||
};
|
||||
|
||||
const char* optionDescriptions[] = {
|
||||
"Include all available options in one",
|
||||
"Aerospace buses: MIL-STD-1553, ARINC 429",
|
||||
"Waveform generator for custom signals",
|
||||
"Audio buses: I2S, TDM, LJ, RJ",
|
||||
"Cars buses: CAN FD, CAN, LIN",
|
||||
"Cars buses: CAN FD, CAN, LIN, FlexRay",
|
||||
"Computer buses: SPI, I2C, RS-232, PS/2",
|
||||
"Embedded protocols: I2C, SPI, UART, GPIO",
|
||||
"Ethernet: 10/100/1000BASE-T",
|
||||
"Cars bus FlexRay",
|
||||
"Limit and mask testing: Go/No-Go",
|
||||
"Mixed Signal Oscill: analog + digital",
|
||||
"Power analysis: efficiency, ripple, Bode",
|
||||
"Spectrum analysis: RF, high-frequency",
|
||||
"Spectr analysis (3 MHz): RF, high-frequency",
|
||||
"Spectr analysis (6 MHz): RF, high-frequency",
|
||||
"Security extension: access control",
|
||||
"RF power level triggering",
|
||||
"USB decoding: USB 1.x/2.0/3.x",
|
||||
"Video triggering: HDMI, VGA, analog"
|
||||
};
|
||||
|
||||
|
||||
const uint8_t optionCount = sizeof(optionList) / sizeof(optionList[0]);
|
||||
|
||||
uint8_t selectedModel = 0;
|
||||
uint8_t selectedOption = 0;
|
||||
|
||||
MenuState currentMenu = MENU_MAIN;
|
||||
uint8_t cursorPos = 0;
|
||||
char editableVersion[16] = "v1.00";
|
||||
uint8_t editIndex = 0;
|
||||
bool editingVersion = false;
|
||||
|
||||
|
||||
void setupUI() {
|
||||
pinMode(BTN_UP_PIN, INPUT_PULLUP);
|
||||
pinMode(BTN_DOWN_PIN, INPUT_PULLUP);
|
||||
pinMode(BTN_OK_PIN, INPUT_PULLUP);
|
||||
pinMode(BTN_BACK_PIN, INPUT_PULLUP);
|
||||
|
||||
if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
|
||||
Serial.println(F("SSD1306 not found"));
|
||||
while (true);
|
||||
}
|
||||
//display.clearDisplay();
|
||||
//display.setFont(&FONT);
|
||||
//display.setTextSize(1);
|
||||
//display.setTextColor(SSD1306_WHITE);
|
||||
//display.display();
|
||||
|
||||
u8g2.begin();
|
||||
|
||||
// Выбираем шрифт - очень маленький, около 6pt (пример: u8g2_font_6x10_tr)
|
||||
u8g2.setFont(FONT);
|
||||
|
||||
|
||||
showMainMenu();
|
||||
}
|
||||
|
||||
void loopUI() {
|
||||
static uint32_t lastPress = 0;
|
||||
if (millis() - lastPress < 200) return;
|
||||
|
||||
if (currentMenu == MENU_SELECT_VERSION && editingVersion) {
|
||||
if (!digitalRead(BTN_UP_PIN)) {
|
||||
if (editableVersion[editIndex] >= '0' && editableVersion[editIndex] <= '9') {
|
||||
if (editableVersion[editIndex] == '9') editableVersion[editIndex] = '0';
|
||||
else editableVersion[editIndex]++;
|
||||
}
|
||||
updateMenuDisplay();
|
||||
lastPress = millis();
|
||||
return;
|
||||
}
|
||||
|
||||
if (!digitalRead(BTN_DOWN_PIN)) {
|
||||
if (editableVersion[editIndex] >= '0' && editableVersion[editIndex] <= '9') {
|
||||
if (editableVersion[editIndex] == '0') editableVersion[editIndex] = '9';
|
||||
else editableVersion[editIndex]--;
|
||||
}
|
||||
updateMenuDisplay();
|
||||
lastPress = millis();
|
||||
return;
|
||||
}
|
||||
|
||||
if (!digitalRead(BTN_OK_PIN)) {
|
||||
// Перейти к следующему редактируемому символу, пропуская точки и буквы
|
||||
do {
|
||||
editIndex++;
|
||||
} while (editIndex < strlen(editableVersion) && (editableVersion[editIndex] < '0' || editableVersion[editIndex] > '9'));
|
||||
|
||||
if (editIndex >= strlen(editableVersion)) {
|
||||
// Закончили редактировать
|
||||
writeStringToEEPROM(editableVersion, versionAddr);
|
||||
strncpy(versionStr, editableVersion, sizeof(versionStr));
|
||||
editingVersion = false;
|
||||
currentMenu = MENU_MAIN;
|
||||
cursorPos = 0;
|
||||
}
|
||||
|
||||
updateMenuDisplay();
|
||||
lastPress = millis();
|
||||
return;
|
||||
}
|
||||
|
||||
if (!digitalRead(BTN_BACK_PIN)) {
|
||||
// Назад по цифрам
|
||||
do {
|
||||
if (editIndex == 0) {
|
||||
editingVersion = false;
|
||||
currentMenu = MENU_MAIN;
|
||||
cursorPos = 0;
|
||||
break;
|
||||
} else {
|
||||
editIndex--;
|
||||
}
|
||||
} while (editableVersion[editIndex] < '0' || editableVersion[editIndex] > '9');
|
||||
|
||||
updateMenuDisplay();
|
||||
lastPress = millis();
|
||||
return;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (!digitalRead(BTN_UP_PIN)) {
|
||||
if (cursorPos > 0) cursorPos--;
|
||||
updateMenuDisplay();
|
||||
lastPress = millis();
|
||||
} else if (!digitalRead(BTN_DOWN_PIN)) {
|
||||
cursorPos++;
|
||||
updateMenuDisplay();
|
||||
lastPress = millis();
|
||||
} else if (!digitalRead(BTN_OK_PIN)) {
|
||||
handleOk();
|
||||
lastPress = millis();
|
||||
} else if (!digitalRead(BTN_BACK_PIN)) {
|
||||
handleBack();
|
||||
lastPress = millis();
|
||||
}
|
||||
}
|
||||
|
||||
void showMainMenu() {
|
||||
currentMenu = MENU_MAIN;
|
||||
cursorPos = 0;
|
||||
updateMenuDisplay();
|
||||
}
|
||||
|
||||
void drawStringWrapped(int x, int y, int maxWidth, const char* text, int lineHeight) {
|
||||
int lineStart = 0;
|
||||
int textLen = strlen(text);
|
||||
|
||||
while (lineStart < textLen) {
|
||||
int lineEnd = lineStart;
|
||||
int lastSpace = -1;
|
||||
int width = 0;
|
||||
|
||||
while (lineEnd < textLen) {
|
||||
char c = text[lineEnd];
|
||||
// Вычисляем ширину подстроки с lineStart до lineEnd + 1
|
||||
char buffer[64]; // должен быть достаточного размера
|
||||
int length = lineEnd - lineStart + 1;
|
||||
if (length >= sizeof(buffer)) length = sizeof(buffer) - 1;
|
||||
memcpy(buffer, text + lineStart, length);
|
||||
buffer[length] = '\0';
|
||||
|
||||
int w = u8g2.getStrWidth(buffer);
|
||||
|
||||
if (w > maxWidth) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (c == ' ' || c == '-' || c == '\t') {
|
||||
lastSpace = lineEnd;
|
||||
}
|
||||
|
||||
lineEnd++;
|
||||
}
|
||||
|
||||
// Если мы вышли за предел maxWidth
|
||||
if (lineEnd == lineStart) {
|
||||
// Если один символ не помещается — выводим его все равно (чтобы не зацикливаться)
|
||||
lineEnd = lineStart + 1;
|
||||
} else if (lineEnd < textLen && lastSpace != -1) {
|
||||
// Откатываемся до последнего пробела, чтобы не разрывать слово
|
||||
lineEnd = lastSpace;
|
||||
}
|
||||
|
||||
// Подстрока для вывода длиной (lineEnd - lineStart)
|
||||
char buf[128];
|
||||
int len = lineEnd - lineStart;
|
||||
if (len >= sizeof(buf)) len = sizeof(buf) - 1;
|
||||
strncpy(buf, text + lineStart, len);
|
||||
buf[len] = 0;
|
||||
|
||||
u8g2.drawStr(x, y, buf);
|
||||
|
||||
y += lineHeight;
|
||||
lineStart = (lineEnd == lastSpace) ? lineEnd + 1 : lineEnd;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void updateMenuDisplay() {
|
||||
u8g2.clearBuffer();
|
||||
//display.clearDisplay();
|
||||
//display.setCursor(0, LINE_SPACING);
|
||||
|
||||
if (currentMenu == MENU_MAIN) {
|
||||
// Выводим три строки меню с курсором >
|
||||
if(cursorPos > 2)
|
||||
{
|
||||
cursorPos = 2;
|
||||
}
|
||||
u8g2.drawStr(0, LINE_SPACING * 1, cursorPos == 0 ? ">Set Options" : " Set Options");
|
||||
u8g2.drawStr(0, LINE_SPACING * 2, cursorPos == 1 ? ">Set Version" : " Set Version");
|
||||
u8g2.drawStr(0, LINE_SPACING * 3, cursorPos == 2 ? ">Read Module" : " Read Module");
|
||||
/*display.print(cursorPos == 0 ? ">Set Options" : " Set Options");
|
||||
display.setCursor(0, LINE_SPACING *2);
|
||||
display.print(cursorPos == 1 ? ">Set Version" : " Set Version");
|
||||
display.setCursor(0, LINE_SPACING *3);
|
||||
display.print(cursorPos == 2 ? ">Read" : " Read");*/
|
||||
|
||||
} else if (currentMenu == MENU_SELECT_MODEL) {
|
||||
u8g2.drawStr(0, LINE_SPACING * 1, "Model:");
|
||||
|
||||
// Формируем строку ">ModelName"
|
||||
char line[20];
|
||||
snprintf(line, sizeof(line), ">%s", modelList[cursorPos % modelCount]);
|
||||
u8g2.drawStr(0, LINE_SPACING * 2, line);
|
||||
/*display.print("Model:");
|
||||
display.setCursor(0, LINE_SPACING *2);
|
||||
display.print(">");
|
||||
display.print(modelList[cursorPos % modelCount]);*/
|
||||
|
||||
} else if (currentMenu == MENU_SELECT_OPTION) {
|
||||
u8g2.setFont(FONT); // основной шрифт
|
||||
u8g2.drawStr(0, LINE_SPACING * 1, "Option:");
|
||||
|
||||
char line[20];
|
||||
uint8_t optIndex = cursorPos % optionCount;
|
||||
snprintf(line, sizeof(line), ">%s", optionList[optIndex]);
|
||||
u8g2.drawStr(0, LINE_SPACING * 2, line);
|
||||
|
||||
// Мелкий шрифт — описание
|
||||
u8g2.setFont(LITTLE_FONT);
|
||||
drawStringWrapped(0, LINE_SPACING * 3 + 4, SCREEN_WIDTH, optionDescriptions[optIndex], 10);
|
||||
u8g2.setFont(FONT);
|
||||
/*display.print("Option:");
|
||||
display.setCursor(0, LINE_SPACING *2);
|
||||
display.print(">");
|
||||
display.print(optionList[cursorPos % optionCount]);*/
|
||||
|
||||
} else if (currentMenu == MENU_SELECT_VERSION) {
|
||||
u8g2.drawStr(0, LINE_SPACING * 1, "UART set ver:");
|
||||
|
||||
// Для версии выводим символы с квадратными скобками вокруг редактируемого
|
||||
int x = 0;
|
||||
for (uint8_t i = 0; i < strlen(editableVersion); i++) {
|
||||
char buf[4];
|
||||
if (i == editIndex && editingVersion) {
|
||||
snprintf(buf, sizeof(buf), "[%c]", editableVersion[i]);
|
||||
} else {
|
||||
snprintf(buf, sizeof(buf), " %c ", editableVersion[i]);
|
||||
}
|
||||
u8g2.drawStr(x, LINE_SPACING * 2, buf);
|
||||
x += u8g2.getStrWidth(buf); // смещение курсора вправо на ширину предыдущей части
|
||||
}
|
||||
|
||||
|
||||
/*display.print("UART set ver:");
|
||||
display.setCursor(0, LINE_SPACING *2);
|
||||
|
||||
for (uint8_t i = 0; i < strlen(editableVersion); i++) {
|
||||
if (i == editIndex && editingVersion) {
|
||||
display.print("[");
|
||||
display.print(editableVersion[i]);
|
||||
display.print("]");
|
||||
} else {
|
||||
display.print(" ");
|
||||
display.print(editableVersion[i]);
|
||||
display.print(" ");
|
||||
}
|
||||
}*/
|
||||
} else if (currentMenu == MENU_SHOW_EEPROM) {
|
||||
char buf[40];
|
||||
|
||||
snprintf(buf, sizeof(buf), "Model Option:");
|
||||
u8g2.drawStr(0, LINE_SPACING * 1, buf);
|
||||
|
||||
snprintf(buf, sizeof(buf), " %s", moduleStr);
|
||||
u8g2.drawStr(0, LINE_SPACING * 2, buf);
|
||||
|
||||
snprintf(buf, sizeof(buf), "Version:");
|
||||
u8g2.drawStr(0, LINE_SPACING * 3, buf);
|
||||
|
||||
snprintf(buf, sizeof(buf), " %s", versionStr);
|
||||
u8g2.drawStr(0, LINE_SPACING * 4, buf);
|
||||
|
||||
/*display.print("Mod:");
|
||||
display.println(moduleStr);
|
||||
display.setCursor(0, LINE_SPACING *3);
|
||||
display.print("Ver:");
|
||||
display.println(versionStr);*/
|
||||
}
|
||||
|
||||
//display.display();
|
||||
u8g2.sendBuffer();
|
||||
}
|
||||
|
||||
|
||||
void handleOk() {
|
||||
if (currentMenu == MENU_MAIN) {
|
||||
if (cursorPos == 0) {
|
||||
currentMenu = MENU_SELECT_MODEL;
|
||||
cursorPos = 0;
|
||||
} else if (cursorPos == 1) {
|
||||
currentMenu = MENU_SELECT_VERSION;
|
||||
} else if (cursorPos == 2) {
|
||||
readVersionFromEEPROM();
|
||||
readModuleFromEEPROM();
|
||||
currentMenu = MENU_SHOW_EEPROM;
|
||||
}
|
||||
|
||||
} else if (currentMenu == MENU_SELECT_MODEL) {
|
||||
selectedModel = cursorPos % modelCount;
|
||||
cursorPos = 0;
|
||||
currentMenu = MENU_SELECT_OPTION;
|
||||
|
||||
} else if (currentMenu == MENU_SELECT_OPTION) {
|
||||
selectedOption = cursorPos % optionCount;
|
||||
|
||||
char fullModule[32];
|
||||
snprintf(fullModule, sizeof(fullModule), "%s%s", modelList[selectedModel], optionList[selectedOption]);
|
||||
writeStringToEEPROM(fullModule, startAddr);
|
||||
readAndDumpEEPROM();
|
||||
strncpy(moduleStr, fullModule, sizeof(moduleStr) - 1);
|
||||
moduleStr[sizeof(moduleStr) - 1] = 0;
|
||||
|
||||
Serial.print("[UI] Options written: ");
|
||||
Serial.println(fullModule);
|
||||
|
||||
currentMenu = MENU_MAIN;
|
||||
cursorPos = 0;
|
||||
|
||||
} else if (currentMenu == MENU_SELECT_VERSION) {
|
||||
editingVersion = true;
|
||||
editIndex = 1;
|
||||
}
|
||||
|
||||
|
||||
updateMenuDisplay();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void handleBack() {
|
||||
if (currentMenu == MENU_SELECT_OPTION) {
|
||||
currentMenu = MENU_SELECT_MODEL;
|
||||
} else {
|
||||
currentMenu = MENU_MAIN;
|
||||
}
|
||||
cursorPos = 0;
|
||||
updateMenuDisplay();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user