Я создаю устройство в стиле роботизированной руки и управляю им с помощью
Arduino Mega Nema 17 шаговых двигателей 2004A ЖК-клавиатура I2C с 16 кнопками
У меня есть несколько меню, которые управляются функцией updateMenuDisplay() и считываются из глобальных массивов строк.
Я хочу, чтобы ЖК-экран работал на всех 4 строках и отображал по 1 элементу в каждой строке. Кажется, я не могу предотвратить зацикливание меню и запуск заново с самого начала. Это особенно раздражает, когда в меню всего три пункта.
Я знаю, что на самом деле это простая логическая задача, но я не могу понять ее правильно.Я не хочу, чтобы курсор выбора исчезал с экрана и вечно показывал пустые строки. Я хочу, чтобы в меню было столько пунктов, сколько в нем есть. Он не должен зацикливаться или возвращаться к началу.
Да, это не идеальный код, и я учусь по ходу дела. Я задаюсь вопросом, почему я сделал какую-то глупость, потому что я не профессиональный разработчик.
#include
#include
#include
#include
#include
#include
#include
#include
// The parameters are (I2C address, number of columns, number of rows).
LiquidCrystal_I2C lcd(0x27, 20, 4);
// Menu items
String mainMenuItems[] = { "SD Card", "Motor Control", "Tests" };
String motorControlMenu[] = { "Speed+", "Speed-", "Deactivate motors", "Home XY", "Stop", "Back" };
String deviceTestsMenu[] = { "SD-Comm", "3-Axis", "Wifi-Comm", "BLE-Comm", "Back" };
// SD card menu
const int maxFiles = 50; // Maximum number of files
String sdCardMenu[maxFiles];
String* currentMenu = mainMenuItems; // Start with main menu
int mainMenuItemCount = sizeof(mainMenuItems) / sizeof(mainMenuItems[0]);
int currentMainMenuItem = 0; // variable to track the current menu item
int currentSubMenuItem = 0; // variable to track the current menu item
// Menu state
enum MenuState { MAIN_MENU,
SD_CARD_MENU,
MOTOR_CONTROL_MENU,
TESTS_MENU
};
MenuState currentMenuState = MAIN_MENU;
// SD Data
const int chipSelectPin = 53; // Change this to your desired CS pin number
bool hasSDcard = false;
// Stepper motor connections
constexpr int dirPinMotorX = 23;
constexpr int stepPinMotorX = 2;
constexpr int dirPinMotorY = 22;
constexpr int stepPinMotorY = 3;
constexpr int enablePinMotorX = 30; // Enable pin for X motor driver
constexpr int enablePinMotorY = 32; // Enable pin for Y motor driver
static bool manualEnabled = false;
// Stepper motor configurations
AccelStepper stepperX(AccelStepper::DRIVER, stepPinMotorX, dirPinMotorX);
AccelStepper stepperY(AccelStepper::DRIVER, stepPinMotorY, dirPinMotorY);
// Servo setup
Servo sg90Servo;
constexpr int servoPin = 25;
// Servo position flags
bool servoPositionHigh = true; // Start with servo at 180 degrees
// Limits and control flags
int xForwardLimit = 2900;
int xBackwardLimit = 0;
bool xMovingForward = true;
int yForwardLimit = 600;
int yBackwardLimit = 0;
bool yMovingForward = true;
// Keypad
const byte ROW_NUM = 4; //four rows
const byte COL_NUM = 4; //four columns
//define the cymbols on the buttons of the keypads
char keys[ROW_NUM][COL_NUM] = {
{ '1', '2', '3', 'A' }, // UP DOWN ENTER BACK
{ '4', '5', '6', 'B' },
{ '7', '8', '9', 'C' },
{ '*', '0', '#', 'D' }
};
byte pin_rows[ROW_NUM] = { 39, 41, 43, 45 }; //connect to the row pinouts of the keypad
byte pin_column[COL_NUM] = { 37, 35, 33, 31 }; //connect to the column pinouts of the keypad
//initialize an instance of class NewKeypad
Keypad customKeypad = Keypad(makeKeymap(keys), pin_rows, pin_column, ROW_NUM, COL_NUM);
void setup() {
Serial.begin(9600);
// LCD
lcd.init();
lcd.backlight();
lcd.begin(20, 4); // Initialize the LCD with 20 columns and 4 rows.
lcd.print("Welcome!"); // Print a message to the LCD.
lcd.setCursor(0, 1); // Set the cursor to the beginning of the second row.
lcd.print("ArduPlot3D online!");
lcd.setCursor(0, 3);
lcd.print("Tom rules");
// Stepper motor setup
stepperX.setMaxSpeed(500);
stepperX.setAcceleration(1000);
stepperX.moveTo(xForwardLimit);
stepperY.setMaxSpeed(300);
stepperY.setAcceleration(1000);
stepperY.moveTo(yForwardLimit);
// Servo initialization and starting position
sg90Servo.attach(servoPin);
sg90Servo.write(0); // Start with servo at 180 degrees
delay(1000);
lcd.clear();
lcd.print("> ");
lcd.print(mainMenuItems[currentMainMenuItem]);
// SD
pinMode(chipSelectPin, OUTPUT);
Serial.println("INTIT COMPLETE");
updateMenuDisplay();
}
void loop() {
char customKey = customKeypad.getKey();
if (customKey != NO_KEY) {
handleButtonPress(customKey);
}
// Continuously run the stepper motors
//stepperX.run();
//stepperY.run();
}
void updateMenuDisplay() {
lcd.clear();
lcd.print("> ");
lcd.print(currentMenu[currentMainMenuItem]); // Displays the current selected item
int numRows = 4; // Get the number of rows on the LCD
// Display subsequent menu items on the third and fourth rows
for (int row = 1; row < numRows; row++) {
lcd.setCursor(2, row);
int nextMenuItem = (currentMainMenuItem + row) % mainMenuItemCount;
lcd.print(currentMenu[nextMenuItem]);
}
}
void handleButtonPress(char key) {
switch (key) {
case '1': // UP button
moveCursorUp();
break;
case '2': // DOWN button
moveCursorDown();
break;
case '3': // ENTER button
selectMenuItem();
break;
case 'A': // BACK button
navigateBack();
break;
default:
break;
}
}
void moveCursorUp() {
if (currentMainMenuItem > 0) {
currentMainMenuItem--;
}
updateMenuDisplay();
}
void moveCursorDown() {
if (currentMainMenuItem < mainMenuItemCount - 1) {
currentMainMenuItem++;
}
updateMenuDisplay();
}
void selectMenuItem() {
switch (currentMenuState) {
case MAIN_MENU:
switch (currentMainMenuItem) {
case 0:
openSDreader();
break;
case 1:
openMotorControlMenu();
break;
case 2:
openDeviceTestsMenu();
default:
break;
}
default:
break;
}
}
// Go back to previous menu
void navigateBack() {
Serial.println("BACK ");
currentMenuState = MOTOR_CONTROL_MENU;
currentMenu = motorControlMenu;
currentMainMenuItem = 0;
updateMenuDisplay();
}
// Device tests
void openDeviceTestsMenu() {
Serial.println("TESTS MENU ----------->>");
currentMenuState = TESTS_MENU;
currentMenu = deviceTestsMenu;
currentMainMenuItem = 0;
updateMenuDisplay();
}
for (int row = 1; row < numRows; row++) {
lcd.setCursor(2, row);
int nextMenuItem = (currentMainMenuItem + row) % mainMenuItemCount;
if (currentMenu[nextMenuItem] == "") {
lcd.print(" "); // Print empty space for missing menu item
} else {
lcd.print(currentMenu[nextMenuItem]);
}
}
Подробнее здесь: https://stackoverflow.com/questions/784 ... rduino-lcd
Почему мои меню продолжают зацикливаться на моем ЖК-дисплее Arduino? ⇐ C++
-
- Похожие темы
- Ответы
- Просмотры
- Последнее сообщение
-
-
Меню настройки основного меню не обновляется в меню «Настройки» меню паузы
Anonymous » » в форуме C# - 0 Ответы
- 17 Просмотры
-
Последнее сообщение Anonymous
-
-
-
Почему темы продолжают загружаться в моем приложении и как я могу ими управлять?
Anonymous » » в форуме Android - 0 Ответы
- 92 Просмотры
-
Последнее сообщение Anonymous
-