NOBのArduino日記!

NOBのArduino日記!

趣味は車・バイク・自転車・ラジコン・電子工作です。

Arduino IDE(PROGMEM修飾子とFマクロの使い方)

■PROGMEM修飾子
 PROGMEM修飾子はFlashメモリ(プログラム領域)にデータを格納するための修飾子です。
 Arduino UnoのSRAM は小さいため、大きなデータはPROGMEM修飾子を使って Flashメモリから読み込みます。
 PROGMEM修飾子を単独の変数に対して使うこともできますが、大きなデータを扱うならば配列にするのが一番簡単です。

■使用例
 Arduino IDEで使用するPROGMEM修飾子の使用例は以下の通りです。
 
例1)PROGMEMにchar(byte)とint(2byte)を読み書きする方法
 Flashメモリに書き込んだデータは、pgmspace.hで定義されている専用のメソッド(関数)を使ってRAMに読み込むことで、利用できるようになります。

#include <avr/pgmspace.h>

// いくつかのunsigned intを保存する
const PROGMEM   uint16_t charSet[]   = { 65000, 32796, 16843, 10, 11234};
// いくつかの文字を保存する
const char signMessage[] PROGMEM   = {"I AM PREDATOR,   UNSEEN COMBATANT. CREATED BY THE UNITED STATES DEPART"};
unsigned int displayInt;
int k;       // カウンタ変数
char myChar;

void setup() {
   Serial.begin(9600);
   while (!Serial);
   // セットアップコードをここに入れて、一度実行してください
   // 2バイトのintを読み戻す
   for (k = 0; k < 5; k++) {
       displayInt = pgm_read_word_near(charSet + k);
       Serial.println(displayInt);
   }
   Serial.println();
   // 文字を読み返す
   int len = strlen_P(signMessage);
   for (k = 0; k < len; k++) {
       myChar =   pgm_read_byte_near(signMessage + k);
       Serial.print(myChar);
   }
   Serial.println();
}

void loop() {
   // メインコードをここに入れて、繰り返し実行
}

イメージ 1

図1:プログラム例1

例2)文字列の配列
 大量のテキスト(LCDディスプレイを備えたプロジェクトなど)で作業して文字列の配列を設定すると便利なことがよくあります。文字列自体は配列なので、実際には2次元配列の例です。
 これらは大きな構造である傾向があり、プログラムメモリに入れるのが望ましいことがよくあります。下記にPROGMEM修飾子によって文字列の配列をFlashメモリに配置する例を示します。

/*プログラムメモリ(フラッシュ)に文字列のテーブルを格納しそれらを取得する方法。
   プログラムメモリ内の文字列のテーブル(配列)の設定は少し複雑ですが、ここに従うための良いテンプレートです。文字列を設定するには、2つの手順があります。最初に文字列を定義します。*/

#include <avr/pgmspace.h>
const char string_0[] PROGMEM = "String 0";     // "文字列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";
// そしてあなたの文字列を参照するテーブルを設定します。
const char* const string_table[] PROGMEM = {string_0, string_1, string_2, string_3, string_4, string_5};
char buffer[30];       // これが保持する必要がある最大の文字列に十分な大きさであることを確認する

void setup() {
   Serial.begin(9600);
   while (!Serial);
   Serial.println("OK");
}


void loop() {
   for (int i = 0; i < 6; i++) {
       strcpy_P(buffer, (char*)pgm_read_word(&(string_table[i]))); // 必要なキャストと参照解除
       Serial.println(buffer);
       delay( 500 );
   }
}

イメージ 1

図1:プログラム例

■構文
 dataType variableName[] PROGMEM = {dataInt0, dataInt1...}; 

 PROGMEM修飾子は変数を宣言するときに使います。PROGMEMキーワードを置く位置は次のどちらかです。

const dataType variableName[] PROGMEM = {};
const PROGMEM dataType variableName[] = {};

 

■パラメータ
 dataType: データ型(表1参照)
 variableName: 配列の名前 

表1:pgmspace.hで使用可能なデータ型
項目 内容
prog_char char (1byte) -127~128
prog_uchar unsigned char (1byte) 0~255
prog_int16_t int (2byte) -32,767~32,768
prog_uint16_t unsigned int (2byte) 0~65,535
prog_int32_t long (4 bytes) -2,147,483,648~2,147,483,647
prog_uint32_t unsigned long (4byte)     0~4,294,967,295
浮動小数点数はサポートされていません。

■戻り値
 有りません

■補足
 PROGMEMはpgmspace.hライブラリの一部ですので、このキーワードを使うときはライブラリをインクルードする必要があります。 

#include <avr/pgmspace.h>

 

◆F()マクロ修飾子
 Frashメモリの文字列にアクセスするためのマクロです。
 PROGMEMよりも簡単に、長い文字列を扱うことができます。 
 
 Arduino IDEで使用するF()マクロ修飾子の使い方は以下の通りです。
 このプログラムを実行すると、Flashメモリから文字列を取得して出力します。

Serial.print( F("Hello World.") );

 

イメージ 1 イメージ 3
励みになりますのでよければクリック下さい(^o^)/

↩【ArduinoIDE reference】目次に戻る