Arduino оптимизация использования оперативной памяти

แชร์
ฝัง
  • เผยแพร่เมื่อ 11 ส.ค. 2019
  • Примеры простейшей оптимизации использования оперативной памяти для Arduino (AVR, ESP8266, ESP32).
    В видео на 11-ой минуте в показанном коде ошибка: для определения длины строки, находящейся во флеше, надо использовать функцию strlen_P() вместо strlen().
    Спасибо внимательному зрителю.
  • วิทยาศาสตร์และเทคโนโลยี

ความคิดเห็น • 35

  • @alexgalstyan
    @alexgalstyan 4 ปีที่แล้ว +9

    И совсем не важно, знаю я это материал или нет все равно всегда приятно слышать Ваши уроки :). Спасибо !! Всегда в тему !!!

  • @user-yu5ml5ks6r
    @user-yu5ml5ks6r 4 ปีที่แล้ว +2

    Как всегда на уровне

  • @Artha111
    @Artha111 4 ปีที่แล้ว +2

    Алексей, огромная благодарность за Ваши уроки! Начинал программировать как "олень", теперь уже как "тюлень", правда, код пока ещё работает как "сонный горностай", но совершенствуюсь... :)
    Есть просьба, огромная, рассмотреть возможность для ESP8266, в дополнение к видео по ООП, показать как сделать библиотеку со своими классами для обработки "кнопок" (т.е. замыкающих/размыкающих входных устройств)
    с использованием прерываний как метода класса (это ключевое, остальное понятней...),
    отработки кратких, долгих, нескольких (double click к примеру) нажатий с программным подавлением дребезга контактов. Во, сформулировал...
    С уважением, Андрей.

    • @alexmorozov73
      @alexmorozov73  4 ปีที่แล้ว

      А th-cam.com/video/OM0f9QZx224/w-d-xo.html не подходит?

    • @Artha111
      @Artha111 4 ปีที่แล้ว

      О, Великий, Великий, где были мои глаза! ((с) не помню). Думал все видео видел, а самое востребованное мимо прошло... Вай, вай, тюленя, аднака!
      Благодарю!

  • @irongarden8415
    @irongarden8415 4 ปีที่แล้ว

    Благодарю, о макросе F не слышал, теперь буду знать. В своих скетчах тоже использовал способы записи массивов констант во флеш, используя avr_pgmspace.

  • @DIY-Club
    @DIY-Club 4 ปีที่แล้ว

    Полезное видео, лайк!

  • @SergeyBelotserkovskiy
    @SergeyBelotserkovskiy 4 ปีที่แล้ว

    круто, несколько раз пересматривал

  • @maksmaxkanal
    @maksmaxkanal 4 ปีที่แล้ว

    Здравствуйте. У вас точно включены оптимизации компилятора. Мне кажется, что преобразование string в char в первом примере должно происходить автоматически.

  • @ulibkaify
    @ulibkaify 4 ปีที่แล้ว +2

    Большое спасибо за видео! Скажите пожалуйста - в случае esp 8266 и esp 32 библиотека та же или другая?

    • @alexmorozov73
      @alexmorozov73  4 ปีที่แล้ว +7

      Библиотека pgmspace.h в случае с ESP находится в том же каталоге, где само ядро Arduino, т.е. в #include не нужен путь перед именем файла.
      Хотя с какого-то времени вместо того, чтобы объяснить людям, что библиотеки из каталога avr/ являются нативными только для AVR, создатели Arduino для ESP8266 сделали копию файла pgmspace.h и по пути avr/
      Но лучше используйте для ESP
      #include

  • @anlaz1
    @anlaz1 2 ปีที่แล้ว

    Очень интересно. Спасибо Я собрал пару ЧПУ-станков. Один для фрезерования рельефов, второй лазерный гравёр. Использую программу GRBL 1.1. На этом месте и начинается мой вопрос.
    При загрузке скетча в arduino я получаю сообщение "Недостаточно памяти, программа может работать нестабильно".
    При этом скетч использует 96% памяти, а глобальные переменные - 1633 (79%).
    Спрашивается, можно ли оптимизировать GRBL чтобы освободить немного памяти :) ? :)

  • @user-rt5mm3ee4k
    @user-rt5mm3ee4k 4 ปีที่แล้ว

    Спасибо!

  • @vicusvanbacvic8618
    @vicusvanbacvic8618 2 ปีที่แล้ว

    Отлично! Ваши уроки будут легче восприниматься на белом фоне и пож-та не строчите как пулемет! И также манера повествования должна походить на четко выстроенный программный алгоритм.

    • @vladimirvt3930
      @vladimirvt3930 ปีที่แล้ว

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

  • @leoalex3271
    @leoalex3271 4 ปีที่แล้ว

    Звиняюсь, а нет ли метода отслеживания объема свободной памяти в ходе выполнения программы? Понятно, что в случае с сhar'ами место для них выделяется на этапе компилирования и все понятно. Но у меня проект весь на string'ах (отправка СМС, получение ответов от GSM-модуля, команды GSM-модулю и т.д.) они хоть все и локальные и как-бы должны убиться при выходе из области видимости, но передаются из функции в функцию (по значению, можно сделать по адресу, но мне кажется не в этом суть). Наслушавшись о коварстве string'ов, у меня возникло беспокойство, что они будут оставлять "хвосты" в памяти, постепенно заполняя ее. И хотя у меня мега2560 и там памяти для моей задачи более чем, хотелось-бы "пощупать все руками", понять насколько страшен чёрт. С уважением, мамкин программист.

    • @leoalex3271
      @leoalex3271 4 ปีที่แล้ว +1

      Еще раз извиняюсь, возможно вам это тоже будет интересно. Нарыл в интернете такую незамысловатую функцию:
      int freeRam ()
      {
      extern int __heap_start, *__brkval;
      int v;
      return (int) &v - (__brkval == 0 ? (int) &__heap_start : (int) __brkval);
      }
      Понятия не имею как и насколько корректно она работает. Вставил в свой скетч, скомпилировал :
      Sketch uses 57 076 bytes (22%) of program storage space. Maximum is 253 952 bytes.
      Global variables use 2 298 bytes (28%) of dynamic memory, leaving 5 894 bytes for local variables. Maximum is 8 192 bytes.
      Сразу после запуска Free memory= 5749. Затем серия звонков, DTMF комманд, исходящих и входящих СМС - Free memory сделалась 5495 и больше не уменьшалась что-бы я ни делал. Но затем пришли две длинные СМС от оператора (или одна СМС в двух частях, хз) после чего свободная память уменьшилась до 4309 и так и осталась что-бы я ни делал. Отсюда мораль - однажды увеличив (запросив память) для String'а, программа больше не уменьшает занятую для него память, только увеличивает.
      Вроде-бы не критично (для меня) , но ради науки стоит разобраться и килобайт тоже жалко, продолжаю эксперименты.

  • @mbikola.bigboss
    @mbikola.bigboss 4 ปีที่แล้ว

    Здравствуйте. Я не эксперт но вроде где-то слыхал что у флеш памати есть ограничения по циклу чтению и записи данных.

    • @alexmorozov73
      @alexmorozov73  4 ปีที่แล้ว +1

      Никакая память из коммерчески реализуемых не имеет ограничений на количество чтений!
      А запись флеша случается только при заливке нового скетча, да и ресурс по записи флеш-памяти исчисляется 1000+ циклами. Вот скорость доступа ниже, чем у ОЗУ, но в случае с Serial.print в любом случае в разы выше скорости UART, так что никакой разницы во времени выполнения не будет.

  • @user-ei4wf1ng8d
    @user-ei4wf1ng8d 4 ปีที่แล้ว

    Здравствуйте . Подскажите пожалуйста можно ли в Ардуино сравнить 32 битовую маску , спрашиваю так как 16 битовую маску у меня получается сравнить , а вот 32 бита нет. Мне надо отправить 32 бита данных в сдвиговый регистр. Спасибо .

    • @alexmorozov73
      @alexmorozov73  4 ปีที่แล้ว

      Почему же нельзя? Можно.
      Если вы сравниваете две 32-х битные переменные, то проблем вообще никаких, а если битность сравниваемых значений разная, то принудительно приводите меньшую к большей. В случае констант или тоже приводите их к типу или с помощью суффикса указывайте компилятору разрядность константы (123L - это (long int)123, 0UL - это (uint32_t)0).
      uint32_t a;
      uint16_t b;
      if (a == (uint32_t)b) ...
      Особое внимание к битовым сдвигам, расширяйте приведением типов аргумент заранее в разрядность результата, чтобы не было сюрпризов.

  • @sergewddm
    @sergewddm 4 ปีที่แล้ว +1

    Наверное, для определения длин строк во флэше правильнее использовать strlen_P().

    • @alexmorozov73
      @alexmorozov73  4 ปีที่แล้ว +3

      Точно! Вот что значит не загонять в плату код. Спасибо!
      Приписал текст под видео, вдруг кто читает.

    • @sergewddm
      @sergewddm 4 ปีที่แล้ว +1

      @@alexmorozov73 Спасибо за Ваши видео. Очень много полезного узнал и узнаю для себя.

  • @avazart614
    @avazart614 4 ปีที่แล้ว

    Наверное лучше будет в одну строку:
    Serial.printf_p(PSTR("Humidity is %i %"), humidityValue);
    Вот с чем я не давно столкнулся это вопрос в том как хранить "кириллические" строки во флеше.
    И вообще не особо понятно как работать с юникодом.

    • @alexmorozov73
      @alexmorozov73  4 ปีที่แล้ว

      Ну попробуйте для AVR найти в классе HardwareSerial метод printf_P... :)
      Да и проигрыш в объеме программы все равно будет в случае использования printf/scanf.
      А в чем проблема UTF-8 во флеше? PSTR и PROGMEM же работают. Да, посимвольный доступ штатными средствами C++ не работает, но никто не мешает написать свои функции или класс. Я когда SMS-шлюз писал, намучился с поддержкой русского, но в итоге сделал аналоги strlen, strncpy и т.п. для UTF-8.

    • @avazart614
      @avazart614 4 ปีที่แล้ว

      @@alexmorozov73 Да я забыл что эта штука только для ESP.
      Такой пример:
      const char test[] PROGMEM = "Привет Мир!";
      void setup()
      {
      Serial.begin(9600);
      Serial.println(test);
      }
      Выводит "квадратики" в монитор порта.
      Если взять другой сериал терминал то видно что выводит '\0' символы.
      Дело в том что есть OLED 128x64 и есть библиотека u8glib в ней есть шрифты с кириллицей,
      но кириллица зашита особыми кодами символов именно по этому мне как раз требовалась посимвольная обработка.
      Выходом из ситуации было использование строк wchar_t c PROGMEM и чтение их через
      pgm_read_word() далее я их преобразовывал в коды понятные дисплею.

    • @alexmorozov73
      @alexmorozov73  4 ปีที่แล้ว

      В вашем примере очевидная ошибка. Строка хранится во флеше, а выводите вы обычными средствами. И причем тут unicode?
      Монитор порта прекрасно работает с UTF-8. В вашем коде надо исправить
      Serial.println((const __FlashStringHelper*)test);
      Ну а как побайтно читать UTF-8 - написано много где. Так что совсем необязательно хранить строки как массив двухбайтных символов.

    • @avazart614
      @avazart614 4 ปีที่แล้ว

      ​@@alexmorozov73 Да интересный момент, не думал что тут явное приведение типов поможет.

    • @alexmorozov73
      @alexmorozov73  4 ปีที่แล้ว

      Макрос F() именно приводит PSTR параметра к указателю на пустой тип __FlashStringHelper, чтобы показать print'у, что надо печатать строку именно из флеша. Поэтому никто не мешает вручную привести к этому типу нашу константу во флеше. По адресу нельзя понять, где именно находится строка, поэтому применяется пустой класс-заглушка для различия типов.

  • @andreyparovozz
    @andreyparovozz 4 ปีที่แล้ว

    Единственное верное решение по экономии озу - отказ от абдурины. 328 проц весьма древний проц и не понимаю, зачем его активно мусолить? Где обзор новых разработок? Я так понимаю, что телепузикам сложно вылезти из стен, воздвигнутых дядей для одурачивания. Дизлайк и отписка.

    • @ByteSmart
      @ByteSmart 4 ปีที่แล้ว +2

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

    • @XanderEVGs
      @XanderEVGs 3 ปีที่แล้ว +2

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

  • @Ura2404
    @Ura2404 4 ปีที่แล้ว

    Спасибо !