Char* mess[] = {"...", "...", ...};

Тема в разделе "Микроконтроллеры AVR", создана пользователем Ariadna-on-Line, 19 мар 2025.

  1. AlexU

    AlexU Гуру

    По поводу использования макросов (#define) нашёл свой старый код (2020 год), код не завершённый, но для примера пойдёт.
    Реализована поддержка нескольких языков. Сообщения выдаются по коду для заданного языка.
    Количество языков и сообщений заданы в файле MenuMessages.h.
    А вся магия в файлах Messages.h и Messages.cpp.
    Макросы из данных файлов берут заданные языки и сообщения из файла MenuMessages.h и генерируют перечисления и нужные массивы со строками, которые могут хранится или во флэш, или в оперативке (см. макрос USE_PGM_SPACE).
    И стоит глянуть строку 43 в файле Menu.cpp.
     
  2. Ariadna-on-Line

    Ariadna-on-Line Гуру

    Успешно жму программу.
    String tape = "";
    char buf_g[strlen_P(TimeMess) + 1]; // Выделим буфер достаточной длины для "Время - "
    strcpy_P(buf_g, TimeMess); // Копируем в буфер строку из ПРОГМЕМа
    tape += buf_g; // Отдаем буфер в работу
    tape += now.hour();
    ,,,,,,
    tape = utf8rus(tape);
    Run();
    Спасибо за примеры - буду разбираться.
     
    Последнее редактирование: 26 мар 2025
  3. AlexU

    AlexU Гуру

    Вот этот код:
    Код (C++):
    char buf_g[strlen_P(TimeMess) + 1]; // Выделим буфер достаточной длины для "Время - "
    может доставить кучу проблем (в некоторых случаях).
    Что Вы хотите сделать?
    Может не стоит городить промежуточные буферы, а отправлять данные напрямую из флэш-памяти, минуя оперативную память?
     
  4. Ariadna-on-Line

    Ariadna-on-Line Гуру

    Использую готовые библиотеки, и вынужден подстраиваться под них. В данном случае должен скармливать им строки текста String tape = "xxx" . ПисАть код с нуля - не тот случай.
    Что я делаю ? На дачу себе рекламный щит и отпугивалку воришек )))). С часами, термометром и др.
     
    Последнее редактирование: 25 мар 2025
  5. AlexU

    AlexU Гуру

    Библиотеки разные бывают. Некоторые разработаны грамотными людьми.
    Ну как сказать. Вот к примеру библиотеки, которые основаны на классе Print (например, тот же Serial), они умеют работать с флеш-памятью напрямую через '__FlashStringHelper'. Может и та библиотека, которую Вы используете, тоже умеет читать напрямую из флеша? И не нужны ни какие промежуточные буферы (но это всего лишь предположение).
    Ну зачем "писать с нуля". В ООП есть наследование с полиморфизмом, может ту библиотеку, которую Вы используете, можно наследовать и чутка переделать.
    Бывает, что люди вместо цели, которой они хотят достичь, рассказывают о выбранном методе достижения этой цели и просят помочь устранить ошибки в этом методе. Но суть в том, что выбранный ими метод не корректный. Цель может быть достигнута с помощью других решений. Просто нужно рассказать:
    или другими словами -- к какой конечной цели стремитесь? Что хотите получить?
    А не -- "должен скармливать им строку текста" -- может не в этом дело?
     
    KindMan и ИгорьК нравится это.
  6. Ariadna-on-Line

    Ariadna-on-Line Гуру

    ПС. Нашел свою глупую ошибку. Поэтому удалил свои мессаджи не по делу.
     
    Последнее редактирование: 26 мар 2025
  7. AlexU

    AlexU Гуру

    Да, Вы задали почти исчерпывающий вопрос и привели свой код. Но вот вопрос -- Вы уверены, что тот подход, который Вы пытаетесь применить для решения своей задачи, является единственно верным?
    Может код должен быть другим?
    К примеру, Вы выводите строку на дисплей, используя функцию 'Print:: print' и думаете, что нужна обязательно строка и Вы её создаёте, используя буферы в оперативной памяти. Но есть другие реализации этой функции, которые могут читать флеш-память напрямую и выводить данные на дисплей, без необходимости создания промежуточных буферов в оперативной памяти.
    Поэтому и спрашиваю -- что Вы хотите получить? И я отвечу как этого достичь. Если будут нужны буферы, скажу как их создавать, переиспользовать и освобождать. Но есть подозрение, что можно обойтись без них, хотя могу ошибаться.
     
  8. Ariadna-on-Line

    Ariadna-on-Line Гуру

    Я же не книгу из флеша на бегущую строку вывожу. А строки составленные из кусков текста и цифр считываемых с часов, термометра, вольтметра, пульта ДУ, ну и может еще чего впихну)))) - В РЕЖИМЕ РЕАЛЬНОГО ВРЕМЕНИ. Сомневаюсь что это можно сделать без промежуточного буфера.
    Длинные сообщения именно рекламы тоже придется выводить. Вероятно именно так как вы говорите. Но я хотел это оставить на позже ))))
     
  9. AlexU

    AlexU Гуру

    Зря сомневаетесь.
    Всё зависит от способа сбора данных --
    Буфер может и не нужен.
     
  10. Ariadna-on-Line

    Ariadna-on-Line Гуру

    Спасибо всем. Уложился в 17794 байт флеша и 366 байт RAM-а. Осталось сделать авто-подсчет вкоряченных рекламных строк, но это уже роскошь !

    ПС.Ничего не смог найти, Потому вернулся к-с-чего начал ))) Коллеги, как процессору самостоятельно узнать количество строк сохраненных в одном "массиве PROGMEM ?
     
    Последнее редактирование: 27 мар 2025
  11. AlexU

    AlexU Гуру

    Вам же уже отвечали в другой теме про так, как вычислять количество элементов в массиве -- размер массив в байтах разделить на размер элемента в байтах:
    Код (C++):
    sizeof(ReklMess) / sizeof(char *)
    Или я не понял сути вопроса?
     
  12. Ariadna-on-Line

    Ariadna-on-Line Гуру

    Не. Все правильно. Спасибо. Все получилось лучше чем ожидал.
     

    Вложения:

    • OK.png
      OK.png
      Размер файла:
      48,4 КБ
      Просмотров:
      24
  13. AlexU

    AlexU Гуру

    А переменная 'tape' случайно не экземпляр класса String?
    Просто ардуиновский класс String может напрямую работать с флэш памятью и, создаваемый Вами буфер, только зря расходует оперативную память. Можно обойтись и без него.
    И второе, если переменная 'tape' действительно класса String, то в этот код:
    Код (C++):
    tape = "";
    -- не очень "хороший"
    Дело в том, что класс String использует динамическое выделение памяти (malloc/free -- если Вам это о чём-то говорит). И при не острожном использовании этого класса можно столкнуться с дефрагментацией кучи в оперативной памяти. Опять же, если понимаете суть термина -- "куча".
     
  14. Ariadna-on-Line

    Ariadna-on-Line Гуру

    Да. Вы правы. После ресета все прекрасно работает, но после 3-5 десятков "оборотов" - бегущая строка " начинает начинаться !!! " не с начала, а со случайного места. И еще после десятка оборотов - все гаснет.
    Пока не понял систему - грешил на контакты на макетке. Ан нет.
    Вопрос. Что может "забивать" память ? Если вы про String tape = "";
    Это единственная глобальная переменная - которая есть вход для функции вывода на матрицы изображения. От нее избавиться нельзя никак.
     
    Последнее редактирование: 28 мар 2025
  15. parovoZZ

    parovoZZ Гуру

    Честно - так и не понял причины, по которой нельзя вытаскивать символы сразу на экран.
    Но даже если без буфера никак, то почему бы его не сделать в виде понятного массива чаров конечной длины (размер буфера известен - количество символов, которые отображаются на экране). Тащить больше символов в ОЗУ никак не нужно - микроконтроллер прекрасно умеет читать прямо из флеша, что является единственным отличием его от микропроцессора. Последний работает только с ОЗУ.
     
  16. Ariadna-on-Line

    Ariadna-on-Line Гуру

    1. Символы кириллицы на экран вытаскиваются кракозябрами. Требуется прогонять через декодер. А он принимает только стринги. И прога вывода - тоже требует стринги в виде глобальной переменной. Используется свойство класса String превращать в String любые типы данных. Выше на картинке всё нарисовано.
    Если вы знаете другие пути - могу выложить скетч. Буду рад поучиться у профессионалов.
    2. В том и фишка. Не надо знать длины и количество строк. Минимум мысле-движений. Тупо вбили тексты и забыли. Код должен сам всё посчитать и исполнить.

    Коротко говоря - оказался сам балда. Нашел в сети функцию проверки памяти. Она нашла утечку. А остальное оказалось дело техники. Нашел случайно сдублировавшуюся строку. Удалил и всё заработало.
     
    Последнее редактирование: 29 мар 2025