基于Arduino的16x2 I2C LCD与4x3键盘交互功能实现求助
解决方案
问题排查
修改后的代码存在以下核心问题导致需求无法实现:
- 编辑触发键
*和退出键#会被误当作输入字符存入数组并显示 - 退出编辑模式后未恢复初始的"Volume/Filled"界面
- 存储输入的字符数组缺少字符串终止符,
atoi转换可能产生异常 - 提前按
#退出时未正确处理未完成的输入,数值转换逻辑混乱 - 未定义的
buttonState1和buttonPin1变量会导致编译报错
修正代码
#include <Keypad.h> #include <LiquidCrystal_I2C.h> #include <Wire.h> LiquidCrystal_I2C lcd(0x27, 16, 2); // 匹配16x2屏幕规格 const int ROW_NUM = 4; const int COLUMN_NUM = 3; char keys[ROW_NUM][COLUMN_NUM] = { {'1','2','3'}, {'4','5','6'}, {'7','8','9'}, {'*','0','#'}, }; byte pin_rows[ROW_NUM] = {8,7,6,5}; byte pin_column[COLUMN_NUM] = {4,3,2}; Keypad keypad = Keypad( makeKeymap(keys), pin_rows, pin_column, ROW_NUM, COLUMN_NUM ); char volume[4]; // 预留字符串终止符位置 byte volumeCount = 0; bool editMode = false; int targetVolume = 0; int sensorValue = 0; // 传感器采集值,根据硬件调整 bool processRunning = false; // 核心流程运行标记 void setup() { lcd.init(); lcd.clear(); lcd.backlight(); showMainScreen(); // 加载初始界面 } void loop() { char key = keypad.getKey(); if(key) { if(key == '*' && !editMode && !processRunning) { // 仅在非编辑、非运行状态激活编辑模式 enterEditMode(); } else if(key == '#' && editMode) { // 退出编辑并保存数值 exitEditMode(); } else if(editMode && volumeCount < 3) { // 仅处理数字键输入 if(key >= '0' && key <= '9') { volume[volumeCount] = key; lcd.setCursor(volumeCount, 1); lcd.print(key); volumeCount++; } } } // 核心流程:传感器值等于目标值时停止 if(processRunning) { // 替换为实际传感器读取代码,此处为模拟 // sensorValue = analogRead(sensorPin); lcd.setCursor(8, 1); lcd.print(sensorValue); lcd.print(" "); // 清除多余显示字符 if(sensorValue == targetVolume) { processRunning = false; lcd.clear(); lcd.print("Process Stopped!"); delay(2000); showMainScreen(); } } } // 显示主界面 void showMainScreen() { lcd.clear(); lcd.setCursor(0, 0); lcd.print("Volume: "); lcd.print(targetVolume); lcd.print(" ml"); lcd.setCursor(0, 1); lcd.print("Filled: 0 ml"); } // 进入编辑模式 void enterEditMode() { editMode = true; volumeCount = 0; memset(volume, 0, sizeof(volume)); // 清空输入数组 lcd.clear(); lcd.setCursor(0, 0); lcd.print("Input Volume:"); lcd.setCursor(0, 1); } // 退出编辑模式 void exitEditMode() { editMode = false; // 处理空输入或不足3位的情况 if(volumeCount == 0) { targetVolume = 0; } else { volume[volumeCount] = '\0'; // 添加字符串终止符 targetVolume = atoi(volume); } showMainScreen(); }
关键修改说明
- 修正LCD初始化参数为
16,2,匹配16x2屏幕规格 - 增加
editMode状态控制,严格区分编辑/非编辑状态,避免误操作 - 过滤编辑模式下的非数字键输入,仅响应
0-9、*、# - 字符数组
volume扩容为4位,添加字符串终止符保证atoi转换正常 - 拆分界面显示、编辑进入/退出为独立函数,逻辑更清晰
- 加入核心流程控制逻辑,当传感器值与目标值相等时停止并提示
- 修复未定义变量问题,补充必要的状态标记
内容的提问来源于stack exchange,提问作者Lord Voldemort
相关产品推荐
相关产品推荐

