Мигающий символ на lcd 128x64

Sanho
Offline
Зарегистрирован: 24.02.2016

 Ребята, просмотрел кучу видео примеров с дисплеем 128х64 и ардуино, нигде не встретил мигающий символ, в описании библиотеки, тоже не нашел. В библиотеке U8GLIB в примере bitmap, символ просто выводится на дисплей. А как заставить его мигать, например с интервалом в 1 секунду? С диодом то все понятно. а вот как с символом на дисплее, и без delay, не очень. Умные головы, подскажите новичку, где рыть.  

U8GLIB_PCD8544 u8g(13, 11, 10, 9, 8);                    // SPI communication: SCK = 13, MOSI = 11, CS = 10, A0 = 9, Reset = 8

const uint8_t rook_bitmap[] U8G_PROGMEM = {
  0x00,         // 00000000 
  0x55,         // 01010101
  0x7f,          // 01111111
  0x3e,         // 00111110
  0x3e,         // 00111110 
  0x3e,         // 00111110
  0x3e,         // 00111110 
  0x7f           // 01111111
};

void draw(void) {
  // graphic commands to redraw the complete screen should be placed here  
  u8g.drawBitmapP( 0, 0, 1, 8, rook_bitmap);
}

void setup(void) {
}

void loop(void) {
  // picture loop
  u8g.firstPage();  
  do {
    draw();
  } while( u8g.nextPage() );

  // rebuild the picture after some delay
  delay(1000);
}

 

Клапауций 232
Offline
Зарегистрирован: 05.04.2016

класс титановый велосипед для delay без delay().

печатаешь символ и стираешь или печатаешь пустоту

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Так точно также как с диодом. Если там понятно, то и здесь понятно. Судя по всему не очень-то понятно. 

Вы свой символ вывести можете? И стереть можете. ну так возьмите программу для диода и там, где его зажигают - выводите, а где гасят - стирайте.

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

Есть путь немного посложне. Делаешь мультипоточную систему. Вешаешь один вычислительный поток на дисплей с обновлением дисплея в 1 секунду. Создаешь мигающую переменную ( 1 проход 0, 2 проход 1) Ну а потом условие когда печатать когда нет. Я так делаю на LCD1602 И2С. 

 ПС: Думаю вам понятно. Нет мультипоточной системы, нет мигания.

Sanho
Offline
Зарегистрирован: 24.02.2016

ЕвгенийП пишет:

Так точно также как с диодом. Если там понятно, то и здесь понятно. Судя по всему не очень-то понятно. 

Вы свой символ вывести можете? И стереть можете. ну так возьмите программу для диода и там, где его зажигают - выводите, а где гасят - стирайте.

То что для диода, сдесь совсем не походит. Например нужно включить элемент по достижению значения, он включается, но нужно чтоб он еще и мигал.

if (val/2-90 >= 20)
u8g.drawBitmapP( 5, 8, 1, 10,simvol);

 

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

Ну а потом через некоторое время стирай , позже опять включай. Нужен дополнительный независимый поток. Или через прерывание или через миллис.

diger67
Offline
Зарегистрирован: 25.07.2015

Вам кусок теста написать? Вам написали алгоритм. Записывать информацию в матричный LCD вы как я понял умеете. Повторю только пространнее. Такой метод работы  называется спрайтовый. Подготавливаем два спрайта. В первом например рисуем почти разряженнуб батарейку и называем ее simvol_on, во втором пустой символ и называем его simvol_off. Cоздаем переменную bool status_simvol, он имеет всего два значения true и false. Для работы со спрайтовой графикой надо обновлять экран или выбранную область экрана с частотой незаметной для глаза и не ниже внутренней частоты обновления самого экрана. Для этого подойдет два варианта. Первый когда весь цыкл loop() не превышает времени частоты смены "кадра", используем millis(). Второй если время выполнения loop() сильно превышает время частоты смены кадра, используем прерывание по таймеру. Здесь пидется поковырятся. Далее исползуем алгоритм, выводим на экран  спрайт simvol_on, запоминаем статус, при выполнении условия смены состояния символа , выводим на экран simvol_off. И так пока не наступит сброс события. Тогда выводим simvol_off и запоминаем статус. Думаю так не очень запутано. Замечу, что ели ввести еще одну переменную переменную simvol_count, можно выводить анимированный спрайт, например вращающиеся песочные часы.

Nosferatu
Offline
Зарегистрирован: 04.11.2012

У меня реализовано так.

class Blink_LCD   // название класса
{
    /*    Класс для мерцания выведенной на LCD экран строковой переменной
          Вставка в код так
          ====================================================
          blink_LCD.Blink_Str = "Строка которая будет мерцать";
          blink_LCD.Blink();
          blink_LCD.Blink_Str <----- мерцающяя строка
    */
  public:
    String Blink_Str;  // переменная
    void Blink()  // добавляем функцию
    {
      if ((millis() & 512)) {
        String Str = "";
        int i =  Blink_Str.length();
        for (int z = 0; z < i; z++)
          Str =  Str + " ";
        Blink_Str = Str;
      } else {
        Blink_Str = Blink_Str;
      }
    }
};

Вставляю этот класс в начале скетча.

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Sanho пишет:

 но нужно чтоб он еще и мигал.

Так мигает-то это когда его то включают, то выключают. Ну и делайте это точно также, как с диодом.

Sanho
Offline
Зарегистрирован: 24.02.2016

Nosferatu

Спасибо за реальный ответ. будем попробовать. А вот если нужно мигать одновременно несколькими символами на дисплее в разных местах, наверно нужно управлять массивом.

[/quote]

Так мигает-то это когда его то включают, то выключают. Ну и делайте это точно также, как с диодом.

[/quote]

Символ на дисплее, немного сложней чем светодиод. 

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Sanho пишет:

Символ на дисплее, немного сложней чем светодиод. 

Абсолютно нет.

Сделайте функции symbolOn() - включает и sybmolOff() - гасит.

Ну и чем он сложнее? Какая разница вызывать digitalWrite или symbolOn ?

Ни грамма не сложнее.

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

Sanho пишет:
Символ на дисплее, немного сложней чем светодиод. 

Если это мигающий светодиод , то да. А вот если обычный,то одинаковая сложность. Алгоритм токой же но команды разные. Вас сбивает стандартная программа Блинк. Вот возьмите в вашей программе вместо мигания картинкой помигайте светодиодом и что бы программа при этом продолжала работать. Сразу поймете.

Nosferatu
Offline
Зарегистрирован: 04.11.2012

Sanho пишет:

А вот если нужно мигать одновременно несколькими символами на дисплее в разных местах, наверно нужно управлять массивом.

Если нужно мерцание отдельного символа, то можно сделать так.

(millis() & 512) ?  'd' :  ' ';

 

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

Nosferatu пишет:

(millis() & 512) ?  'd' :  ' ';

Есть маленькое замечание. Эту команду надо делать регулярно, как бы не чаще, чем мигаешь. А не как обычно.Сделал и перешел к следущей.

Sanho
Offline
Зарегистрирован: 24.02.2016

Ребята, всем спасибо!

Оказалось все очень просто.

Оно работает. Символы прекрасно мигают. Просто добавил одну строчку.

Как прекрасно решать проблемы вместе!

if (val/2-90 >= 20) \\ Включить при достижении параметра.
if ((millis() & 512)) \\ Мигание символа.
u8g.drawBitmapP( 5, 8, 1, 10, simvol); \\ Вывести символ в нужное место.

 

diger67
Offline
Зарегистрирован: 25.07.2015

Nosferatu пишет:

У меня реализовано так.

class Blink_LCD   // название класса
{
    /*    Класс для мерцания выведенной на LCD экран строковой переменной
          Вставка в код так
          ====================================================
          blink_LCD.Blink_Str = "Строка которая будет мерцать";
          blink_LCD.Blink();
          blink_LCD.Blink_Str <----- мерцающяя строка
    */
  public:
    String Blink_Str;  // переменная
    void Blink()  // добавляем функцию
    {
      if ((millis() & 512)) {
        String Str = "";
        int i =  Blink_Str.length();
        for (int z = 0; z < i; z++)
          Str =  Str + " ";
        Blink_Str = Str;
      } else {
        Blink_Str = Blink_Str;
      }
    }
};

Вставляю этот класс в начале скетча.

А вы думаете что вот это можно использовать с другими классами. Определите это как функцию и переменную. Классы создают объект который можно передать другому классу с наследованием или переопределить свойства функции.  Где кроме вашего применения ее можно использовать?

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

diger67 пишет:
А вы думаете что вот это можно использовать с другими классами. Определите это как функцию и переменную. Классы создают объект который можно передать другому классу с наследованием или переопределить свойства функции.  Где кроме вашего применения ее можно использовать?

Не надо высоко принимать этот код. Это просто заплатка.Все программы Ардуины это заплатка на заплатке. В Ардуине очень мало памяти, особенно оперативки что бы баловаться с наследованием и созданием базовых классов.

Nosferatu
Offline
Зарегистрирован: 04.11.2012

diger67 пишет:

А вы думаете что вот это можно использовать с другими классами. Определите это как функцию и переменную. Классы создают объект который можно передать другому классу с наследованием или переопределить свойства функции.  Где кроме вашего применения ее можно использовать?

Незнаю, я не программист.

diger67
Offline
Зарегистрирован: 25.07.2015

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

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

Вы когда нибудь разворачивали библиотеки Ардуино? Разверните и насладитесь кодом.

diger67
Offline
Зарегистрирован: 25.07.2015

Если Ваш вопрос адресован мне, то не только разворачивал, но и переносил на другие платформы, другую архитектуру и язык более низкого уровня, а конкретно С. В свое время все то что вы делаете на C++ с данным индикатором делалось на asm. в AtmelStudio.