From 9abb1b18c1f0cbb58c229a6691ce5b912a1e066c Mon Sep 17 00:00:00 2001 From: LeisureLadi <33247104+LeisureLadi@users.noreply.github.com> Date: Tue, 3 Dec 2019 09:53:37 +0100 Subject: [PATCH 1/2] Update PROGMEM.rst Include array of strings in the description, since the examples in Arduino do not consider the right pointer size --- doc/PROGMEM.rst | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/doc/PROGMEM.rst b/doc/PROGMEM.rst index eb44028069..cf93f5c456 100644 --- a/doc/PROGMEM.rst +++ b/doc/PROGMEM.rst @@ -237,6 +237,19 @@ the value back. } } +How do I declare Arrays of strings in PROGMEM and retrieve an element from it. +------------------------------------------------------------------------------ + +It is often convenient when working with large amounts of text, such as a project with an LCD display, to setup an array of strings. Because strings themselves are arrays, this is actually an example of a two-dimensional array. + +These tend to be large structures so putting them into program memory is often desirable. The code below illustrates the idea. + +.. code:: cpp + +/* +PROGMEM string demo How to store a table of strings in program memory (flash), and retrieve them. Information summarized from: http://www.nongnu.org/avr-libc/user-manual/pgmspace.html Setting up a table (array) of strings in program memory is slightly complicated, but here is a good template to follow. Setting up the strings is a two-step process. First define the strings. */ static const char string_0[] PROGMEM = "String 0"; // "String 0" etc are strings to store - change to suit. static const char string_1[] PROGMEM = "String 1"; static const char string_2[] PROGMEM = "String 2"; static const char string_3[] PROGMEM = "String 3"; static const char string_4[] PROGMEM = "String 4"; static const char string_5[] PROGMEM = "String 5"; // Then set up a table to refer to your strings. const char *const string_table[] PROGMEM = {string_0, string_1, string_2, string_3, string_4, string_5}; char buffer[30]; // make sure this is large enough for the largest string it must hold void setup() { Serial.begin(9600); // wait for serial port to connect. Needed for native USB Serial.println("OK"); } void loop() { /* Using the string table in program memory requires the use of special functions to retrieve the data. The strcpy_P function copies a string from program space to a string in RAM ("buffer"). Make sure your receiving string in RAM is large enough to hold whatever you are retrieving from program space. */ for (int i = 0; i < 6; i++) { strcpy_P(buffer, (char *)pgm_read_dword(&(string_table[i]))); // Necessary casts and dereferencing, just copy. Serial.println(buffer); delay(500); } } + + In summary ---------- From 111d5882e6b0c5050b17e656b5fbdd91f61d3d97 Mon Sep 17 00:00:00 2001 From: LeisureLadi <33247104+LeisureLadi@users.noreply.github.com> Date: Tue, 3 Dec 2019 18:53:56 +0100 Subject: [PATCH 2/2] Update PROGMEM.rst --- doc/PROGMEM.rst | 27 +++++++++++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) diff --git a/doc/PROGMEM.rst b/doc/PROGMEM.rst index cf93f5c456..2b8138f6a8 100644 --- a/doc/PROGMEM.rst +++ b/doc/PROGMEM.rst @@ -246,8 +246,31 @@ These tend to be large structures so putting them into program memory is often d .. code:: cpp -/* -PROGMEM string demo How to store a table of strings in program memory (flash), and retrieve them. Information summarized from: http://www.nongnu.org/avr-libc/user-manual/pgmspace.html Setting up a table (array) of strings in program memory is slightly complicated, but here is a good template to follow. Setting up the strings is a two-step process. First define the strings. */ static const char string_0[] PROGMEM = "String 0"; // "String 0" etc are strings to store - change to suit. static const char string_1[] PROGMEM = "String 1"; static const char string_2[] PROGMEM = "String 2"; static const char string_3[] PROGMEM = "String 3"; static const char string_4[] PROGMEM = "String 4"; static const char string_5[] PROGMEM = "String 5"; // Then set up a table to refer to your strings. const char *const string_table[] PROGMEM = {string_0, string_1, string_2, string_3, string_4, string_5}; char buffer[30]; // make sure this is large enough for the largest string it must hold void setup() { Serial.begin(9600); // wait for serial port to connect. Needed for native USB Serial.println("OK"); } void loop() { /* Using the string table in program memory requires the use of special functions to retrieve the data. The strcpy_P function copies a string from program space to a string in RAM ("buffer"). Make sure your receiving string in RAM is large enough to hold whatever you are retrieving from program space. */ for (int i = 0; i < 6; i++) { strcpy_P(buffer, (char *)pgm_read_dword(&(string_table[i]))); // Necessary casts and dereferencing, just copy. Serial.println(buffer); delay(500); } } + // Define Strings + const char string_0[] PROGMEM = "String 0"; + const char string_1[] PROGMEM = "String 1"; + const char string_2[] PROGMEM = "String 2"; + const char string_3[] PROGMEM = "String 3"; + const char string_4[] PROGMEM = "String 4"; + const char string_5[] PROGMEM = "String 5"; + + // Initialize Table of Strings + const char* const string_table[] PROGMEM = { string_0, string_1, string_2, string_3, string_4, string_5 }; + + char buffer[30]; // buffer for reading the string to (needs to be large enough to take the longest string + + void setup() { + Serial.begin(9600); + Serial.println("OK"); + } + + void loop() { + for (int i = 0; i < 6; i++) { + strcpy_P(buffer, (char*)pgm_read_dword(&(string_table[i]))); + Serial.println(buffer); + delay(500); + } + } In summary