Антимограние I2C LCD1602

LCD1602_I2CВсем привет.

Разрабатывал проект с выводом информации на дисплей LCD 1602 через I2C шину. Жутко добивало моргание дисплея и потом оказалось что из-за данного моргания не работал энкодер.

Данное моргание происходит по двум причинам:

  1. Шина подключения I2C. Тут приведено сравнения скорости работы, как видно данный способ «тормозит» скорость на 66% от прямого подключения.
  2. Подход в выводе данных. Каждый проход LOOP цикла мы посылаем много комманд (в моем случае было больше 20):
    • очищаем дислей
    • устанавливаем курсор (несколько раз)
    • записываем данные (несколько раз)

Если в первом случае я сделать ничего не могу (не хочу задействовать аж 7 портов Arduino), то во втором случая проблема решается достаточно просто.

Итак что я сделал:

  1. Информация отправляется НЕ в дисплей, а в переменную.
    1. Создаем две переменных в которых храним строку для вывода в дисплей
    2. Для указания позиции вывода информации в строку создал функцию, Которая принимает 4 параметра:
      1. Строка в которую нужно добавить инфу
      2. Инфа которую добавляем
      3. Позиция начала ввода инфы
      4. Позиция окончания ввода инфы
    3. Функция умеет:
      1. Добавлять пробелы если длина строки меньше выделенного диапазона.
  2. Сохраняю предыдущее значение двух строк, и только в случае их изменения посылаю новую комманду на вывод в дисплей.

Итог:

  • + Дисплей не мограет
  • + Задержки в коде сведены к минимуму что позволяет использовать энкодер.
  • + Минимальное изменение кода.
  • + Не нужно менять «железо»

Пример функции

[cpp]
String put2string(String inputStr, String addStr, int from, int to) {

int addStrSize = addStr.length();
int addStrMaxSize = to — from;
String strBefore = "";
String strAfter = "";

if(from > 0){
strBefore = inputStr.substring(0, from);
}

strAfter = inputStr.substring(to + 1);

if (addStrSize < addStrMaxSize) {
for (int i = addStrSize; i < addStrMaxSize; i++) {
addStr = " " + addStr;
}
}

return strBefore + addStr + strAfter;
}
[/cpp]

Пример использования

[cpp]
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x20, 16, 2);

String ant_name_current = "ANT1";
int  sensor_degree = 100;

String display_last_info_1 = "                ";
String display_last_info_2 = "                ";

void setup()
{
  //Begin the LCD interface
  lcd.init();                      // initialize the lcd
  lcd.backlight();
}

void loop()
{
//ваш код

  show_display();
}

void show_display() {
  String outStr1 = "                ";
  String outStr2 = "                ";
 
//Нужно заменить на ваши переменные
  outStr1 = put2string(outStr1, ant_name_current, 6, 9);

  if (display_last_info_1 != outStr1) {
    display_last_info_1 = outStr1;
    lcd.setCursor (0, 0);
    lcd.print(outStr1);
  }

  ////////////////////////////////////////

//Нужно заменить на ваши переменные
  outStr2 = put2string(outStr2, String(sensor_degree), 11, 13);
 
  if (display_last_info_2 != outStr2) {
    display_last_info_2 = outStr2;
    lcd.setCursor (0, 1);
    lcd.print(outStr2);
  }
}
[/cpp]

P.S.

очень хочется чтобы подобный функционал был добавленный в библиотеку, тогда код вообще не придется изменять код кроме того чтобы послать в конце кода комманду на вывод информацию на дислей.

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *