Oled дисплей (решение проблемы с торможением ардуины)

Тема в разделе "Arduino & Shields", создана пользователем kt315where, 3 фев 2018.

  1. kt315where

    kt315where Гик

    Здравствуйте. На всякий случай решил поделиться ситуацией, с которой я столкнулся, возможно новичкам в будущем эта информация будет полезна

    недавно я создавал тему http://forum.amperka.ru/threads/Вопрос-про-delay-и-millis.14406/#post-149148

    писал там вопрос не с проста.

    Дело в том, что я столкнулся с очень странным явлением, с которым никогда раньше не сталкивался
    Возможно кто-то еще из новичков испытает подобную проблему, поэтому сделаю мир лучше и оставлю этот пост на форуме.

    Использую дисплей 128х64 пикселя, вот такой
    oled_micro_i2c_mkpochtoi (1).jpg

    подключается по 4 проводам (SDA, SCL , GND , +5V)

    Использую библиотеку OLED_I2C.h

    Короче, этот дисплей в скетче стал тормозить мк, причем выявить это можно только если вы делаете какой-то более менее серьезный проект, в котором есть millis, или любые другие факторы позволяющие наглядно выявить скорость работы ардуины. в моем случае был таймер считающий время с начала работы мотора, так вот за 3 часа работы расхождение с обычным секундомером в телефоне получилось почти в 50 минут :eek:

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

    например если вы в loop напишите что-то вроде такого:

    Код (C++):
     myOLED.clrScr(); //очищаем дисплей от всего
      myOLED.drawBitmap(0, 0, logo1, 128, 64); // выводим картинку из библиотеки, файл с пикселями картинки должен быть заранее подключен к скетчу
      myOLED.update(); // обновляем буфер дисплея

    то при таком раскладе процессор ардуины скорее всего будет очень сильно тормозить.

    Дело в том, что обновление дисплея myOLED.update(); будет работать при каждом проходе void loop, а это огромное количество обновлений с большой частотой.

    Поэтому, нужно применить задержку. но не в коем случае не delay!

    Делаем через millis()

    Я сделал вот так:

    вначале объявляем переменную

    Код (C++):
    unsigned long time_oled_update;
    ну и отрабатываем время обновления в loop
    Код (C++):
    if (millis() - time_oled_update > 200)
    {
      time_oled_update = millis();
      myOLED.update();
    }

    Как Вы можете видеть, я у себя поставил время обновления 200м.с, т.е 5 раз в секунду. :)
    тормозов пока не наблюдаю. Для человеческого глаза актуально наверное до 24 раз в секунду, но мы же не кино смотрим здесь.
    Вообще хотелось бы провести тесты на частоту обновления дисплея и найти тот самый порог, начиная с которого и начинаются тормоза. А может кто-то уже делал такое?))) :D
     
    Последнее редактирование: 3 фев 2018
    b707 нравится это.
  2. DIYMan

    DIYMan Guest

    Не надо проводить никаких тестов, надо усвоить одну простейшую истину: обновлять дисплей только тогда, когда данные, которые должны быть на нём видны - изменились. И обновлять не весь экран, а только изменившуюся часть.

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

    И никаких тормозов, и ваши волосы мягкие и шелковистые.
     
    Сусемьбек, Arduino_man, Tomasina и 2 другим нравится это.
  3. b707

    b707 Гуру

    Добавлю к тому. что написал DIYMan.
    Если в результате слишком частого обновления дисплея у вас какой-то таймер отстал на 50 мин за 3 часа - это говорит лишь о том, что ваш таймер был написан с ошибкой. Системный таймер, на котором основан миллис - тикает с неизвменной скоростью независмо от загрузки процессора .

    В общем, вывод - очень хорошо, что вы сами додумались, что экран стоит обновлять пореже, однако вам еще очень многое предстоит узнать о ардуино, в частности о правильной работе с экраном и таймерами :)
     
    Arduino_man и arkadyf нравится это.
  4. DetSimen

    DetSimen Guest

    если ничьи шаловливые ручки прерывания не запретять.
     
    Arduino_man нравится это.
  5. Arduino_man

    Arduino_man Гик

    М-да! Никогда не ставьте обновления чего-либо в loop.
     
  6. SergeiL

    SergeiL Оракул Модератор

    Интересная точка зрения :) !
    А где Вы предлагаете проводить обновление, к примеру, данных, отображаемых на дисплее?
     
  7. Arduino_man

    Arduino_man Гик

    Я не то имел в виду :). Я просто хотел поддержать идею @DIYMan , что нужно проводить обновление только тогда, когда оно нужно.
     
  8. ostrov

    ostrov Гуру

    Можно не запрещая перенастроить. ))
     
  9. kvitko1

    kvitko1 Гик

    Здравствуйте. Я новичок пользуюсь Ардуино Уно. Очень хочу зделать метеостанцию, и мне нужен дисплей какой посоветуете?
     
  10. ostrov

    ostrov Гуру

    Посоветую купить готовую метеостанцию.
     
    parovoZZ нравится это.
  11. Securbond

    Securbond Гуру

    Странно что у Вас возник только этот вопрос )), а как вы будете датчики на улице развешивать (что бы их солнце не грело и дождь не заливал) и подключать их к Ардуино не думали ?
    Если вопрос только в экране то для начала обычный 20*4 экран с i2c шиной.
    Это при условии что питание от розетки. Если от батарейки, то экран лучше совсем исключить или использовать с низким энергопотреблением, например на жидких чернилах (дорого!).
     
  12. AlexU

    AlexU Гуру

    Откуда библиотеку брали?
    А то, ради интереса, посмотрел на первую, что попалась. Так "автор" библиотеки забил на нормальную настройку TWI и работает с интерфейсом в "ручном" режиме. И метод 'update()' запрещает прерывания на всё время обмена данными, а циклов там крутится не мало. С такой библиотекой работа встроенных RTC в Arduino будет нарушена в любом случае -- функция 'millis()' будет давать некорректные результаты, да впрочем и все остальные функции, завязанные на RTC на нулевом таймере. Такие библиотеки только "для поиграться", а потом на помойку...
     
  13. kvitko1

    kvitko1 Гик

    Спасибо!
     
  14. kvitko1

    kvitko1 Гик

    Спасибо. Я также хотел приобрести, но не нашел нужную.
    Напишите если знаете пожалуйста ссылку.
     
  15. Yasha

    Yasha Нуб

    Подскажите как обновлять только часть экрана, не очищая при этом весь экран?
     
  16. Tomasina

    Tomasina Сушитель лампочек Модератор

    Затирать существующий рисунок таким же, но черным цветом, затем отправлять команду на обновление экрана.
     
  17. parovoZZ

    parovoZZ Гуру

    С дисплеями надо по SPI общаться или параллельно, но никак не через тормознутый I2C
     
    NikitOS нравится это.
  18. NikitOS

    NikitOS Король шутов Администратор

    Неа, это не то :)
    Надо не отчищая весь дисплей, а при обновлении он отчистится..