如何在字符串数组中添加LCD自定义字符并实现?
赞美盒:自定义字符实现与代码优化
一、自定义字符在赞美语中的实现
LCD的自定义字符通过lcd.createChar(index, pattern)存入指定索引(0-7),无法直接识别字符串里的{Ao}标记,需要用以下方式处理:
替换占位符:
把赞美语中的{Ao}替换为对应自定义字符索引的ASCII值(你将Ao存在索引0,就用\x00作为占位符)。推荐用const char*数组代替String,减少内存占用:// 赞美语数组,\x00对应索引0的自定义字符 const char* compliments[] = { "Test 0 \x00", "Test 1", "Test 2", "Test 3", "Test 4", "Test 5", "Test 6", "Test 7", "Test 8", "Test 9" };编写解析打印函数:
遍历字符串每个字符,遇到占位符时调用lcd.write()输出自定义字符,否则打印普通字符:void printCompliment(const char* str) { while (*str != '\0') { if (*str == '\x00') { lcd.write(0); // 输出索引0的自定义字符 } else { lcd.print(*str); } str++; } }调用解析函数:
在按钮触发逻辑中,替换原lcd.print(compliments[randNum])为:printCompliment(compliments[randNum]);
二、代码优化建议
1. 修复防重复逻辑
原代码的防重复逻辑无效,正确逻辑是生成随机数后,若与上一次相同则重新生成,直到不同:
if (!digitalRead(BUTTON_PIN)) { // 生成与上一次不同的随机数 do { randNum = random(NUM_COMPLIMENTS); } while (randNum == previousRandNum); previousRandNum = randNum; clearLowerLCDRows(); lcd.setCursor(0, 0); printCompliment(compliments[randNum]); Serial.println(randNum); // 按钮防抖,用millis代替delay避免阻塞 unsigned long pressTime = millis(); while (!digitalRead(BUTTON_PIN) && millis() - pressTime < 500); }
2. 常量与内存优化
- 用宏定义赞美语数量,方便后续修改:
#define NUM_COMPLIMENTS 10 - 所有固定字符串用
const char*代替String,避免Arduino内存碎片化问题。 - 自定义字符数组命名更清晰,添加注释:
// 自定义字符:挪威语字母Å的点阵 byte custom_Aa[8] = { B00100, B01010, B00100, B01110, B00001, B01111, B10001, B01111 };
3. 函数与可读性优化
- 重命名
clearLCD为clearLowerLCDRows,明确仅清除第1-3行:void clearLowerLCDRows() { for (int row = 1; row < 4; row++) { lcd.setCursor(0, row); lcd.print(" "); } } - 变量初始化更合理:
int previousRandNum = -1;(随机数范围0-9,第一次生成必然不同)。
4. 完整优化后的代码
#include <Wire.h> #include <LiquidCrystal_I2C.h> // LCD初始化参数 LiquidCrystal_I2C lcd(0x27, 20, 4); // 常量定义 const int BUTTON_PIN = 7; #define NUM_COMPLIMENTS 10 // 全局变量 int randNum = 0; int previousRandNum = -1; // 初始化为-1,确保第一次随机数有效 // 自定义字符:挪威语字母Å的点阵 byte custom_Aa[8] = { B00100, B01010, B00100, B01110, B00001, B01111, B10001, B01111 }; // 赞美语数组,\x00对应索引0的自定义字符 const char* compliments[] = { "Test 0 \x00", "Test 1", "Test 2", "Test 3", "Test 4", "Test 5", "Test 6", "Test 7", "Test 8", "Test 9" }; // 清除LCD第1-3行 void clearLowerLCDRows() { for (int row = 1; row < 4; row++) { lcd.setCursor(0, row); lcd.print(" "); } } // 解析并打印含自定义字符的赞美语 void printCompliment(const char* str) { while (*str != '\0') { if (*str == '\x00') { lcd.write(0); // 输出索引0的自定义字符 } else { lcd.print(*str); } str++; } } void setup() { Serial.begin(9600); randomSeed(analogRead(A0)); pinMode(BUTTON_PIN, INPUT_PULLUP); // LCD初始化 lcd.init(); lcd.backlight(); lcd.createChar(0, custom_Aa); // 将自定义字符存入索引0 // 初始界面 lcd.setCursor(0, 1); lcd.print(" Dette er en boks "); lcd.setCursor(0, 2); lcd.print(" Trykk her "); } void loop() { // 按钮按下检测(INPUT_PULLUP,按下时为低电平) if (!digitalRead(BUTTON_PIN)) { // 生成与上一次不同的随机数 do { randNum = random(NUM_COMPLIMENTS); } while (randNum == previousRandNum); previousRandNum = randNum; clearLowerLCDRows(); lcd.setCursor(0, 0); printCompliment(compliments[randNum]); Serial.println(randNum); // 按钮防抖,避免重复触发 unsigned long pressTime = millis(); while (!digitalRead(BUTTON_PIN) && millis() - pressTime < 500); } }
内容的提问来源于stack exchange,提问作者Robin Bråthen
相关产品推荐
相关产品推荐

