Не мог пройти мимо, даже нану новую вытащил из упаковки. Конечно, сообщество меня изругает...
#include <avr/pgmspace.h>
struct listUsr_t
{
const char phoneNum[13];
const char phonePass[5];
const char phonePDU[13];
};
const listUsr_t PROGMEM users[] =
{
{ "70000000000", "00000", "000000000000"},
{ "70000000001", "00001", "000000000000"},
{ "70000000002", "00002", "000000000000"},
};
void setup() {
char incomingNumber[20];
Serial.begin(115200);
Serial.println("Begin!");
for (int i = 0; i < 3; i++) {
strncpy_P(incomingNumber, (char*) users[i].phoneNum, sizeof(listUsr_t::phoneNum));
Serial.println(incomingNumber);
}
}
void loop() {
// put your main code here, to run repeatedly:
}
И еще я не совсем уверен, что sizeof можно напускать на такого жука... Ну, если что - поправят.
Почему-то в данном примере помещение строковых констант прямо в массив эквивалентно помещению в массив ссылок на строковые константы (как на arduino.cc), но попытка перетащить данный пример в реальный скетч почему-то дает разные результаты по компиляции. Надо будет этот вопрос изучить. Может компилятор умничает опять.
char val[] = "" - это чего, зарезервировали нуль байт памяти, а потом туда строку копируете? Вы там надеюсь, игрушку-пердушку собираете, а не управление газовым котлом...
СПАСИБО! Если сможете, объясните про (char*) перед указателем на строку в массиве...
Не мог пройти мимо, даже нану новую вытащил из упаковки. Конечно, сообщество меня изругает...
#include <avr/pgmspace.h>
for (int i = 0; i < 3; i++) {
strncpy_P(incomingNumber, (char*) users[i].phoneNum, sizeof(listUsr_t::phoneNum));
Serial.println(incomingNumber);
}
}
void loop() {
}
интересно, зачем второй параметр strncpy_P() приводить к типу char* - это ж специальная функция для строк во флеше, она и без этого адрес строки должна понимать... точно там нужно приведение?
Нет, можно без приведения, но я же тоже знатный копипастер )) Бахнул с готового кода, не отчистил. Внутренний рецензент тоже не зацепился - хуже-то не будет, говорит.
А теперь уже все, процитировано, не исправишь. Простите, люди добрые.
интересно, зачем второй параметр strncpy_P() приводить к типу char* - это ж специальная функция для строк во флеше, она и без этого адрес строки должна понимать... точно там нужно приведение?
for (int i = 0; i < 6; i++)
{
strcpy_P(buffer, (char*)pgm_read_word(&(string_table[i]))); // Necessary casts and dereferencing, just copy.
Serial.println(buffer);
delay( 500 );
}
Решил таки разобраться с тем, почему в реальном скетче я начал проигрывать в ресурсе. Заодно освежить знания по progmem и проиллюстрировать разные способы.
Забегая вперед скажу, что ТС избрал (осмысленно или нет - не знаю) как самый экономный по ресурсу для его задачи вариант, так и более красивый.
№1 (классический)
Ключевая особенность: в PGM структуре хранятся ссылки на PGM строки, т.е. в RAM ничего не подгружается
Плюсы: строки одного поля структуры могут быть разной длины, и это не дает оверхеда, каков мог быть в №3. Так же можно одну строку (указатель на нее) использовать в разных полях структуры и повторять в одних и тех же совершенно безнаказанно (без какого-либо пенальти).
Минусы: много писанины.
Sketch uses 1,138 bytes (3%) of program storage space. Maximum is 32,256 bytes.
Global variables use 21 bytes (1%) of dynamic memory, leaving 2,027 bytes for local variables. Maximum is 2,048 bytes.
Ключевая особенность: в PGM структуре хранятся ссылки на строки, которые хранятся в RAM, ибо "Unfortunately, with GCC attributes, they affect only the declaration that they are attached to. So in this case, we successfully put the string_table variable, the array itself, in the Program Space. This DOES NOT put the actual strings themselves into Program Space. "
Плюсы: "красота" кода.
Минусы: бессмысленный оверхед по RAM, ожидаемый эффект практически не достигается
Sketch uses 1,088 bytes (3%) of program storage space. Maximum is 32,256 bytes.
Global variables use 65 bytes (3%) of dynamic memory, leaving 1,983 bytes for local variables. Maximum is 2,048 bytes.
Ключевая особенность: в PGM структуре строки хранятся сразу как массивы символов (последовательности байт), а не через указатели на таковые массивы, поэтому нет необходимости в предварительном объявлении строк, как PGM-ресурса. Доступ к первой ячейке какой-либо строки осуществляется по простому смещению от начального адреса массива структур.
Плюсы: красота кода.
Минусы: строки с разной длиной принесут оверхед по progmem space, так как компилятор будет резервировать блоки объявленной размерности в любом случае.
Sketch uses 1,114 bytes (3%) of program storage space. Maximum is 32,256 bytes.
Global variables use 21 bytes (1%) of dynamic memory, leaving 2,027 bytes for local variables. Maximum is 2,048 bytes.
P.S. В фрагментах кода закомментированы работающие методы получения правильного указателя на строку для каждого случая, так как сначала я оставил во всех трех один и те же, чтобы исследовать изменения только в объемах хранимых данных. Естественно, что для двух из трех этот метод не работал. Исправляюсь.
если не знаешь язык - то и картинки скидывать незачем.
Я хочу сразу предупредить - приходите с конкретными вопросами по УЖЕ НАПИСАННОМУ ВАМИ коду. Вопросы "не получается, покажите как" - здесь не прокатывают.
И еще - примеров, как эффекты для светодиодов во флеш положить - в гугле сотни.
В фрагментах кода закомментированы работающие методы получения правильного указателя на строку для каждого случая, так как сначала я оставил во всех трех один и те же, чтобы исследовать изменения только в объемах хранимых данных. Естественно, что для двух из трех этот метод не работал. Исправляюсь.
так можно было вообще все удалить, оставив только инициализацию массива в setup() и пустой loopn() :o)
pure cpp-code / avr_gcc-5.4.0 (только описание данных, без печати, пустой main() ... )
Конечно, сообщество меня изругает...
да ладно - хочется быть добрым - будь!
Только сам потом не пожалей.
char val[] = "" - не правильно скопировал....
Объясните, пожалуйста, ещё раз, зачем в указателе на строку стоит (char*), зачем????
Да че-то по привычке тип привел. Без него тоже работает.
Не мог пройти мимо, даже нану новую вытащил из упаковки. Конечно, сообщество меня изругает...
И еще я не совсем уверен, что sizeof можно напускать на такого жука... Ну, если что - поправят.
Почему-то в данном примере помещение строковых констант прямо в массив эквивалентно помещению в массив ссылок на строковые константы (как на arduino.cc), но попытка перетащить данный пример в реальный скетч почему-то дает разные результаты по компиляции. Надо будет этот вопрос изучить. Может компилятор умничает опять.
char val[] = "" - это чего, зарезервировали нуль байт памяти, а потом туда строку копируете? Вы там надеюсь, игрушку-пердушку собираете, а не управление газовым котлом...
СПАСИБО! Если сможете, объясните про (char*) перед указателем на строку в массиве...
да ладно - хочется быть добрым - будь!
Только сам потом не пожалей.
Выглядит угрожающе ))
Не мог пройти мимо, даже нану новую вытащил из упаковки. Конечно, сообщество меня изругает...
интересно, зачем второй параметр strncpy_P() приводить к типу char* - это ж специальная функция для строк во флеше, она и без этого адрес строки должна понимать... точно там нужно приведение?
Нет, можно без приведения, но я же тоже знатный копипастер )) Бахнул с готового кода, не отчистил. Внутренний рецензент тоже не зацепился - хуже-то не будет, говорит.
А теперь уже все, процитировано, не исправишь. Простите, люди добрые.
интересно, зачем второй параметр strncpy_P() приводить к типу char* - это ж специальная функция для строк во флеше, она и без этого адрес строки должна понимать... точно там нужно приведение?
Кстати, https://www.nongnu.org/avr-libc/user-manual/pgmspace.html
Наверное из такого источника я, ранее, в свой код и притащил приведение типа.
https://www.arduino.cc/reference/en/language/variables/utilities/progmem/
№3 (изначальный)
P.S. В фрагментах кода закомментированы работающие методы получения правильного указателя на строку для каждого случая, так как сначала я оставил во всех трех один и те же, чтобы исследовать изменения только в объемах хранимых данных. Естественно, что для двух из трех этот метод не работал. Исправляюсь.
sadman41, отличное исследование!
А фраза про "Unfortunately... " - это откуда цитата?
Когда читаешь - вроде очевидно, но самому в голову не пришло.
sadman41, отличное исследование!
А фраза про "Unfortunately... " - это откуда цитата?
Когда читаешь - вроде очевидно, но самому в голову не пришло.
Отседова: https://www.nongnu.org/avr-libc/user-manual/pgmspace.html
Почитал, очень даже доступно и качественно написано, и, исследовано.
Спасибо, еще раз!!!
Привет, не поможешь разобраться?
Привет, не поможешь разобраться?
разобраться в чём???
Нужно вывести битмап на матрицу 100х40 не получается засунуть фреймы в массив, чтобы перебирать его попорядку
Массив в какую память писать?
Я его progmem во флешь пишу, у меня проблема с выводом на ws2812 не знаю толком язык и совсем запутался
Как сюда картинки скидывать?
Как сюда картинки скидывать?
если не знаешь язык - то и картинки скидывать незачем.
Я хочу сразу предупредить - приходите с конкретными вопросами по УЖЕ НАПИСАННОМУ ВАМИ коду. Вопросы "не получается, покажите как" - здесь не прокатывают.
И еще - примеров, как эффекты для светодиодов во флеш положить - в гугле сотни.
Я написал, есть битмап массив, примерно 30 блоков, как их вывести на ws2812, я их вывожу но хотелось бы более изящное решение
Я написал, есть битмап массив, примерно 30 блоков, как их вывести на ws2812, я их вывожу но хотелось бы более изящное решение
не вижу. где вы написали
А вообще - в разделе "Песочница" прочтите приклееную тему - многие вопросы отпадут
В фрагментах кода закомментированы работающие методы получения правильного указателя на строку для каждого случая, так как сначала я оставил во всех трех один и те же, чтобы исследовать изменения только в объемах хранимых данных. Естественно, что для двух из трех этот метод не работал. Исправляюсь.
так можно было вообще все удалить, оставив только инициализацию массива в setup() и пустой loopn() :o)
pure cpp-code / avr_gcc-5.4.0 (только описание данных, без печати, пустой main() ... )
в принципе, те-же результаты
у меня были сомнение на счет 3го метода, т.к. за счет "фрагментарности" д.б. занимать больше места... но оптимизация взяла свое :о) ...