Мерцает дисплей 1602

Тема в разделе "Arduino & Shields", создана пользователем Karabas, 22 ноя 2015.

  1. Karabas

    Karabas Гик

    Вобщем беда пришла откуда не ждали :)
    Простейшая схема регулятора мощности, понадобилось для наглядности прикрутить индикацию, ну, дурное дело не хитрое.

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

    Да еще добавилось, если на экране было трехзначное число, то двухзначное пишется на него, при этом третий знак остается, в итоге вместо 80 рисует 800.

    Чтоб хоть как то победить недуг, ввел проверку или кто то крутил ручку, если были изменения - lcd.clear();
    Но то же не выход, так как если крутить быстро- все плывет, если ручка останется в неустойчивом положении (-\+ 1 деление) экран опять будет помигивать.

    Код (C++):
    #include <LiquidCrystal.h>
    LiquidCrystal lcd(4, 5, 10, 11, 12, 13);
    int power;
    int ind;
    int tmp;
    int prev;
    int curr;
    void setup()
    {
      pinMode (3, OUTPUT);
      pinMode (A0, INPUT);
      lcd.begin(16, 2);
      Serial.begin(9600);
    }
    void loop()
    {

      tmp = analogRead(A0);
      power = map(tmp, 0, 1023, 0, 255);
      curr = power;
      lcd.setCursor(0, 0);
      lcd.print ("Power>");
      lcd.print (power);
      lcd.setCursor(0, 1);
      ind = map (power, 0, 255, 0, 16);
      for (int i = 0; i < ind; i++)
      {
        lcd.print ("*");
      }
      analogWrite(3, power);
      if (curr != prev)lcd.clear();
      prev = curr;
    }
     
  2. geher

    geher Гуру

    Очистка экрана - это зло, порождающее ненужное мерцание.
    Правильнее выводить только изменившиеся данные.
    С выравниванием влево:
    Код (C):

      lcd.print ("Power>");
      lcd.print (power);
      if (power<100) lcd.print (" ");
      if (power<10) lcd.print (" ");
     
    С выравниванием вправо:
    Код (C):

      lcd.print ("Power>");
      if (power<100) lcd.print (" ");
      if (power<10) lcd.print (" ");
      lcd.print (power);
    В этом случае число всегда занимает фиксированное количество позиций (в данном случае три), если оно не выходит за определенные пределы (в данном случае 0 - 999).

    Линейку звездочек нужно просто явно добивать до конца пробелами;
    Код (C):

    for (int i = 0; i < ind; i++)
      {
        lcd.print ("*");
      }
    for (int i = ind; i < 16; i++)
      {
        lcd.print (" ");
      }
     
    Чтобы победить излишнее мерцание при быстром изменении достаточно производить вывод не каждый раз, а хотя бы пару раз в секунду или реже.
    Примерно так:
    Код (C):

    static unsigned long int lastouttime=0;
    if ((millis()-lastouttime)>500)
    {
        // начало вывода на дисплей
        ...
        // завершение вывода не дисплей
        lastouttime=millis();
    }
     
     
    Tomasina и Karabas нравится это.
  3. Karabas

    Karabas Гик

    Спасибо, все стало намного приятней.
    Была мысль формировать строки вида "001", но я был уверен, что есть более элегантное решение, чем просто забивать пустотой.
     
  4. DrProg

    DrProg Вечный нерд

    Вот это:
    Код (C++):
     lcd.print ("Power>");
    каждый раз выводить не нужно, достаточно одного раза в setup, а потом:
    Код (C++):
    lcd.setCursor(7,0);
    lcd.print (power);
    И, как выше заметили, выводить не каждую итерацию loop (тысячи раз в секунду), а раз в секунду например. Для этого воспользоваться таймером и оператором millis();
     
    ИгорьК нравится это.