From 206dc82f252fd8b7fc71c36bc67b8ef4d7d5ecd7 Mon Sep 17 00:00:00 2001 From: Your Name Date: Fri, 20 Feb 2015 15:07:19 +0100 Subject: [PATCH] Changed PROGMEM according to the new documentation online --- Language/Variables/Utilities/PROGMEM.adoc | 83 +++++++++++++---------- 1 file changed, 47 insertions(+), 36 deletions(-) diff --git a/Language/Variables/Utilities/PROGMEM.adoc b/Language/Variables/Utilities/PROGMEM.adoc index 047c5fa97..e82a9c811 100644 --- a/Language/Variables/Utilities/PROGMEM.adoc +++ b/Language/Variables/Utilities/PROGMEM.adoc @@ -24,29 +24,22 @@ The `PROGMEM` keyword is a variable modifier, it should be used only with the da [float] === Syntax -`dataType variableName[] PROGMEM = {dataInt0, dataInt1, dataInt3...};` +const dataType variableName[] PROGMEM = {data0, data1, data3...};` -`program memory dataType` - any program memory variable type (see below) +`dataType` - any variable type `variableName` - the name for your array of data -Note that because PROGMEM is a variable modifier, there is no hard and fast rule about where it should go, so the Arduino compiler accepts all of the definitions below, which are also synonymous. However experiments have indicated that, in various versions of Arduino (having to do with GCC version), PROGMEM may work in one location and not in another. The "string table" example below has been tested to work with Arduino 13. Earlier versions of the IDE may work better if PROGMEM is included after the variable name. +Note that because PROGMEM is a variable modifier, there is no hard and fast rule about where it should go, so the Arduino compiler accepts all of the definitions below, which are also synonymous. However experiments have indicated that, in various versions of Arduino (having to do with GCC version), PROGMEM may work in one location and not in another. The "string table" example below has been tested to work with Arduino 13. Earlier versions of the IDE may work better if PROGMEM is included after the variable name. + +`const dataType variableName[] PROGMEM = {}; // use this form` + +`const PROGMEM dataType variableName[] = {}; // or this one`+ +`const dataType PROGMEM variableName[] = {}; // not this one -`dataType variableName[] PROGMEM = {}; // use this form` + -`dataType PROGMEM variableName[] = {}; // not this one` + -`PROGMEM dataType variableName[] = {}; // use this form` 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 http://www.nongnu.org/avr-libc/user-manual/group__avr__pgmspace.html[pgmspace.h] library, to read the data from program memory back into SRAM, so we can do something useful with it. -As mentioned above, it is important to use the datatypes outlined in http://www.nongnu.org/avr-libc/user-manual/group__avr__pgmspace.html[pgmspace.h]. Some cryptic bugs are generated by using ordinary datatypes for program memory calls. Below is a list of variable types to use. Floating point numbers in program memory do not appear to be supported. - - `prog_char` - a signed char (1 byte) -127 to 128 + - `prog_uchar` - an unsigned char (1 byte) 0 to 255 + - `prog_int16_t` - a signed int (2 bytes) -32,767 to 32,768 + - `prog_uint16_t` - an unsigned int (2 bytes) 0 to 65,535 + - `prog_int32_t` - a signed long (4 bytes) -2,147,483,648 to * 2,147,483,647. + - `prog_uint32_t` - an unsigned long (4 bytes) 0 to 4,294,967,295 [%hardbreaks] -- // OVERVIEW SECTION ENDS @@ -69,20 +62,43 @@ The following code fragments illustrate how to read and write unsigned chars (by // save some unsigned ints -PROGMEM prog_uint16_t charSet[] = { 65000, 32796, 16843, 10, 11234}; +const PROGMEM uint16_t charSet[] = { 65000, 32796, 16843, 10, 11234}; // save some chars -prog_uchar signMessage[] PROGMEM = {"I AM PREDATOR, UNSEEN COMBATANT. CREATED BY THE UNITED STATES DEPART"}; +const char signMessage[] PROGMEM = {"I AM PREDATOR, UNSEEN COMBATANT. CREATED BY THE UNITED STATES DEPART"}; unsigned int displayInt; int k; // counter variable char myChar; -// read back a 2-byte int - displayInt = pgm_read_word_near(charSet + k) -// read back a char -myChar = pgm_read_byte_near(signMessage + k); +void setup() { + Serial.begin(9600); + while (!Serial); + + // put your setup code here, to run once: + // read back a 2-byte int + for (k = 0; k < 5; k++) + { + displayInt = pgm_read_word_near(charSet + k); + Serial.println(displayInt); + } + Serial.println(); + + // read back a char + for (k = 0; k < strlen(signMessage); k++) + { + myChar = pgm_read_byte_near(signMessage + k); + Serial.print(myChar); + } + + Serial.println(); +} + +void loop() { + // put your main code here, to run repeatedly: + +} ---- *Arrays of strings* @@ -105,34 +121,28 @@ These tend to be large structures so putting them into program memory is often d here is a good template to follow. Setting up the strings is a two-step process. First define the strings. - */ #include -prog_char string_0[] PROGMEM = "String 0"; // "String 0" etc are strings to store - change to suit. -prog_char string_1[] PROGMEM = "String 1"; -prog_char string_2[] PROGMEM = "String 2"; -prog_char string_3[] PROGMEM = "String 3"; -prog_char string_4[] PROGMEM = "String 4"; -prog_char string_5[] PROGMEM = "String 5"; +const char string_0[] PROGMEM = "String 0"; // "String 0" etc are strings to store - change to suit. +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"; // Then set up a table to refer to your strings. -PROGMEM const char *string_table[] = // change "string_table" name to suit -{ - string_0, - string_1, - string_2, - string_3, - string_4, - string_5 }; +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); + while(!Serial); + Serial.println("OK"); } @@ -147,10 +157,11 @@ void loop() 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 ); + Serial.println(buffer); delay( 500 ); } } + ---- [%hardbreaks]