Как исправить мерцание светодиодной матрицы и экрана ЖК-меню - PullRequest
0 голосов
/ 12 апреля 2019

Я делаю проект, в котором у вас есть светодиодная матрица, ЖК-дисплей и 7 разных датчиков. Каждый датчик будет отображать различные сообщения в матрице и имеет собственное подменю на ЖК-дисплее.

Я создал меню для переключения между датчиками. Вращающийся регулятор используется для навигации по меню. (Пин имеет прерывание при изменении для выполнения только цикла void, когда штырь изменился) Также кнопка выбора используется для запуска программы пункта меню (программа датчика, такая как prg_Pong (), prg_Flame ());

Я хочу отобразить пункты меню на ЖК-дисплее (без I2C). Теперь моя проблема в том, что пункты моего главного меню отображаются правильно (без мерцания из-за прерывания на контакте поворотного энкодера) но когда я нажимаю кнопку, чтобы запустить ex prg_Pong (), lcd печатает сообщение с запущенным понгом, но сообщение мигает, и сообщение на светодиодной матрице хорошее (статическое).

Я нашел решение, добавив задержку (300); в цикле после drawMenu, но когда я это сделаю и введите prg_Pong (); сообщение на светодиодной матрице начинает мигать во время задержки, и пункт меню «бегущий понг» больше не мигает.

Функции displayData (), mtx_clear () используются для светодиодной матрицы и работают. Потому что, когда я удаляю функциональность ЖК-дисплея, сообщение отображается правильно.

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]);
  }
}

1 Ответ

0 голосов
/ 12 апреля 2019

Вы часто очищаете ЖК-дисплей, поэтому он будет выглядеть как мерцание.

Я использовал еще две переменные, чтобы найти, есть ли необходимость в обновлении дисплея? меняйте содержимое дисплея только при необходимости, я не компилировал код, но надеюсь, что это решит вашу проблему, я использую похожую технику в своих проектах.

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]);
  }
}
...