Napisal/-a s5ti » 06 Mar 2025, 15:19
AI naredi lepe komentarje
####
Code Anaysis
1. Language & Platform
The code is written in C++ for an Arduino microcontroller.
Uses the LiquidCrystal library to interface with an LCD display.
Uses digital inputs for button handling.
Implements debouncing logic and long-press detection.
Implements a menu system on a 16x2 LCD screen.
2. Purpose of the Code
The program:
Reads button presses from four buttons (connected to pins 8, 9, 10, 11).
Implements debouncing to ensure stable button reads.
Handles both short and long presses for different actions.
Manages an LCD menu system that allows navigation and parameter adjustment.
Updates LCD display to show current menu options and values.
3. Code Functionality Breakdown
3.1. LCD Initialization
LiquidCrystal lcd(6, 7, 5, 4, 3, 2);
Initializes the LCD using specific pins for RS, E, D4, D5, D6, and D7.
3.2. Input Button Setup
const int numOfInputs = 4;
const int inputPins[numOfInputs] = {8,9,10,11};
int inputState[numOfInputs];
int lastInputState[numOfInputs] = {LOW,LOW,LOW,LOW};
bool inputFlags[numOfInputs] = {LOW,LOW,LOW,LOW};
long lastDebounceTime[numOfInputs] = {0,0,0,0};
long debounceDelay = 5;
unsigned long pressStartTime[numOfInputs] = {0};
Manages button states and debounce timing.
Stores last button states and press durations.
3.3. Menu System Setup
const int numOfScreens = 9;
int currentScreen = 0;
String screens[numOfScreens][2] = {{"Dolzina enote","ms"}, {"Ustavi po znaku",""}, {"St. ponovitev 1", " "},
{"St. ponovitev 2",""}, {"Gumb 1:", ""}, {"Gumb 2:", ""},
{"Gumb 3:", ""},{"Gumb 4:", ""}, {"Gumb 5:", ""}};
int parameters[numOfScreens];
numOfScreens defines the number of menu screens.
screens contains screen titles and units for display.
parameters stores values associated with each menu option.
3.4. setup() - Initial Configuration
void setup() {
for(int i = 0; i < numOfInputs; i++) {
pinMode(inputPins[i], INPUT);
digitalWrite(inputPins[i], HIGH); // pull-up 20k
}
lcd.begin(16, 2);
}
Sets button pins as INPUT and enables internal pull-up resistors (active-low logic).
Initializes the 16x2 LCD display.
3.5. loop() - Main Execution Loop
void loop() {
setInputFlags();
resolveInputFlags();
}
Calls functions to handle button presses and actions.
3.6. setInputFlags() - Button Debouncing and Long-Press Handling
void setInputFlags() {
for(int i = 0; i < numOfInputs; i++) {
int reading = digitalRead(inputPins[i]);
if (reading != lastInputState[i]) {
lastDebounceTime[i] = millis();
}
if ((millis() - lastDebounceTime[i]) > debounceDelay) {
if (reading != inputState[i]) {
inputState[i] = reading;
if (inputState[i] == LOW) {
inputFlags[i] = HIGH;
pressStartTime[i] = millis();
}
}
}
if (inputState[i] == LOW && (millis() - pressStartTime[i]) > 500) {
static unsigned long lastIncrementTime[numOfInputs] = {0};
if (millis() - lastIncrementTime[i] > 100) {
inputFlags[i] = HIGH;
lastIncrementTime[i] = millis();
}
}
lastInputState[i] = reading;
}
}
Detects button press and release events.
Implements debouncing using debounceDelay.
Detects long-press events (holding for >500ms).
3.7. resolveInputFlags() - Processing Button Actions
void resolveInputFlags() {
for(int i = 0; i < numOfInputs; i++) {
if(inputFlags[i] == HIGH) {
inputAction(i);
inputFlags[i] = LOW;
printScreen();
}
}
}
Calls inputAction() when a button is pressed.
Refreshes the LCD screen after processing.
3.8. inputAction() - Defining Actions for Each Button
void inputAction(int input) {
if(input == 0) { // Left button
if (currentScreen == 0) {
currentScreen = numOfScreens - 1;
} else {
currentScreen--;
}
} else if(input == 1) { // Right button
if (currentScreen == numOfScreens - 1) {
currentScreen = 0;
} else {
currentScreen++;
}
} else if(input == 2) { // Increment parameter
parameterChange(0);
} else if(input == 3) { // Decrement parameter
parameterChange(1);
}
}
Button 0 (left): Moves to the previous menu item.
Button 1 (right): Moves to the next menu item.
Button 2: Increments the selected parameter.
Button 3: Decrements the selected parameter.
3.9. parameterChange() - Adjusting Parameter Values
void parameterChange(int key) {
if(key == 0) {
parameters[currentScreen]++;
} else if(key == 1) {
parameters[currentScreen]--;
}
}
Increments or decrements the parameter of the current screen.
3.10. printScreen() - Updating LCD Display
void printScreen() {
lcd.clear();
lcd.print(screens[currentScreen][0]);
lcd.setCursor(0,1);
lcd.print(parameters[currentScreen]);
lcd.print(" ");
lcd.print(screens[currentScreen][1]);
}
Clears the LCD screen.
Displays the menu title on the first line.
Displays the parameter value and unit on the second line.
4. Suggested Improvements
4.1. Improve Button Handling
Instead of using LOW and HIGH states manually, use bool for clarity.
bool inputFlags[numOfInputs] = {}; // Zero-initialized
4.2. Improve Debounce Logic
lastDebounceTime should be unsigned long instead of long (to match millis()).
debounceDelay should be constexpr for optimization.
constexpr unsigned long debounceDelay = 5;
unsigned long lastDebounceTime[numOfInputs] = {};
4.3. Use constexpr for Constants
constexpr int numOfInputs = 4;
constexpr int numOfScreens = 9;
4.4. Prevent Negative Parameter Values
void parameterChange(int key) {
if (key == 0) {
parameters[currentScreen]++;
} else if (key == 1 && parameters[currentScreen] > 0) {
parameters[currentScreen]--;
}
}
Prevents decrementing below zero.
4.5. Optimize LCD Refreshing
void resolveInputFlags() {
bool shouldRefresh = false;
for(int i = 0; i < numOfInputs; i++) {
if(inputFlags[i]) {
inputAction(i);
inputFlags[i] = false;
shouldRefresh = true;
}
}
if (shouldRefresh) printScreen();
}
Avoids unnecessary LCD updates.
Final Thoughts
The code is well-structured and efficiently handles an LCD menu system.
Improvements can optimize memory usage and enhance readability.
These optimizations will make the code more robust and maintainable.
Več glav - več zelja