Набор удобных инструментов для работы с PROGMEM, C++ обёртка на стандартные pgm-функции
- Одна функция для чтения любых данных
- Чтение многомерных массивов
- Чтение массива строк
Совместима со всеми Arduino платформами (используются Arduino-функции)
// синоним const __FlashStringHelper*
FSTR
// преобразовать PGM_P в FSTR
FPSTR(x)
// поместить одиночное значение val типа T в PROGMEM под именем name
PGM_VAL(T, name, val)
// поместить одиночное значение val типа T (класс, структура) в PROGMEM под именем name, передать список для инициализации
PGM_STRUCT(T, name, ...)
// поместить строку str в PROGMEM под именем name
PGM_STR(name, str)
// поместить строки в PROGMEM и в список указателей под именем name
PGM_STR_LIST(name, ...)
PGM_STR_LIST_STATIC(name, ...)
// поместить строки в PROGMEM и в список указателей + создать объект StringList с именем name
// создаст progmem массив name_list и строки name_list_0, ... name_list_n
PGM_STR_LIST_OBJ(name, ...)
PGM_STR_LIST_OBJ_STATIC(name, ...)
// создать объект pgm::StringList с посчитанным количеством строк
MAKE_STR_LIST(name)
// поместить массив типа T в PROGMEM под именем name
PGM_ARRAY(T, name, ...)
// поместить массивы типа T в PROGMEM массив указателей под именем name
PGM_ARRAY_LIST(T, name, ...)
// создать объект pgm::Array типа T с посчитанной длиной массива
MAKE_ARRAY(T, name)
// создать PROGMEM массив типа T и объект name класса pgm::Array из него
// создаст progmem массив name_arr
PGM_ARRAY_OBJ(T, name, ...)
// прочитать данные любого типа
T pgm_read(const T* ptr);
Чтение одномерного массива
Array(const T* arr, size_t len = 0);
// длина массива. 0 если не указана при инициализации
size_t length();
// получить значение по индексу
T operator[](int idx);
Чтение массива из массива указателей на массивы
ArrayList(const T** arr, size_t len = 0);
// длина массива. 0 если не указана при инициализации
size_t length();
// прочитать массив как pgm::Array по индексу
Array<T> operator[](int idx);
Работа с PROGEMEM строкой
PString(PGM_P str, size_t len = 0);
// напечатать
size_t printTo(Print& p);
// длина строки
size_t length();
// вывести в char[]
void toStr(char* buf);
// вывести в String
String toString();
// сравнить со строкой
bool compare(const char* str);
bool operator==(const char* str);
// сравнить со строкой
bool compare(const String& str);
bool operator==(const String& str);
// получить как FlashStringHelper*
FSTR f_str();
// получить символ
char operator[](int idx);
operator PGM_P();
operator FSTR();
PGM_P pstr;
Работа с массивом строк из массива указателей
StringList(const char** arr, size_t len = 0);
// длина массива. 0 если не указана при инициализации
size_t length();
// получить строку
PString operator[](int idx);
PGM_STR_LIST(name, "str1", "str2", "str3")
разворачивается в:
const char name_0[] PROGMEM = "str1";
const char name_1[] PROGMEM = "str2";
const char name_2[] PROGMEM = "str3";
const char* const name[] = {name_0, name_1, name_2};
Максимальное количество строк -
512
PGM_VAL(int, vali, 123);
PGM_VAL(float, valf, 3.14);
struct Test {
byte i;
char str[10];
};
PGM_STRUCT(Test, ptest, 10, "test");
void foo() {
Serial.println(pgm_read(&vali)); // 123
Serial.println(pgm_read(&valf)); // 3.14
Test t = pgm_read(&ptest);
Serial.println(t.i); // 10
Serial.println(t.str); // test
}
PGM_STR(pgmstr, "hello");
void foo() {
pgm::PString pstr(pgmstr);
Serial.println(pstr); // hello
Serial.println(pstr.length()); // 5
for (int i = 0; i < pstr.length(); i++) {
Serial.print(pstr[i]);
}
Serial.println();
// при работе со String используй f_str()!
// это оптимальнее всего
String s = pgmstr.f_str();
s += pgmstr.f_str();
}
PGM_ARRAY(byte, pgmarrb, 1, 2, 3); // pgm массив
PGM_ARRAY(int, pgmarri, 123, 456, 789); // pgm массив
PGM_ARRAY_OBJ(float, arrf, 1.12, 2.34, 3.45); // массив + объект pgm::Array
void foo() {
// длина неизвестна
pgm::Array<byte> arrb(pgmarrb);
Serial.println(arrb[1]); // 2
// длина посчитается в MAKE
pgm::Array<int> arri = MAKE_ARRAY(int, pgmarri);
Serial.println(arri[1]); // 456
Serial.println(arri.length()); // 3
// готовый объект
Serial.println(arrf[1]); // 2.34
}
PGM_STR_LIST(pstrlist, "string 1", "kek", "hello");
PGM_STR_LIST_OBJ(pstrlist_obj, "str1", "str2", "str3");
void foo() {
pgm::StringList list(pstrlist);
// pgm::StringList list = MAKE_STR_LIST(pstrlist); // тут длина известна
Serial.println(list.length());
Serial.println(list[1]);
Serial.println(list[1].length());
Serial.println(list[0] == "string 1");
// str1, str2, str3
for (int i = 0; i < pstrlist_obj.length(); i++) {
Serial.println(pstrlist_obj[i]);
}
}
- v1.0
- Библиотеку можно найти по названию pgm_utils и установить через менеджер библиотек в:
- Arduino IDE
- Arduino IDE v2
- PlatformIO
- Скачать библиотеку .zip архивом для ручной установки:
- Распаковать и положить в C:\Program Files (x86)\Arduino\libraries (Windows x64)
- Распаковать и положить в C:\Program Files\Arduino\libraries (Windows x32)
- Распаковать и положить в Документы/Arduino/libraries/
- (Arduino IDE) автоматическая установка из .zip: Скетч/Подключить библиотеку/Добавить .ZIP библиотеку… и указать скачанный архив
- Читай более подробную инструкцию по установке библиотек здесь
- Рекомендую всегда обновлять библиотеку: в новых версиях исправляются ошибки и баги, а также проводится оптимизация и добавляются новые фичи
- Через менеджер библиотек IDE: найти библиотеку как при установке и нажать "Обновить"
- Вручную: удалить папку со старой версией, а затем положить на её место новую. "Замену" делать нельзя: иногда в новых версиях удаляются файлы, которые останутся при замене и могут привести к ошибкам!
При нахождении багов создавайте Issue, а лучше сразу пишите на почту [email protected]
Библиотека открыта для доработки и ваших Pull Request'ов!
При сообщении о багах или некорректной работе библиотеки нужно обязательно указывать:
- Версия библиотеки
- Какой используется МК
- Версия SDK (для ESP)
- Версия Arduino IDE
- Корректно ли работают ли встроенные примеры, в которых используются функции и конструкции, приводящие к багу в вашем коде
- Какой код загружался, какая работа от него ожидалась и как он работает в реальности
- В идеале приложить минимальный код, в котором наблюдается баг. Не полотно из тысячи строк, а минимальный код