如何修复闪烁的 LED 矩阵和液晶菜单屏幕
How to fix a flickering led Matrix and lcd menu screen
我正在制作一个项目,其中有一个 LED 矩阵、LCD 和 7 个不同的传感器。每个传感器都会向矩阵显示不同的消息,并且在 LCD 上有自己的子菜单。
我创建了一个用于在传感器之间切换的菜单。旋转编码器用于在菜单中导航。 (一个引脚有一个变化中断,当引脚改变时只执行无效循环)还有一个 select 按钮用于 运行 菜单项的程序。(传感器程序如 prg_Pong(), prg_Flame());
我想在 LCD 上显示菜单项(无 I2C)。现在我的问题是我的主菜单项显示正确(没有闪烁,因为旋转编码器引脚中断)
但是当我按下按钮 运行 for ex prg_Pong() 时,lcd 打印消息 运行ning pong 但消息在闪烁并且 LED 矩阵上的消息是好的(静态)。
我通过添加延迟 (300) 找到了解决方案;在 drawMenu 之后的循环中,但是当我这样做并输入 prg_Pong();
LED 矩阵上的信息在延迟时间开始闪烁,菜单项 "running pong" 不再闪烁。
函数 displayData(),mtx_clear() 用于 led 矩阵,它们正在工作。因为当我删除 LCD 的功能时,消息显示正确。
void loop() {
drawMenu(RotaryEncoder());
delay(300);
}
void drawMenu(byte rotaryPosition) {
stateBtnSelect = digitalRead(BTN_SELECT);
if (stateBtnSelect == HIGH && previousBtnState == LOW && millis() - time > debounce) {
if (state == HIGH)
state = LOW;
else
state = HIGH;
time = millis();
}
previousBtnState = stateBtnSelect;
//Switch the value of the rotary encoder
switch (rotaryPosition) {
case 0:
displayMenuItem(0);
if (state == HIGH) {
prg_Pong();
}
break;
case 1:
displayMenuItem(1);
if (state == HIGH) {
prg_Ascroll();
}
break;
case 2:
displayMenuItem(2);
if (state == HIGH) {
prg_Clock();
}
break;
case 3:
displayMenuItem(3);
if (state == HIGH) {
prg_Flame();
}
break;
case 4:
displayMenuItem(4);
if (state == HIGH) {
prg_Heartbeat();
}
break;
default:
break;
}
}
//Display a menu item
void displayMenuItem(byte item)
{
//menu strings (mai n categories)
String menuItems[MAX_MENU_ITEMS] = {"Pong game", "A. Scroller", "Clock", "Flame/temp", "Heartbeat"};
lcd.clear();
lcd.setCursor(6, 0);
lcd.print("Menu");
lcd.setCursor(0, 1);
lcd.write(byte(0));
lcd.print(menuItems[item]);
}
void prg_Pong()
{
lcd.clear();
delay(100);
lcd.print("run pong");
mtx_clear();
//print cirlce once
MessageEncoder(ReturnLetter(24), BitStream);
for (int j = 0; j < 8; j++)
{
displayData(~BitStream[j] & Kolommen[j]);
}
}
你经常清除液晶显示,所以它看起来像闪烁。
我又用了两个变量找,有没有必要更新显示?仅在需要时更改显示内容,我没有编译代码,但希望这能解决您的问题,我在我的项目中使用了类似的技术。
prev_menu=-1;
update_display=true;
void loop() {
drawMenu(RotaryEncoder());
delay(300);
}
void drawMenu(byte rotaryPosition) {
stateBtnSelect = digitalRead(BTN_SELECT);
if (stateBtnSelect == HIGH && previousBtnState == LOW && millis() - time > debounce) {
if (state == HIGH)
state = LOW;
else
state = HIGH;
time = millis();
update_display=true;
}
previousBtnState = stateBtnSelect;
if(prev_menu != rotaryPosition)
update_display=true;
else
update_display=false;
//Switch the value of the rotary encoder
switch (rotaryPosition) {
case 0:
displayMenuItem(0);
if (state == HIGH) {
prg_Pong();
}
break;
case 1:
displayMenuItem(1);
if (state == HIGH) {
prg_Ascroll();
}
break;
case 2:
displayMenuItem(2);
if (state == HIGH) {
prg_Clock();
}
break;
case 3:
displayMenuItem(3);
if (state == HIGH) {
prg_Flame();
}
break;
case 4:
displayMenuItem(4);
if (state == HIGH) {
prg_Heartbeat();
}
break;
default:
break;
}
}
//Display a menu item
void displayMenuItem(byte item)
{
//menu strings (mai n categories)
if( update_display){
String menuItems[MAX_MENU_ITEMS] = {"Pong game", "A. Scroller", "Clock", "Flame/temp", "Heartbeat"};
lcd.clear();
lcd.setCursor(6, 0);
lcd.print("Menu");
lcd.setCursor(0, 1);
lcd.write(byte(0));
lcd.print(menuItems[item]);
prev_menu=item;
}
}
void prg_Pong()
{
if(update_display){
lcd.clear();
delay(100);
lcd.print("run pong");
update_display=false;
}
mtx_clear();
//print cirlce once
MessageEncoder(ReturnLetter(24), BitStream);
for (int j = 0; j < 8; j++)
{
displayData(~BitStream[j] & Kolommen[j]);
}
}
我正在制作一个项目,其中有一个 LED 矩阵、LCD 和 7 个不同的传感器。每个传感器都会向矩阵显示不同的消息,并且在 LCD 上有自己的子菜单。
我创建了一个用于在传感器之间切换的菜单。旋转编码器用于在菜单中导航。 (一个引脚有一个变化中断,当引脚改变时只执行无效循环)还有一个 select 按钮用于 运行 菜单项的程序。(传感器程序如 prg_Pong(), prg_Flame());
我想在 LCD 上显示菜单项(无 I2C)。现在我的问题是我的主菜单项显示正确(没有闪烁,因为旋转编码器引脚中断) 但是当我按下按钮 运行 for ex prg_Pong() 时,lcd 打印消息 运行ning pong 但消息在闪烁并且 LED 矩阵上的消息是好的(静态)。
我通过添加延迟 (300) 找到了解决方案;在 drawMenu 之后的循环中,但是当我这样做并输入 prg_Pong(); LED 矩阵上的信息在延迟时间开始闪烁,菜单项 "running pong" 不再闪烁。
函数 displayData(),mtx_clear() 用于 led 矩阵,它们正在工作。因为当我删除 LCD 的功能时,消息显示正确。
void loop() {
drawMenu(RotaryEncoder());
delay(300);
}
void drawMenu(byte rotaryPosition) {
stateBtnSelect = digitalRead(BTN_SELECT);
if (stateBtnSelect == HIGH && previousBtnState == LOW && millis() - time > debounce) {
if (state == HIGH)
state = LOW;
else
state = HIGH;
time = millis();
}
previousBtnState = stateBtnSelect;
//Switch the value of the rotary encoder
switch (rotaryPosition) {
case 0:
displayMenuItem(0);
if (state == HIGH) {
prg_Pong();
}
break;
case 1:
displayMenuItem(1);
if (state == HIGH) {
prg_Ascroll();
}
break;
case 2:
displayMenuItem(2);
if (state == HIGH) {
prg_Clock();
}
break;
case 3:
displayMenuItem(3);
if (state == HIGH) {
prg_Flame();
}
break;
case 4:
displayMenuItem(4);
if (state == HIGH) {
prg_Heartbeat();
}
break;
default:
break;
}
}
//Display a menu item
void displayMenuItem(byte item)
{
//menu strings (mai n categories)
String menuItems[MAX_MENU_ITEMS] = {"Pong game", "A. Scroller", "Clock", "Flame/temp", "Heartbeat"};
lcd.clear();
lcd.setCursor(6, 0);
lcd.print("Menu");
lcd.setCursor(0, 1);
lcd.write(byte(0));
lcd.print(menuItems[item]);
}
void prg_Pong()
{
lcd.clear();
delay(100);
lcd.print("run pong");
mtx_clear();
//print cirlce once
MessageEncoder(ReturnLetter(24), BitStream);
for (int j = 0; j < 8; j++)
{
displayData(~BitStream[j] & Kolommen[j]);
}
}
你经常清除液晶显示,所以它看起来像闪烁。
我又用了两个变量找,有没有必要更新显示?仅在需要时更改显示内容,我没有编译代码,但希望这能解决您的问题,我在我的项目中使用了类似的技术。
prev_menu=-1;
update_display=true;
void loop() {
drawMenu(RotaryEncoder());
delay(300);
}
void drawMenu(byte rotaryPosition) {
stateBtnSelect = digitalRead(BTN_SELECT);
if (stateBtnSelect == HIGH && previousBtnState == LOW && millis() - time > debounce) {
if (state == HIGH)
state = LOW;
else
state = HIGH;
time = millis();
update_display=true;
}
previousBtnState = stateBtnSelect;
if(prev_menu != rotaryPosition)
update_display=true;
else
update_display=false;
//Switch the value of the rotary encoder
switch (rotaryPosition) {
case 0:
displayMenuItem(0);
if (state == HIGH) {
prg_Pong();
}
break;
case 1:
displayMenuItem(1);
if (state == HIGH) {
prg_Ascroll();
}
break;
case 2:
displayMenuItem(2);
if (state == HIGH) {
prg_Clock();
}
break;
case 3:
displayMenuItem(3);
if (state == HIGH) {
prg_Flame();
}
break;
case 4:
displayMenuItem(4);
if (state == HIGH) {
prg_Heartbeat();
}
break;
default:
break;
}
}
//Display a menu item
void displayMenuItem(byte item)
{
//menu strings (mai n categories)
if( update_display){
String menuItems[MAX_MENU_ITEMS] = {"Pong game", "A. Scroller", "Clock", "Flame/temp", "Heartbeat"};
lcd.clear();
lcd.setCursor(6, 0);
lcd.print("Menu");
lcd.setCursor(0, 1);
lcd.write(byte(0));
lcd.print(menuItems[item]);
prev_menu=item;
}
}
void prg_Pong()
{
if(update_display){
lcd.clear();
delay(100);
lcd.print("run pong");
update_display=false;
}
mtx_clear();
//print cirlce once
MessageEncoder(ReturnLetter(24), BitStream);
for (int j = 0; j < 8; j++)
{
displayData(~BitStream[j] & Kolommen[j]);
}
}