String и PROGMEM не работают
- Войдите на сайт для отправки комментариев
Пт, 20/03/2015 - 23:05
Коллеги
я не могу никак поженить String и PROGMEM
код упростил как мог для вопроса, меньше не получилось :-). Вставляешь в описание переменной PROGMEM и перестает работать, убираешь - работает. Ерунда какая-то. Кто может подскажет что?
//PROGMEM const String str = "Qwerty"; void setup() { Serial.begin(9600); Serial.println(str); } void loop() { }
While PROGMEM could be used on a single variable, it is really only worth the fuss if you have a larger block of data that needs to be stored, which is usually easiest in an array, (or another C data structure beyond our present discussion).
Using PROGMEM is also a two-step procedure. After getting the data into Flash memory, it requires special methods (functions), also defined in the pgmspace.h library, to read the data from program memory back into SRAM, so we can do something useful with it.
Попробуй написать //PROGMEMIS
Какой особый смысл хранить константный объект во флеше?
Большое меню - константный объект
UNO кряхтит, жалуется
Попробуй написать //PROGMEMIS
А что это?
Я его не нашел в <avr/pgmspace.h>
И компилятор ругается
Большое меню - константный объект
UNO кряхтит, жалуется
Можно хотя бы маленький кусочек для примера? Не верю, что нужен именно String, именно объект. String можно заменить на const char или плоский массив const char, если там могут быть '\0'
Большое меню - константный объект
UNO кряхтит, жалуется
да можно и без String - просто с ними удобнее, можно и без PROGMEMа - мега съест.
Просто за державу обидно, да и на нано хотелось уместиться.
просто на первый взгляд должно работать?
На первый взгляд - не должно даже компилироваться. Во флеш строки можно, переменные можно, а с объектами в чистом виде - скорее всего нельзя без извратов.
Пример жалко? Ладно, не настаиваю, Ваше право.
На первый взгляд - не должно даже компилироваться. Во флеш строки можно, переменные можно, а с объектами в чистом виде - скорее всего нельзя без извратов.
Пример жалко? Ладно, не настаиваю, Ваше право.
Совсем не жалко, но пример чего? Пример того что не работает я приладил
а то что я пишу - пока кучка скетчей разных подсистем - показывать то нечего, просто на один из них ругнулась, что памяти маловато. Там конечно полно отладочных Print-ов, но это и не вся задумка - там управление мощностью, 3-х точечный термостат, управление потоком жидкости и большое меню, вот и решил сплавить во флэш. Ан нет, не лезет :-)
я правильно понимаю проблему: PROGMEM и String не уживутся?
Но вот почему это тогда вот это с PROGMEM не работает, а без - работает?:
какое-то ругательное это слово PROGMEM...... в eeprom уберу тогда хоть что-то, если поплохеет
Для начала разберите хотя бы один рабочий пример, как читать данные из флеша. Примеры в гугле есть, а потом поймёте, почему со String не получится.
Можете смеяться, но у меня оба примера работают, и с PROGMEM и без.
Во втором только надо добавить const в правильном месте:
Почему работает - так сразу не пойму.
По-моему, такое может быть, если разработчики специально предусмотрели версию Serial.println понимающую указатель на строку в PROGMEM. Выяснять и уточнять не полезу - лениво мне. :)
А насчёт первого примера - вряд ли там будет заметная экономия от использования PROGMEM. Объект String, скорее всего, состоит только из указателя на строку. Ну ещё, может быть, её длины.
Но при этом сама строка размещается всё равно в обычной памяти, выделенной функцией malloc.
-----
Upd: Вот, попробуйте если интересно.
Оказывается, размер объекта типа String всегда равен 6 байтам, независимо от длины самого текста.
(Кроме указателя и длины, там ещё какой-то array length. В чём разница не понял, но по смыслу, думаю, это размер зарезервированной памяти, который может быть больше длины строки).
Можете смеяться, но у меня оба примера работают, и с PROGMEM и без
-----
Спасибо,
а какая у Вас версия IDE?
Я поставил 1.5.8. Да еще на маке. Может просто мой глюк с IDE? Я согласен с тем, что выгоды может не быть, но откровенный мусор при использовании PROGMEMа выводить то не должно, явно при его использовании указатели начинают показывать на деревню дедушке
Ваш код попробую
У меня 1.5.7 на XP, правда сомневаюсь, что от этого зависит.
Не подскажу я в чём там дело, не знаю.
И вот что входит (v.1.6 ковырял). Как ни странно, но String таки умеет работать с PROGMEM. Для этого служит класс
Используемый в соответствующих методах и операторах, например метод
Обратите внимание на функцию strcpy_P, таких прелеснейших много, лежат в ..\hardware\tools\avr\avr\include\avr\pgmspace.h и ждут когда мы их заюзаем. На всяк случай скопипащу сюды, может кому пригодятся, мне например.
откомпилированный в новом IDE 1.6.1 скетч (оба, с учетом замечания про второй const) работают
похоже это косяк IDE:
в ARDUINO 1.6.0rc1 упоминается:
[libraries]
ARDUINO 1.6.0rc3 - 2015.02.03
Доброго времени суток уважаемые форумчане. Помогите плиз нубу. Пытаюсь научить "великому и могучему" LCD 16х2. Столкнулся с проблемой копирования строчек типа wchar_t из PROGMEM.
Библиотека русификации LiquidCrystal_1602_RUS выводит символы кириллицы (utf8) только когда они типа wchar_t .
вот так работает:
сейчас эта же конструкция работает как char, а вот аналога strcpy_P для wchar_t я не могу подобрать.
если сделать вот так :
то ругается на несоответствие типов для strcpy_P (cannot convert 'wchar_t*' to 'char*' for argument '1' to 'char* strcpy_P(char*, const char*)' )
то ругается на несоответствие типов для strcpy_P (cannot convert 'wchar_t*' to 'char*' for argument '1' to 'char* strcpy_P(char*, const char*)' )
А что мешает вычитать строку побайтово, юзая pgm_read_byte? У вас есть массив word (коим и является wchar_t на данной платформе), который расположен во флеше попа к писе, т.е. последовательно. Получаете указатель на его начало, и вычитываете побайтово. Навскидку, как вариант.