備忘録(メモ以上ノウハウ未満) 20130730

1. Arduinoについて
1.1 メモリ(SRAM)節約・配列の領域確保について
 
     Arduino搭載のマイコンのメモリ(SRAM、以下RAMで)は精々数キロバイト(一番人気のUNOで2K、大きなMEGAでも8KB)程度しかないのでちょっと大きな配列などを使おうとすると容量が足りなくなります。それどころか、変数の領域確保が下手なのか、メモリは余っているのに別の配列と領域が重複するようなバグがあるような気がします(追々検証しようと思います、ちなみに私の環境では、300Byte程のchar型配列を作成した時不具合がでました)。
 まあともかく、メモリが貴重なのは変わりませんし、メモリ絡みの無駄なトラブルを避けるために有用そうな情報をまとめておきたいと思います。
 
1.1.1 定数をSRAMからflashROM(フラッシュメモリ、以下ROMで)に待避する
 
 constつけたらROM上に確保してくれるんじゃないの?と思うのが人情ってもんですが(そうですか?)、実際は「PROGMEM」という修飾子をつけて変数を宣言します。本家のページを見ると「RROGMEM:Store in flash (program) memory instead of SRAM 」と書いてあるのでPROGramMEMoryの略のようですね。
 
 使い方ですが、大きく分けて3つの手順を踏む必要があるようです。
 
 1. #include<avr.pgmspace.h> をインクルード
   これは流石に説明不要ですかね?スケッチの一番上に追加します。
 
 2. ROM上にデータを書き込む
   修飾子PROGMEMと一緒に、pgmspace.hで定義されているデータ型で宣言します。
   配列宣言しているのは、データを並べてその先頭のアドレスを使ってアクセスするためです。
 
   RROGMEM データ型  配列名[] = {要素1 , 要素2 , ... }
 
   データ型には、次の物があります。
    prog_char    char               1Byte    (-127~128)
    prog_uchar  unsigned char 1Byte   (0~255)
    prog_int16_t  int                  2Byte (-32767~32768)
    prog_uint16_t  unsigned int  2Byte (0~65535)
    prog_int32_t  long                4Byte (-2147483648~2147483647).
    prog_uint32_t  unsigned long 4Byte (0~4294967295)
 
 3. PRAGMEM用の関数を使ってデータにアクセスする
         pgm_read_byte_near( 参照するアドレス );  //1Byte 読み込み
    pgm_read_word_near( 参照するアドレス );  //2Byte 読み込み
    pgm_read_dword_near( 参照するアドレス ); //4Byte 読み込み
 
公式のサンプルソースもご覧下さいーm(_ _)m
 
 
 1.1.2 Serial.print("文字列") で、文字列がSRAMに格納されるのを抑制する
 
 こちらもなんで?って感じなんですがSRAMを消費しちゃいます。ちょっと古めの情報だと、1.1.1と同じようにフラッシュROM上に配置&出力用に関数をつくって...ってパターンが多かったのですが、なんと!
 
 Serial.print(F("Hello ! Arduino !!"));
 
でOKだそうです。こちら様の情報ですーm(_ _)m