ArduinoのSketch(スケッチ)で、データをFlashメモリ(プログラム領域)へ格納する方法を解説します。
変更の必要がない文字列等でデータ量が多い場合、それらを、Flashメモリへ格納する事で、SRAMの負担を減らす事が出来ます。
PROGMEM修飾子
PROGMEM修飾子を変数宣言時に使用する事で、Flashメモリにデータを格納できますが、pgmspace.hライブラリをインクルードする必要があります。また書式は次の2通りです。
#include
dataType varArray[] PROGMEM = {data0, data1...};
//or
PROGMEM dataType varArray[] = {data0, data1...};
// dataType: data type
// varArray: name of array
注意点としては、pgmspace.hで定義されているデータ型を使う必要がある事です。使用可能なデータ型は次の通りです。浮動小数点数はサポートされていません。
prog_char char (1 byte) -127~128
prog_uchar unsigned char (1 byte) 0~255
prog_int16_t int (2 bytes) -32,767~32,768
prog_uint16_t unsigned int (2 bytes) 0~65,535
prog_int32_t long (4 bytes) -2,147,483,648~2,147,483,647.
prog_uint32_t unsigned long (4 bytes) 0~4,294,967,295
なお、Flashメモリ上のデータは、pgmspace.hで定義されている専用関数で、RAMに読み込むことで、利用できるようになります。
使用例
次のコードは、char型(1バイト)とint型(2バイト)のデータを読み書きする例で、 Arduino公式リファレンスのサンプルとなります。
//Arduino Sketch Example: PROGMEM, Read and Write
//Original Source: Arduino Reference (http://arduino.cc/en/Reference/HomePage)
#include
// save some unsigned ints
PROGMEM prog_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"};
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);
Creative Commons Attribution-ShareAlike 3.0 License (CC BY-SA 3.0)
“Arduino Reference:PROGMEM” by Arduino Team is licensed under CC BY-SA 3.0
次のコードは、文字列の配列をFlashメモリに配置する例で、 Arduino公式リファレンスのサンプルとなります。
//Arduino Sketch Example: PROGMEM, Array of String
//Original Source: Arduino Reference (http://arduino.cc/en/Reference/HomePage)
/*
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.
*/
#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";
// 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 };
char buffer[30]; // make sure this is large enough for the largest string it must hold
void setup()
{
Serial.begin(9600);
}
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_word(&(string_table[i]))); // Necessary casts and dereferencing, just copy.
Serial.println( buffer );
delay( 500 );
}
}
Creative Commons Attribution-ShareAlike 3.0 License (CC BY-SA 3.0)
“Arduino Reference:PROGMEM” by Arduino Team is licensed under CC BY-SA 3.0
Sponsored Link