Spresense Header CodeSpresense Header Code

Spresense - エッジコンピューティングを低消費電力で

Spresense で乾電池でも動く本格的なエッジコンピューティングを体験してみませんか?

Spresense Arduino Library 開発ガイド

1. Spresense で Arduino スケッチを書いてみよう!

Spresense の Spresense Arduino Library をインストールすると、Arduino IDE のメニューの File → Examples → Spresense に、多くのサンプルスケッチがあります。Spresense Arduino Library のインストールについては、Spresense Arduino Library の使い方 を参照してください。

多くの Arduino スケッチをSpresenseで動かすことができますが、Arduino Uno と Spresense に、幾つかハードウェアの違いがあり、全てのスケッチをそのまま動かせるわけではありません。詳細については、Spresenseと Arduino Uno のハードウェの違いを参照してください。

1.1. Spresense Arduino Library でスケッチを書く際の注意事項について

Spresense は、Arduino互換APIをサポートしていますが、使用にあたり制限や違い、そして追加機能があります。この章ではそのような注意事項について記述しています。Arduino プログラミング言語仕様については、Arduino Language Reference を参照してください。

1.1.1. LED

Spresense メインボードには4つのビルトインLEDが搭載されています。これらはアプリケーションから自由に使うことができます。LEDのピン番号は LED0LED1LED2LED3 として定義されています。LED_BUILTIN の定義は、LED0 に割り当てられています。これらは通常のデジタル端子と同様に pinMode(LED番号, OUTPUT)digitalWrite(LED番号, HIGH/LOW) で操作できます。また、 ledOn(LED番号) もしくは ledOff(LED番号) という専用APIを使うこともできます。

1.1.2. EEPROM

Spresense は、EEPROM を内蔵していませんが、Flash メモリを使用して EEPROM をエミュレートしています。永続的なデータを扱いたい場合は、EEPROMライブラリ、もしくは Spresense拡張ボードのSDカードを使用することができます。

1.1.3. Serial

Spresense には二つのシリアルポート(UART)が備わっており、Serial 機能をサポートしています。メインボード上の USB ポートはデバッグシリアル専用で Serial と定義して使用できます。一方、DO0、DO1 端子のシリアルは、 Serial2 のインスタンス名で使用することができます。

1.1.4. pinMode()

pinMode(pin, mode)mode について、 INPUT, OUTPUT, INPUT_PULLUP の他に INPUT_PULLDOWN をサポートしています。I/O電圧に関して、メインボード側のデジタル端子は1.8Vですが、拡張ボードのデジタル端子は 3.3V もしくは 5V 出力(ジャンパJP1で選択)になるように設計されています。この電圧レベル変換は、レベルシフタとプルアップ抵抗で行っているため、拡張ボードのデジタル端子にはいくつかの制約があります。

  • 起動時は、拡張ボードの全てのデジタル端子がプルアップされ HIGH になります。pinMode()で、 INPUT_PULLDOWN を指定してもプルアップされるレベルの方が高いため、入力は HIGH になります。

  • ピンがインプットに設定されている場合、初期値は HIGH に設定されます。これはプルダウン抵抗を必要とする回路に影響を与えますので注意してください。

  • ピンの出力は、 digitalWrite() で設定されてはじめて、 HIGH もしくは、 LOW にセットされます。

レベルシフタやプルアップ抵抗の詳細については、Spresense拡張ボード回路図 を参照してください。

1.1.5. analogRead()

Spresense は A0 から A5 まで 6 つのアナログ入力専用ピンをもっています。これらのピンをデジタルピンとして使用することはできません。 analogRead() に指定するピンには、ピン番号の数字だけではなく A0A1A2A3A4A5 という定義を使用してください。

1.1.6. analogReference()

Spresense 拡張ボードのアナログ入力基準電圧は5V固定、メインボードのアナログ入力基準電圧は0.7V固定です。 analogReference() 関数はサポートされていません。

1.1.7. analogWrite()

analogWrite(pin, value) にて、約 490 Hz 周期の PWM 信号を出力します。指定する pin 番号が、3, 5, 6, 9 の場合は、ハードウェア機能により PWM 信号を出力します。それ以外の pin 番号を指定した場合は、タイマーを使用して信号を交互に High / Low 出力することでソフトウェア制御により PWM 信号を生成します。

  • pin 3, 5, 6, 9 : ハードウェア制御 PWM

  • 上記以外の pin : ソフトウェア制御 PWM

ハードウェア制御 PWM を使用する場合、3 番 pin と 9 番 pin は連動して PWM モードに切り替わります。analogWrite() 関数で指定した pin には PWM 信号が出力されますが、同時にもう一方の pin も PWM モードに切り替わるため Low 信号が出力されます。両方の pin に対して順番に analogWrite() を呼び出して、二つの pin を PWM として使用することは可能ですが、どちらか一方だけを GPIO として使用するような使い方はできません。また、5 番 pin と 6 番 pin の組み合わせに対しても同様の制約があります。

1.1.8. tone()

tone(pin, frequency [, duration]) は、タイマーを使用してソフトウェア制御により tone 信号を生成します。このときタイマーの分解能が 1 マイクロ秒なので、frequency の半周期が 1 マイクロ秒で割り切れない場合に周波数誤差が発生します。 設定可能な最大 frequency は約 166 kHz です。 tone() 関数は、attachTimerInterrupt() と同じタイマーリソースを使用するため、attachTimerInterrupt() と同時に使用することはできません。

1.1.9. F()

F() マクロはサポートされていません。F() マクロを使用してもコンパイルは可能ですが、通常の文字列データと同様に RAM 上に配置されます。(Fマクロの例: Serial.println(F("This string will be stored in flash memory")); )

1.1.10. PROGMEM

PROGMEM 機能はサポートされていません。 PROGMEM は空マクロとして定義されているため、使用箇所があってもコンパイルエラーにはなりません。

1.1.11. attachInterrupt()

ピンに対する割り込み番号は、attachInterrupt() 関数内で動的に割り当てられます。 digitalPinToInterrupt() は空マクロとして定義されており、 次のどちらの使い方も可能です。

API

attachInterrupt(digitalPinToInterrupt(pin), void (*isr)(void), mode);
attachInterrupt(pin, void (*isr)(void), mode);

Parameter

pin: D05 などのピン番号

isr: 割り込みが発生したときに呼ばれる関数。この関数は引数も戻り値もありません。

この関数は割り込みハンドラから呼ばれるため、呼び出し可能な API には制限があります。 例えば、この関数内から Analog I/O 関数を使用することはできません。

mode: 割り込みを発生させるトリガ

  • LOW: ピンの状態がLOWのとき

  • CHANGE: ピンの状態が変化したとき

  • RISING: ピンの状態がLOWからHIGHに変わったとき

  • FALLING: ピンの状態がHIGHからLOWに変わったとき

  • HIGH: ピンの状態がHIGHのとき

ピン番号の変化に対して、チャタリング防止用にRTC(32.768kHz) 3サイクル分のノイズフィルタをもっています。 そのため、急峻なパルス上の信号変化に対しては割り込みを取得できないことがあります。

1.1.12. attachTimerInterrupt()

タイマー割り込み機能をサポートしています。 この機能は、tone() と同じタイマーリソースを使用するため、tone() と同時に使用することはできません。 attachTimerInterrupt() 機能はシステム上で一つだけ動作します。既に使用中の状態で、 再び attachTimerInterrupt() を呼び出すとエラーになります。異なるハンドラや周期で再設定する際は、detachTimerInterrupt() を呼び出してリソースを解放した後に、再度、attachTimerInterrupt() を呼び出してください。

API

void attachTimerInterrupt(unsigned int (*isr)(void), unsigned int us);

Parameter

isr: タイマー割り込みが発生したときに呼ばれる関数。この関数は次のタイマー周期を戻り値として返します。

  • この関数が 0 を return したときは、タイマーが停止し、ワンショットタイマーとして使用できます。

  • 周期タイマーとして使用したいときは、attachTimerInterrupt() で指定した us 時間と等しい値を return で返してください。

  • その他、return で任意の値を返すことで、次のタイマー割り込みまでの時間を動的に変更することができます。

この関数は割り込みハンドラから呼ばれるため、呼び出し可能な API には制限があります。 例えば、この関数内から Analog I/O 関数を使用することはできません。

us: マイクロ秒

1.1.13. micros()

micros() は RTC (32.768kHz) サイクルでカウントしているため、分解能は約 30 マイクロ秒です。

1.2. メモリの使用状況レポートに関して

Spresense の特徴として、コンパイルされたスケッチは全てフラッシュメモリ内にインストールされ、 それが実行されるときに、コードや読み出し専用のデータを含めてすべて、フラッシュメモリからRAM 上に展開されて RAM 上で実行されます。

展開先の RAM サイズ容量は、 デフォルトの構成でアプリケーション SRAM 1.5 MB のうちの半分 768 キロバイト(= 786432 バイト) が割り当てられています。 このスケッチのプログラムサイズがこの RAM サイズ容量を超えてしまった場合は、コンパイルに失敗しエラーが発生します。

Arduino IDE上で、スケッチをコンパイルした後に以下のようなメモリ使用状況のレポートが出力されます。 このレポートにより、スケッチが消費するメモリサイズを確認することができます。

最大786432バイトのフラッシュメモリのうち、スケッチがxxxxxxバイト(xx%)を使っています。
最大786432バイトのRAMのうち、グローバル変数がxxxxxxバイト(xx%)を使っていて、ローカル変数でxxxxxxバイト使うことができます。

このレポートでは、本来とは異なる意味で用語が使用されているので次のように読み替えてください。

  • フラッシュメモリ: 展開先の RAM サイズ容量を表します

  • グローバル変数 :スケッチが静的に使用する RAM サイズを表します

  • ローカル変数:RAM サイズ容量からスケッチが静的に使用する RAM サイズを差し引いた、残りのRAMサイズを表します

スケッチプログラムが消費するメモリとして、静的に確保されるサイズの他に、動的に確保されるヒープ領域があります。 ローカル変数 で表される残りの RAM サイズは全てこのヒープ領域に割り当てられます。 そのためスケッチ作成時にはヒープ領域の使用分も考慮し、残りの RAM サイズを空けておく必要があります。 目安として、スケッチプログラムの使用サイズが全体の 75% を超えると スケッチが使用できるメモリが少なくなっています。動作が不安定になる可能性があります。 という警告が出力されますので、そのときはスケッチプログラムのコードサイズを削減するなど、プログラムを見直してください。

2. Spresense ハードウェア比較

この章では、Spresense の他のオープンプラットフォームである、Arduino Uno や Raspberry Pi model 3B と比較し、何が違うのかを明らかにします。

2.1. プロセッサとオペレーションシステム

Feature

Arduino Uno

Spresense

Raspberry Pi 3B

Processor type

AVR

ARM M4F

ARM A53

Bits

8

32

64

Number of cores

1

6

4

Clock speed

16 MHz

156 MHz

1.2 GHz

Operating system

None

NuttX

Linux

Boot time

0

<1 second

~20 Seconds

Spresense は、 Arduino のボードと比較すると遥かにパワフルなプロセッサを備えています。これはより計算が必要とされるようなセンサーフュージョンアプリケーションに非常に有利です。しかし、それよりも遥かに高速なCPUを持つ Raspberry Pi には及びません。

Spresense による大きなアドバンテージはその起動速度にあります。 Raspberry Pi は高機能であるが故に起動に20秒はかかりますが、Spresense では1秒もかからずに起動することができます。

2.2. メモリシステム

Feature

Arduino Uno

Spresense

Raspberry Pi 3B

RAM

0.002MB

1.5 MB

1000MB

FLASH

0.032MB

8 MB

None

SD Card

Shield

On-Board, optional

On-Board, essential

eMMC

None

Shield

None

EEPROM

0.001MB

Use Flash

Use microSD card

Arudino は小さなメモリのため、複雑なアプリケーションを構築することを難しくしています。一方、 Raspberry Pi は遥かに大きなメモリを有していますが、それはシステムとして micro SD カードを必要とします。

Spresense はちょうどその中間の位置にあります。プログラムをストアするフラッシュメモリ(ROM)は 8MB あり、またRAMは 1.5MB 有しています。また、micro SD カードもサポートしているため、音楽データや画像データをストアすることができます。

2.3. 電力供給

Feature

Arduino Uno

Spresense

Raspberry Pi 3B

Voltage

5V or 6-20V

5V or LiPo(3.7V)

5V

Typical Operating Power

50 mW

100mW or low power modes

2400mW

Spresense のチップセットである CXD5602 と CXD5247 は、ウェアラブル製品向けに設計されているため、シングルセルのLiPoバッテリで駆動できるように設計されています。また充電機能もあります。しかし、Spresense では安全性の観点から使えるようになっていません。

電源供給は、Spresense メイン基板のUSBコネクタから行ってください。

Spresense は、省電力モードを活用すると非常に小さな電力でセンサー等のイベントを待ち受けることができます。これらは、 ArduinoRaspberry Pi にはない IoT向けセンシングプロセッサならではの機能です。Spresense SDK を使えば、省電力機能を効率的に使うことが可能になります。

2.4. オーディオ

Feature

Arduino Uno

Spresense

Raspberry Pi 3B

Quality

Shield

High

Low

Microphones

Shield

up to 8 microphone

Stereo

Speakers

Shield

Stereo (BTL)

Stereo

CXD5602 と CXD5247 は、ハイクオリティのポータブルオーディオ機器としての機能を持つようにも設計されています。ハイレゾリューションのオーディオの再生とマルチ録音が可能になっています。

CXD5247 は高性能のA/Dコンバータを有しており、アナログなら4チャンネル、デジタルなら8チャンネルのマイク入力を扱うことが可能です。さらに、フルデジタルアンプも備えており、非常にクリアな音でスピーカーに直接出力できます。スピーカー出力はBTL(Balanced Transformer Less)のため、ダイナミックな音を提供することができます。

CXD5602 は専用のAudio DSPを備えており、ハイレゾリューション音源の再生や録音が可能になっています。

これらの機能は、 ArudinoRaspberry Pi を遥かに凌ぐ、Spresense ならではの大きな特長と言えるでしょう。

2.5. GNSS測位機能とリアルタイムクロック

Feature

Arduino Uno

Spresense

Raspberry Pi 3B

GNSS

Shield

GPS & GLONASS

Shield

Time

Shield

RTC

Shield

Spresense は超低消費電力のGNSS受信機能を有しています。これは正確な位置を必要とするトラッキング端末やドローンには非常に重要な機能です。

また、GNSS信号から受信できる極めて正確な時刻でリアルタイムクロックを同期できるため、時刻が重要なデータロギングに向いています。また、時刻をトリガーとして同期しなければならないアプリケーション(例えば、360度映像システム)の制御にも使えます。

ArduinoRaspberry Pi ではそのような機能はシールドで実現しなければならず、低消費電力やローレイテンシーで実現することを非常に難しくしています。

2.6. デジタル端子

Feature

Arduino Uno

Spresense

Raspberry Pi 3B

IO Pins

14

29 + 4 LED

27

IO voltage

5V

5V/3.3V/1.8V

3.3V

UART

1

2

2

SPI

1

1 (3.3/5V) +1 (1.8V)

1

I2C

1

1 (3.3/5V) +1 (1.8V/camera)

2

PWM

6

4

1

Spresense は、UART, I2C, SPI, PWM, I2S など非常に多様なデジタル端子を備えています。

Spresense メインボードのデジタル端子の基準電圧は1.8Vで、Spresense拡張ボードのデジタル端子の基準電圧は、3.3Vもしくは5Vに設定できます。これはメインボードの1.8V基準電圧を3.3Vもしくは5Vにレベルシフトしています。また、メインボードには、ビルトインの四つのLEDを備えています。

Spresense メインボートとSpresense拡張ボードは、100ピンのB2Bコネクタで接続されています、

2.7. A/Dコンバータ

Feature

Arduino Uno

Spresense

Raspberry Pi 3B

Channels

6

6

None

Bits

10

10

None

Fastest rate

~10 kHz

500 kSPS

None

Spresense 拡張ボードには、 Arduino と同じように6チャンネルのアナログ入力端子を備えています。しかし、 Arduino と異なり、アナログ入力端子をデジタル端子として使うことはできません。

また、A/Dコンバータの電圧レンジは5V固定です。SpresenseメインボードのA/Dコンバータ入力端子の電圧レンジは0.7Vなので、Spresense拡張ボードからの入力をノイズを抑えるために、抵抗分圧で電圧シフトしています。

したがって、接続されるデバイスの出力インピーダンスには十分注意を払ってください。

2.8. コネクティビティ

Feature

Arduino Uno

Spresense

Raspberry Pi 3B

USB

1 device

2 device

4 host

Camera

Shield

5M Pixel

8M Pixel

Video display

None

SPI up to 360x240 Pixel

HDMI, DSI

WiFi

Shield

Shield

802.11n

Bluetooth

Shield

Shield

4.1 Classic, Low Energy

Ethernet

Shield

Shield

10/100

Cellular

Shield

Shield

Shield

Spresense メインボードは、 Raspberry Pi と同じく専用のカメラインターフェースを用意しています。専用のカメラボードを使うことでHDの静止画を取得することができます。

3. ライブラリ

3.1. Audio ライブラリ

Spresense Audio ライブラリは、ハイレゾ音源含むオーディオデータの再生・録音を SD カードを使って行うことができます。シンプルなスケッチでハイレゾリューションオーディオの世界を体験することができます。

Spresense は、ADC と DAC (フルデジタルアンプ機能含む) を搭載しており、Audio ライブラリからこれらの機能を制御します。Spresense は 6つの CPU コアが搭載されており、オーディオの信号処理をアプリケーションプロセッサとは別のコア(以降、それらのコアをDSP と呼びます)で動作させることにより、非常に効率的かつ簡単な記述でオーディオのアプリケーションを構築することができます。

  • ハイレゾは、現時点では、192kHzのWAV(LPCM)のみサポートしています。

  • アプリケーションが求めるオーディオ機能に応じて、適切な DSP Codec バイナリを事前にインストールし、アプリケーションプログラムから DSP がインストールされている場所を指定する必要があります。詳細については後述します。

Audio ライブラリの主な特徴

  • Sound recorder

  • Audio player

  • Volume control

  • Balance (L/R Gain)

  • Beep generation

    • Beep音は、Arduino の tone() 関数と異なり、ヘッドホンに出力されますので注意してください。

この Audio ライブラリは input channel、output channel を選択できます。

Audio Input Channels
  • Analog microphone

  • Digital microphone

  • I2S

Audio Output Channel
  • Analog headphone

  • I2S

DSP codec は以下のフォーマットを扱うことができます。

  • MP3

MP3 ファイルは、ID3v2 TAG(特に画像データのような大きなメタデータ)がある場合、 デコーダがparseエラーになります。 MP3Tag などのツールで、タグ情報を削除してください。
  • WAV (PCM)

録音・再生時に、サンプリングレート、ビットレートを指定してください。例えば、MP3 codec は 32000, 44100, 48000 Hz をサポートしています。

詳細については、Audio Subsystem を参照してください。

3.1.1. Audio 動作環境

Audio ライブラリを動作させるために事前に準備が必要なものを以下に示します。

  • Spresense 拡張ボード

  • 録音用マイク

  • 再生用ヘッドホン

  • マイクロ SD カード

Spresense 拡張ボードは、マイク入力専用ピンと SD カードスロット、ヘッドホンジャックを備えています。ヘッドホンジャックは、3極 3.5mm ステレオジャックです。

ピン配置やオーディオ関連のコネクタに関する詳細については マイクの使用方法スピーカーの使用方法 を参照してください。

3.1.2. Audio スケッチのサンプル

Audio ライブラリを使ったサンプルスケッチは、Arduino IDE 上から ファイル → スケッチ例 → Spresense用のスケッチ例 Audio → application 以下にあります。Audio のサンプルスケッチを動かすときは、事前に DSP codec バイナリの準備が必要です。

録音用サンプル (recorder)

このサンプルでは、SD カードとマイクを使用します。

マイクの使用方法を参考に、拡張ボードにマイクを接続してください。

マイクに関するコンフィグレーションをし直したい場合は、MIC channel select map の設定を参照してください。
SDKのbuildとArduinoIDEへの組み込みに関しては、How to prepare Arduino environment を参照してください。

MP3エンコード用の DSP バイナリファイル MP3ENC、 もしくは、WAV、PCMエンコード用の DSP バイナリファイル SRCDSP Codec バイナリのインストール を参照し、インストールしてください。

Arduino IDE 上から ファイル → スケッチ例 → Spresense用のスケッチ例 Audio → application → recorder を選択してサンプルスケッチを起動して実行してください。

サンプルは、起動後に録音を開始し、一定時間で録音を停止します。録音したデータは "Sound.mp3" というファイル名で SD カードに保存されます。

記録する音声フォーマットは、 initRecorder の引数で切り替えることができます。

WAVファイルを記録する場合、音声記録実行前に、 writeWavHeader を呼び出し、WAVヘッダを作成する必要があります。
recorder_wav も参照してください。

ハイレゾ(192kHz)での記録を行う場合は、 setRecorderMode 実行前に、 setRenderingClockModeAS_CLKMODE_HIRES を指定して呼び出します。

MicのGainを設定したい場合は、 setRecorderMode の"input_gain"を設定してください。
デジタルは、0db~-78.5db
アナログは、21db~-78.5db
が設定できる範囲になります。

シリアルモニタにエラーメッセージが表示されている場合は、オーディオサブシステムのエラーについて を参照してください。

録音データを確認する場合は、SD カードを取り外して、PC 上で録音されたデータを確認してください。 また、後述する再生用サンプルでその録音データを再生することも可能です。

音声取得ができたとしても、SDカードの書き込み性能と動作しているアプリケーションなどの要因で、すべてのデータを書き込みことができない可能性があります。
現在の拡張ボードの場合、目安として、8ch/48kHz か、2ch/192kHzが限界になります。

また、SDカードのスピードクラスにも依存します。できるだけ転送速度の速いものをお使いください。

SDカードに書き込む際に必要なバッファのサイズは、デフォルトで、160kバイトになっています。このサイズは、ハイレゾのWAV音声の書き込みが可能なサイズになっており、48kHzのMP3ファイルなどを記録する場合は、メモリを不必要に使用します。
そのため、 setRecorderMode で、使用するバッファサイズを変更することができます。目安としては、ハイレゾのWAVファイルを記録する場合は、デフォルトの160kバイトを、48KHzのMP3ファイルを記録する場合は、8kバイトぐらいに設定することをお勧めします。

サイズに関しては、あくまで目安です。SDカードの性能、アプリケーションの処理量などに応じて、調整して使ってください。
バッファを小さくしすぎると、SDカードへの書き込み時にエラーが発生します。書き込みのオーバーフローが発生する場合は、バッファサイズを大きくしてください。

接続しているマイクがデジタルマイクであった場合は、 setRecorderMode の"is_digital"を"true"にしてください。

音楽再生用サンプル (player)

このサンプルでは、SD カードとヘッドホンを使用します。

拡張ボードにヘッドホンを接続してください。

再生したい MP3/WAV ファイル、もしくは、recorder サンプルスケッチで録音された MP3/WAV ファイルを "Sound.mp3" もしくは、"Sound.wav" というファイル名で SD カードのルートディレクトリに置いてください。

  • MP3 ファイルのサンプリングレートは 32000, 44100 または 48000 bps をサポートしています。

  • MP3 ファイルは、ID3v2 TAG(特に画像データのような大きなメタデータ)がある場合、デコーダがparseエラーになります。 MP3Tag などのツールで、タグ情報を削除してください。

MP3デコード用の DSP バイナリファイル MP3DEC、もしくは、WAVデコード用の DSP バイナリファイル WAVDEC、 を DSP Codec バイナリのインストール を参照しインストールしてください。

Arduino IDE 上から ファイル → スケッチ例 → Spresense用のスケッチ例 Audio → application → player を選択してサンプルスケッチを起動して実行してください。

スケッチがアップロードされ実行されると、SD カードに置いた MP3/WAV ファイルがヘッドホンから再生されます。

ハイレゾ(192kHz)コンテンツの再生を行う場合は、 setPlayerMode 実行前に、 setRenderingClockModeAS_CLKMODE_HIRES を指定して呼び出します。

ハイレゾ、ノーマルレゾリューションを切り替える場合は、一度、 setReadyMode を呼び出し、Ready状態に遷移する必要があります。

出力デバイスをI2Sに切り替えたい場合は、 setPlayerMode での出力デバイスを AS_SETPLAYER_OUTPUTDEVICE_I2SOUTPUT に切り替えてください。
I2Sの動作モードは、Slaveモード、I2Sフォーマットモード、48000Hz、Stereo のみ対応です。

SDカードから読み出す際に必要なバッファのサイズは、各プレイヤーごとにデフォルトで、160kバイトになっています。このサイズは、ハイレゾのWAV音声の読み出しが可能なサイズになっており、48kHzのMP3ファイルなどを再生する場合は、メモリを不必要に使用します。
そのため、 setPlayerMode で、使用するバッファサイズを変更することができます。目安としては、192kHzのハイレゾのWAVファイルを再生する場合は、デフォルトの160kバイトを、128kbps程度ののMP3ファイルを再生する場合は、24kバイトぐらいに設定することをお勧めします。

サイズに関しては、あくまで目安です。SDカードの性能、アプリケーションの処理量などに応じて、調整して使ってください。
バッファを小さくしすぎると、SDカードからの読み出し時にエラーが発生します。読み出しデータのアンダーフローが発生する場合は、バッファサイズを大きくしてください。

SPRESENSEからのオーディオ出力が拡張ボードのオーディオコネクタを用いたラインアウトの場合、CXD5247から出力されるAudioの信号のドライブ能力を setPlayerMode の"sp_drv"で、"AS_SP_DRV_MODE_LINEOUT"に設定してください。
CXD5247のアンプ出力をそのまま用いる、Speakerピンでの出力を行う場合は、"sp_drv"で、"AS_SP_DRV_MODE_4DRIVER"に設定してください。 初期値は、"AS_SP_DRV_MODE_LINEOUT"になっています。

シリアルモニタにエラーメッセージが表示されている場合は、オーディオサブシステムのエラーについて を参照してください。
Beep音サンプル (beep)

このサンプルは、ビープ音を鳴らす例になります。 ヘッドホンを使用します。

Arduino IDE 上から ファイル → スケッチ例 → Spresense用のスケッチ例 Audio → application → beep を選択してサンプルスケッチを起動して実行してください。 Beep音を発音します。

Beep音を発音するためには、setPlayerMode を呼び出し、音楽再生モードに変更する必要があります。

プレイリスト音楽再生用サンプル (play_playlist)

このサンプルは、プレイリスト (playlist) を使用して音楽を再生するためのサンプルスケッチです。

プレイリスト機能を使用するためには、PC 等で事前にプレイリストファイルを作成して SD カードにコピーしておく必要があります。 本サンプルスケッチが使用する SD カードのディレクトリ構成を以下に示します。

SD カードルートディレクトリ
|-- BIN/
|   |-- MP3DEC
|   `-- WAVDEC
|-- AUDIO/
|   |-- Sound1.mp3
|   |-- Sound2.mp3
|   |--   :
|   |-- Sound1.wav
|   |-- Sound2.wav
|   |--   :
`-- PLAYLIST/
    `-- TRACK_DB.CSV
  • BIN/ ディレクトリに、後述されるインストール方法にしたがって、MP3DEC や WAVDEC 等の DSP バイナリファイルをコピーしてください。

  • AUDIO/ ディレクトリに、プレイリストで再生する音楽コンテンツファイルをコピーしてください。

  • PLAYLIST/ ディレクトリに、プレイリストファイル (TRACK_DB.CSV) をコピーしてください。

プレイリストファイル TRACK_DB.CSV のフォーマットを以下に示します。 各ファイルの情報が行単位で書かれた CSV (comma-separated values) 形式のテキストファイルです。

[filename],[artist],[album],[channel number],[bit length],[sampling rate],[file format]
[filename],[artist],[album],[channel number],[bit length],[sampling rate],[file format]
[filename],[artist],[album],[channel number],[bit length],[sampling rate],[file format]
 :

音楽コンテンツのファイル名、アーティスト名、アルバム名や、コーデック情報(チャンネル数、ビット長、サンプリングレートHz)を記述してください。 TRACK_DB.CSV の例を以下に示します。

Sound1.mp3,Artist1,Album1,2,16,44100,mp3
Sound2.mp3,Artist1,Album1,2,16,44100,mp3
Sound1.wav,Artist2,Album2,2,16,48000,wav
Sound2.wav,Artist2,Album2,2,24,192000,wav

また、プレイリストファイルを作成するための簡単なスクリプトツール mkplaylist.py を提供しています。 こちら を右クリックしてファイルをダウンロードしてお使いください。 このスクリプトは ffmpeg-python を使用しているため、ffmpeg 及び ffmpeg-python をインストール済みの環境でご利用ください。

mkplaylist.py の使用方法を以下に示します。

$ python mkplaylist.py
usage: python mkplaylist.py dirname [dirname2] [dirname3] ...
usage: python mkplaylist.py -f filename

Generate an audio playlist file named as TRACK_DB.CSV

引数に音楽ファイルを含むディレクトリパスを指定して実行してください。 正常に実行を完了すると、TRACK_DB.CSV ファイルがカレントディレクトリに出力されます。 既に TRACK_DB.CSV ファイルが存在する場合はファイルの末尾に追加されます。

$ python mkplaylist.py MyMusic
  • 音楽コンテンツファイル名の拡張子は .mp3 もしくは .wav にしてください。

  • 日本語のような2バイトコードを含むファイル名はサポートされていません。ファイル名を ASCII コードの文字列に変更してください。

  • プレイリストファイルが CSV 形式で書かれているため、filename, artist, album 名に "," コンマを含む文字列を使用しないでください。

SD カードを基板に挿した状態で、 Arduino IDE 上から ファイル → スケッチ例 → Spresense用のスケッチ例 Audio → application → play_playlist を選択してサンプルスケッチを起動して実行してください。

起動するとシリアルモニタに次のようなメニューが表示されます。シリアルからのキー入力にしたがって各種の動作を行います。

=== MENU (input key ?) ==============
p: play  s: stop  +/-: volume up/down
l: list  n: next  b: back
r: repeat on/off  R: random on/off
a: auto play      m,h,?: menu
=====================================

また、EEPROM ライブラリを使用して、volume 値, random / repeat / auto play 等の設定情報を不揮発メモリに保存しています。 次回起動時に、前回プリセットされた情報をもとに動作するというサンプルアプリケーションになっています。

オリジナルのミュージックプレイヤーを作成する際に参考にしてください。

Audio Throughサンプル (through)

このサンプルは、I2Sから入力されたデジタル音声をアナログ出力に出力したり、マイク入力をI2Sに出力するなど、オーディオHWのパス設定を用いることで、省電力で、非常にレイテンシの少ない出力を実現します。
このアプリケーションは、SWでのAudio信号処理が必要でないため、DSP、すなわち、SDカードが不要です。
マイクを使用する場合は、マイクの使用方法を参考に、拡張ボードにマイクを接続してください。

マイクに関するコンフィグレーションをし直したい場合は、MIC channel select map の設定を参照してください。
SDKのbuildとArduinoIDEへの組み込みに関しては、How to prepare Arduino environment を参照してください。

例えば、I2Sから入力された音声をアナログ出力したい場合は、 setThroughMode の"input"を"I2sIn"に設定し、
"i2s_out"を"None"に、
"sp_out"を"true"に設定します。

Micから入力された音声をI2S出力したい場合は、 setThroughMode の"input"を"MicIn"に設定し、
"i2s_out"を"Mic"に、
"sp_out"を"false"に設定します。

MicのGainを設定したい場合は、 setThroughMode の"input_gain"を設定してください。
デジタルは、0db~-78.5db
アナログは、21db~-78.5db
が設定できる範囲になります。

SPRESENSEからのオーディオ出力が拡張ボードのオーディオコネクタを用いたラインアウトの場合、CXD5247から出力されるAudioの信号のドライブ能力を setThroughMode の"sp_drv"で、"AS_SP_DRV_MODE_LINEOUT"に設定してください。
CXD5247のアンプ出力をそのまま用いる、Speakerピンでの出力を行う場合は、"sp_drv"で、"AS_SP_DRV_MODE_4DRIVER"に設定してください。 初期値は、"AS_SP_DRV_MODE_LINEOUT"になっています。

そのほかの複合サンプル

通常サンプルの他に、幾つかの複合動作サンプルがあります。

  • dual_players
    2つの音楽再生を同時に行うサンプルです。

  • pcm_capture
    音声データをキャプチャするだけのサンプルです。信号解析などにお使いください。

  • rec_play
    音声を録音した後、その音声を再生するサンプルです。オーディオ動作を切り替えるためのサンプルになります。

  • Recorder_with_rendering
    音声を確認しながら録音するサンプルです。

  • Voice_effector
    入力音声を加工しながら出力するサンプルです。

3.1.3. DSP Codec バイナリのインストール

オーディオの再生・録音機能を動かす際に、適切な DSP バイナリファイルを下記の手順に従ってインストールしてください。

表 1. DSPの種類
DSPファイル名 DSP インストーラー 説明

MP3DEC

mp3_dec_installer

MP3 オーディオ再生で使用します

WAVDEC

wav_dec_installer

WAV (PCM) オーディオ再生で使用します

MP3ENC

mp3_enc_installer

MP3 オーディオ録音で使用します

SRC

src_installer

WAV(PCM) オーディオ録音で使用します

DSP バイナリのインストール先は、SD カード、もしくは、フラッシュを選択できます。インストール手順は、単純に PC を使って SD カードへファイルをコピーする方法と、DSP インストーラーと呼ばれるスケッチを用いた方法の二通りがあります。

DSP バイナリのインストール作業は、DSP ファイルの更新が無い限り、一回実行してインストール済みの状態であれば毎回作業する必要はありません。
  • SD カードへ DSP ファイルをコピーしてインストールする場合

    1. 上の表 にあるDSP ファイルを次の手順でインストールされているSpresense Arduino パッケージから取り出します。ご使用のPCのプラットフォーム毎に異なりますのでお使いのOSの手順をご参照ください。

      • Windowsの場合

        • 次のテキストをコピーして pickup_dsp.bat としてファイルを作成します。

          set SPRESENSE_DIR=%userprofile%\AppData\Local\Arduino15\packages\SPRESENSE\hardware\spresense
          set AUDIO_DSP_DIR=libraries\Audio\examples\dsp_installer
          
          for /f "usebackq tokens=*" %%i IN (`dir /B %SPRESENSE_DIR%`) DO @set BOARD_VERSION=%%i
          
          set DSP_OUT=dsp_ver%BOARD_VERSION%
          
          echo "DSP binary copy to %DSP_OUT%"
          
          mkdir %DSP_OUT%"
          
          copy %SPRESENSE_DIR%\%BOARD_VERSION%\%AUDIO_DSP_DIR%\mp3_dec_installer\MP3DEC %DSP_OUT%\
          copy %SPRESENSE_DIR%\%BOARD_VERSION%\%AUDIO_DSP_DIR%\mp3_enc_installer\MP3ENC %DSP_OUT%\
          copy %SPRESENSE_DIR%\%BOARD_VERSION%\%AUDIO_DSP_DIR%\src_installer\SRC %DSP_OUT%\
          copy %SPRESENSE_DIR%\%BOARD_VERSION%\%AUDIO_DSP_DIR%\wav_dec_installer\WAVDEC %DSP_OUT%\
        • pickup_dsp.bat をダブルクリックで実行するとDSPファイルが dsp_ver1.x.x にコピーされます。

      • Ubuntu/Macintoshの場合

        • 次のテキストをコピーして pickup_dsp.sh としてファイルを作成します。

          #! /bin/bash
          
          HOST=`uname`
          if [ "${HOST}" == "Linux" ]; then
                  ARDUINO_ROOT=~/.arduino15
          elif [ "${HOST}" == "Darwin" ]; then
                  ARDUINO_ROOT=~/Library/Arduino15
          else
                  echo "ERROR: Cannot detect your machine."
                  exit
          fi
          
          SPRESENSE_ROOT=${ARDUINO_ROOT}/packages/SPRESENSE/hardware/spresense
          AUDIO_DSP_PATH=libraries/Audio/examples/dsp_installer
          
          BOARD_VERSION=`ls ${SPRESENSE_ROOT}`
          
          DSP_OUT=dsp_ver${BOARD_VERSION}
          
          echo "DSP binary copy to `pwd`/${DSP_OUT}"
          
          mkdir -p ${DSP_OUT}
          cp -a ${SPRESENSE_ROOT}/${BOARD_VERSION}/${AUDIO_DSP_PATH}/mp3_dec_installer/MP3DEC ${DSP_OUT}/
          cp -a ${SPRESENSE_ROOT}/${BOARD_VERSION}/${AUDIO_DSP_PATH}/mp3_enc_installer/MP3ENC ${DSP_OUT}/
          cp -a ${SPRESENSE_ROOT}/${BOARD_VERSION}/${AUDIO_DSP_PATH}/src_installer/SRC ${DSP_OUT}/
          cp -a ${SPRESENSE_ROOT}/${BOARD_VERSION}/${AUDIO_DSP_PATH}/wav_dec_installer/WAVDEC ${DSP_OUT}/
        • pickup_dsp.sh を下記コマンドで実行するとDSPファイルが dsp_ver1.x.x にコピーされます。

          $ bash pickup_dsp.sh
    2. SD カードに BIN ディレクトリを作成し、そこに取り出したファイルをコピーしてください。

      arduino dsp copy ja
      図 1. DSPファイルのコピー

      オーディオの再生・録音のアプリケーションプログラムにおいて、DSP ファイルがインストールされた場所を initPlayer() 関数、または initRecorder() 関数の引数で指定する必要があります。SD カードへインストールした場合は、/mnt/sd0/BIN を指定してください。Example スケッチでは、/mnt/sd0/BIN が指定されています。

  • DSPインストーラー用いてインストールする場合

    DSP インストーラーは、Arduino IDE 上から ファイル → スケッチ例 → Spresense用のスケッチ例 Audio → dsp_installer 以下にあります。DSP バイナリごとにインストーラーが分かれているので、上の表に従って、DSP インストーラーを選んで起動してください。

    arduino dsp installer ja
    図 2. DSPインストーラーの起動

    コンパイル&書き込み(Upload)の実行が終わったら、シリアルモニタを起動してください。

    1. ボーレート 115200 bps を選択すると、下図に示すメッセージが表示されます。

    2. インストール先の番号を入力してください。 SD カードへインストールする場合は、Spresense 拡張ボード上の SD カードスロットへ FAT フォーマット済みの SD カードを挿入してください。

    3. 送信ボタンを押してください。

      arduino dsp installer monitor1 ja
      図 3. DSPインストール先の選択

      インストールが成功すれば下図に示すメッセージ表示されます。

      arduino dsp installer monitor2 ja
      図 4. DSPインストール実行

    オーディオの再生・録音のアプリケーションプログラムにおいて、DSP ファイルがインストールされた場所を initPlayer() 関数、または initRecorder() 関数の引数で指定する必要があります。SD カードへインストールした場合は、/mnt/sd0/BIN を指定し、フラッシュへインストールした場合は、/mnt/spif/BIN を指定してください。Example スケッチでは、SD カード /mnt/sd0/BIN が使用されています。

3.1.4. 詳細情報

さらなる情報については、以下のリンクを参照してください。

3.2. Camera ライブラリ

ここでは、Spresense のArduino IDE で利用可能なCameraライブラリについて説明します。

3.2.1. 概要

下記にCamera ライブラリの概略図を示します。

arduino camera overview
図 5. Camera Overview

Spresense Cameraには、2つのライブラリクラスが用意されています。 1つは、CameraClassのインスタンスである"theCamera"で、もう一つがCameraから取得した画像を操作するCamImageクラスです。

"theCamera"には大きく3つの機能が備わっています。

  • CameraのPreviewを取得するVideoStream機能

  • Cameraのパラメータを制御する機能

  • Cameraで高解像度なJPEG画像を写真として取得する機能

CamImageクラスは、theCameraから取得した画像イメージをユーザが操作するための関数です。 CamImageクラスの概要を以下の図に示します。

arduino camera camimage
図 6. CamImage Overview

CamImageクラスには、2つの機能が備わっています。

  • Cameraで撮影された画像の情報を取得する。

  • 取得した画像を変換する。

以下に、theCameraおよびCamImageが持つ、これら5つの機能について説明します。

3.2.2. CameraのPreviewを取得するVideoStream機能

通常カメラのファインダーには、Cameraに映るリアルタイムの画像が映っています。 ここでは、このリアルタイム画像(リアルタイム動画)をPreview画像と呼びます。 "theCamera"には、このPreview画像を毎フレーム取得する機能が備わっています。

Preview画像を取得するには、まず、begin()メソッド関数を用いて、Preview画像の画像フォーマットを決定します。 begin()メソッド関数の定義は以下のようになっています。

begin(
    int buff_num=1,
    CAM_VIDEO_FPS fps = CAM_VIDEO_FPS_30,
    int video_width   = CAM_IMGSIZE_QVGA_H,
    int video_height  = CAM_IMGSIZE_QVGA_V,
    CAM_IMAGE_PIX_FMT fmt=CAM_IMAGE_PIX_FMT_YUV422)

begin()に与えるパラメータはすべてPreview画像のパラメータを決定するものです。 それぞれ、theCamera内部で持つPreview用画像バッファの数とVideoのフレームレート(1秒間に何コマの画像を取得するか)、 画像の縦横サイズと画像データのピクセルフォーマットになります。 デフォルトではそれぞれ、内部画像バッファ数が1枚、フレームレートが30FPS(1秒間に30枚)、画像サイズがQVGA(320 x 240)、ピクセルフォーマットがYUV422となっています。 内部画像バッファの数は通常使用であればデフォルトの値をご使用ください。

内部画像バッファの数を増やす際の例としては、 取得した画像を色々と加工するなどの重たい処理をさせたい場合に、画像処理とCameraからの画像取得を並列化したい、という場合が考えられます。 そのような場合、内部画像バッファ数を2にすることで、その重たい処理をさせながら、その裏でCameraからの画像取得を平行して行うということが可能となり、結果的にフレームレートが改善する場合もあります。 ただし、QVGAでバッファのメモリを約150KB消費しますので、枚数を多く設定する場合はご注意ください。

現在、画像サイズはQVGAのみサポートしています。 QVGA以外の値を設定するとbegin()でエラーが発生します。 また、 Preview画像のピクセルフォーマットはYUV422のみサポートしています。

begin()メソッド関数は、theCameraを利用する際に最初に呼び出す必要のある関数です。 begin()メソッド関数が正常に終了したらstartStreaming()メソッド関数を使ってPreview画像を取得するためのコールバック関数を登録します。 コールバック関数の型は以下のようになります。

void camera_callback(CamImage img)

ユーザはこの型の関数を独自に実装して、startStreaming()メソッド関数を用いて登録します。 startStreaming()の第一引数に"true"を指定すると、Preview用のVideo画像の取得が開始され、画像が取得されるたびに登録されたコールバック関数が呼び出されます。 画像を取得する頻度は、begin()メソッド関数で指定した、フレームレートによって決定します。 ただし、ユーザが実装したコールバック関数が終了しない限り、次のフレームのコールバック関数が呼び出されることはありません。 Preview画像の取得を停止したい場合は、startStreaming()メソッド関数の第一引数をfalseにしてstartStreaming()メソッド関数を呼び出してください。

3.2.3. Cameraのパラメータを制御する機能

通常のCameraには、色味の調整や明るさなど、様々な設定が出来るようになっており、Spresense Cameraにも、いくつかの設定が出来るようになっています。

表 2. Camera Parameter Control method functions
Method name Description

setAutoWhiteBalance()

Cameraの自動ホワイトバランスの開始停止

setAutoISOSensitive()

Cameraの自動ISO感度の開始停止

setISOSensitivity()

マニュアルISO感度設定でのISO感度設定

setAutoWhiteBalanceMode()

自動ホワイトハウス時のモード設定

setColorEffect()

画像効果設定

これらの設定メソッド関数はbegin()メソッド関数をエラー無く呼び出した後であれば、任意のタイミングで呼び出すことが可能です。

3.2.4. Cameraで高解像度なJPEG画像を写真として取得する機能

Preview画像は低解像度な半面、動画としてフレームレートの頻度で画像を取得することが出来ます。 一方、写真としてデータを取得する場合、Spresense Cameraでは、高解像度なJPEG圧縮された画像を取得することが出来ます。

まず、theCameraに対して「フィルムをセットする」という処理を行います。 この処理を行うメソッド関数が、setStillPictureImageFormat()になります。 このメソッド関数を用いて、静止画(写真)用の画サイズやピクセルフォーマットを設定します。

setStillPictureImageFormat(int width, int height, CAM_IMAGE_PIX_FMT fmt = CAM_IMAGE_PIX_FMT_JPEG)

第一、第二引数で画像の縦横サイズを指定します。第三引数で画像のピクセルフォーマットを指定します。

現在、画像のピクセルフォーマットはJPEGのみサポートしています。

setStillPictureImageFormat()メソッド関数は、1度設定を行えば、パラメータの変更をしない限り、永続的に設定が有効になります。

画像の設定が終わったら、任意のタイミングで「シャッターを切る」という処理を行い、写真データを取得します。 そのためのメソッド関数がtakePicture()になります。 takePicture()は戻り値としてCamImageのインスタンスを返します。 写真撮影で何らかのエラーが発生した場合、空のCamImageを返します。 CamImageのインスタンスが空かどうかを判断するには、CamImageクラスのisAvailable()で確認することが出来ます。

3.2.5. Cameraで撮影された画像の情報を取得する。

startStreaming()でのコールバック及びtakePicture()の戻り値で得られるCamImageインスタンスは、取得した画像の情報が入っています。 CamImageクラスのメソッド関数を用いて、画像の情報を取得することが出来ます。

表 3. Methods to get Informations from CamImage
Method name Description

isAvailable()

取得したCamImageインスタンスが利用可能なものかどうかを確認する

getWidth()

画像の幅をピクセル単位で取得

getHeight()

画像の高さをピクセル単位で取得

getPixFormat()

画像のピクセルフォーマットを取得

getImgSize()

画像のデータのサイズをバイト単位で取得

getImgBuff()

画像データのバッファアドレスを取得

3.2.6. 取得した画像を変換する。

CamImageインスタンスには1つの画像変換メソッド関数が用意されています。

表 4. Methods to convert CamImage
Method name Description

convertPixFormat()

現状のピクセルフォーマットから別のピクセルフォーマットに画像を変換する

画像をディスプレイに出したいような場合、ディスプレイのピクセルフォーマットは通常、RGBフォーマットが用いられます。 特にPreview画像を取得した場合、取得した画像をディスプレイ表示したいケースは多いと思います。 このようなケースで、ピクセルフォーマットの変換を行う際などに、このメソッド関数を用いることが出来ます。

convertPixFormat()は自身データメモリ上でピクセルフォーマットが変換されるため、 現在のCamImageインスタンスが上書きされます。

現時点では以下の制約があります。

  • convertPixformat()は、YUV422からRGB、YUV422からGLAY、の2つのみ対応しています

3.2.7. サンプルコードによる解説

ここでは、実際に、Spresense Arduino Packageに含まれるCameraのサンプルコードを用いて、 Spresense Cameraの使い方を解説します。

サンプルコードは、Arduino IDEのメニューバーから開くことが出来ます。

「ファイル」⇒「スケッチ例」⇒「Spresenseのスケッチ例の中のCamera」⇒「camera」

/*
 *  camera.ino - One minute interval time-lapse Camera
 *  Copyright 2018 Sony Semiconductor Solutions Corporation
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License as published by the Free Software Foundation; either
 *  version 2.1 of the License, or (at your option) any later version.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 *  This is a test app for the camera library.
 *  This library can only be used on the Spresense with the FCBGA chip package.
 */

#include <SDHCI.h>
#include <stdio.h>  /* for sprintf */

#include <Camera.h>

#define BAUDRATE                (115200)

SDClass  theSD;
int take_picture_count = 0;


/**
 * Callback from Camera library when video frame is captured.
 */

void CamCB(CamImage img)
{

  /* Check the img instance is available or not. */

  if (img.isAvailable())
    {

      /* If you want RGB565 data, convert image data format to RGB565 */

      img.convertPixFormat(CAM_IMAGE_PIX_FMT_RGB565);

      /* You can use image data directly by using getImgSize() and getImgBuff().
       * for displaying image to a display, etc. */

      Serial.print("Image data size = ");
      Serial.print(img.getImgSize(), DEC);
      Serial.print(" , ");

      Serial.print("buff addr = ");
      Serial.print((unsigned long)img.getImgBuff(), HEX);
      Serial.println("");
    }
  else
    {
      Serial.print("Failed to get video stream image\n");
    }
}

/**
 * @brief Initialize camera
 */
void setup()
{

  /* Open serial communications and wait for port to open */

  Serial.begin(BAUDRATE);
  while (!Serial)
    {
      ; /* wait for serial port to connect. Needed for native USB port only */
    }


  /* begin() without parameters means that
   * number of buffers = 1, 30FPS, QVGA, YUV 4:2:2 format */

  Serial.println("Prepare camera");
  theCamera.begin();


  /* Start video stream.
   * If received video stream data from camera device,
   *  camera library call CamCB.
   */

  Serial.println("Start streaming");
  theCamera.startStreaming(true, CamCB);

  /* Auto white balance configuration */

  Serial.println("Set Auto white balance parameter");
  theCamera.setAutoWhiteBalanceMode(CAM_WHITE_BALANCE_DAYLIGHT);

  /* Set parameters about still picture.
   * In the following case, QUADVGA and JPEG.
   */

  Serial.println("Start streaming");
  theCamera.setStillPictureImageFormat(
     CAM_IMGSIZE_QUADVGA_H,
     CAM_IMGSIZE_QUADVGA_V,
     CAM_IMAGE_PIX_FMT_JPG);
}

/**
 * @brief Take picture with format JPEG per second
 */

void loop()
{
  sleep(1); /* wait for one second to take still picture. */

  /* You can change the format of still picture at here also, if you want. */

  /* theCamera.setStillPictureImageFormat(
   *   CAM_IMGSIZE_HD_H,
   *   CAM_IMGSIZE_HD_V,
   *   CAM_IMAGE_PIX_FMT_JPG);
   */

  /* This sample code can take 100 pictures in every one second from starting. */

  if (take_picture_count < 100)
    {

      /* Take still picture.
      * Unlike video stream(startStreaming) , this API wait to receive image data
      *  from camera device.
      */

      Serial.println("call takePicture()");
      CamImage img = theCamera.takePicture();

      /* Check availability of the img instance. */
      /* If any error was occured, the img is not available. */

      if (img.isAvailable())
        {
          /* Create file name */

          char filename[16] = {0};
          sprintf(filename, "PICT%03d.JPG", take_picture_count);

          Serial.print("Save taken picture as ");
          Serial.print(filename);
          Serial.println("");

          /* Save to SD card as the finename */

          File myFile = theSD.open(filename, FILE_WRITE);
          myFile.write(img.getImgBuff(), img.getImgSize());
          myFile.close();
        }

      take_picture_count++;
    }
}

このサンプルは、Preview画像をQVGA、フレームレートを60FPSに設定し、60コマのデータを取得すると1枚JPEG写真を撮り、SDCardに保存する、 という動作をします。

ステップとしては、「初期設定」、「setup()」、「Previewコールバック」そして「loop()」の4つで動作しています。

それでは、これら4つについて詳しく見ていきましょう。

初期設定
/*
 *  camera.ino - One minute interval time-lapse Camera
 *  Copyright 2018 Sony Semiconductor Solutions Corporation
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License as published by the Free Software Foundation; either
 *  version 2.1 of the License, or (at your option) any later version.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 *  This is a test app for the camera library.
 *  This library can only be used on the Spresense with the FCBGA chip package.
 */

#include <SDHCI.h>
#include <stdio.h>  /* for sprintf */

#include <Camera.h>

#define BAUDRATE                (115200)

SDClass  theSD;
int take_picture_count = 0;

まず、Camera ライブラリを利用する場合、ヘッダファイル <Camera.h> をインクルードする必要があります。

#include <Camera.h>

このヘッダファイルをインクルードすることで、thCameraインスタンスを利用することが出来るようになります。

その後、コールバック関数とloop()関数で共通で使う変数を定義しています。

int take_picture_count = 0;

take_picture_countは、1秒おきにtakePicture()を呼ばれる度にカウントアップしていく変数で、この変数を用いて、 SDCardに書き出されるファイル名と作成するファイル数の上限を制御しています。 (このサンプルでは100枚の写真を撮ると写真撮影を終了するようになっています。)

Previewコールバック
/**
 * Callback from Camera library when video frame is captured.
 */

void CamCB(CamImage img)
{

  /* Check the img instance is available or not. */

  if (img.isAvailable())
    {

      /* If you want RGB565 data, convert image data format to RGB565 */

      img.convertPixFormat(CAM_IMAGE_PIX_FMT_RGB565);

      /* You can use image data directly by using getImgSize() and getImgBuff().
       * for displaying image to a display, etc. */

      Serial.print("Image data size = ");
      Serial.print(img.getImgSize(), DEC);
      Serial.print(" , ");

      Serial.print("buff addr = ");
      Serial.print((unsigned long)img.getImgBuff(), HEX);
      Serial.println("");
    }
  else
    {
      Serial.print("Failed to get video stream image\n");
    }
}

startStreaming()で登録される、カメラのPreviewが出力された際に呼び出される関数になります。 この関数内では、関数の引数として取得したCamImageのインスタンスが利用可能なものかどうかのチェックを行い、 その後、ピクセルフォーマットをRGB565に変換しています。 変換後、getImgSize()とgetImgBuff()で取得したデータサイズとメモリアドレスを表示しています。 一般的には、この段階で接続したディスプレイなどにイメージデータを出力して、 カメラのファインダービューを構築します。

setup()
/**
 * @brief Initialize camera
 */
void setup()
{

  /* Open serial communications and wait for port to open */

  Serial.begin(BAUDRATE);
  while (!Serial)
    {
      ; /* wait for serial port to connect. Needed for native USB port only */
    }


  /* begin() without parameters means that
   * number of buffers = 1, 30FPS, QVGA, YUV 4:2:2 format */

  Serial.println("Prepare camera");
  theCamera.begin();


  /* Start video stream.
   * If received video stream data from camera device,
   *  camera library call CamCB.
   */

  Serial.println("Start streaming");
  theCamera.startStreaming(true, CamCB);

  /* Auto white balance configuration */

  Serial.println("Set Auto white balance parameter");
  theCamera.setAutoWhiteBalanceMode(CAM_WHITE_BALANCE_DAYLIGHT);

  /* Set parameters about still picture.
   * In the following case, QUADVGA and JPEG.
   */

  Serial.println("Start streaming");
  theCamera.setStillPictureImageFormat(
     CAM_IMGSIZE_QUADVGA_H,
     CAM_IMGSIZE_QUADVGA_V,
     CAM_IMAGE_PIX_FMT_JPG);
}

setup()では、初めにメッセージ表示用にSerialのセットアップを行い、続いてCameraのbegin()メソッド関数を呼び出しています。 Cameraのbegin()はデフォルトではフレームバッファメモリは1枚、フレームレートが30FPS、画サイズはQVGAになっています。 その後、startStreaming()でPreview用コールバック関数の設定とコールバックを有効にし、setAutoWhiteBalanceMode()で日中設定にしています。 最後に、setStillPictureImageFormat()で、QUAD VGAサイズの写真用の設定を行っています。

loop()
/**
 * @brief Take picture with format JPEG per second
 */

void loop()
{
  sleep(1); /* wait for one second to take still picture. */

  /* You can change the format of still picture at here also, if you want. */

  /* theCamera.setStillPictureImageFormat(
   *   CAM_IMGSIZE_HD_H,
   *   CAM_IMGSIZE_HD_V,
   *   CAM_IMAGE_PIX_FMT_JPG);
   */

  /* This sample code can take 100 pictures in every one second from starting. */

  if (take_picture_count < 100)
    {

      /* Take still picture.
      * Unlike video stream(startStreaming) , this API wait to receive image data
      *  from camera device.
      */

      Serial.println("call takePicture()");
      CamImage img = theCamera.takePicture();

      /* Check availability of the img instance. */
      /* If any error was occured, the img is not available. */

      if (img.isAvailable())
        {
          /* Create file name */

          char filename[16] = {0};
          sprintf(filename, "PICT%03d.JPG", take_picture_count);

          Serial.print("Save taken picture as ");
          Serial.print(filename);
          Serial.println("");

          /* Save to SD card as the finename */

          File myFile = theSD.open(filename, FILE_WRITE);
          myFile.write(img.getImgBuff(), img.getImgSize());
          myFile.close();
        }

      take_picture_count++;
    }
}

loop()関数では、まず、1秒ほどsleep()関数で待ちます。 1秒後、take_picture_count変数の値が100を超えていないかチェックし、超えていなければ写真撮影処理に入ります。 撮影する処理では、 takePicture()メソッド関数をコールし、写真撮影を行って、取得した写真をimg変数に代入します。 img変数が利用可能であることをisAvailable()関数で確認し、取得した画像をSDカードに保存します。 最後に、take_picture_countをインクリメント(1増やす)して、loop()関数を終了しています。

以上でサンプルを使った説明は終わりになります。

さあ、Spresense Cameraを使ってオリジナルカメラデバイスを作ってみましょう。

3.3. DNNRTライブラリ

DNN Runtimeライブラリは、Sonyが提供するNeural Network LibrariesまたはNeural Network Consoleで学習したモデルを使用して、Deep Neural Network (DNN) を用いた認識処理を行うことができます。

dnnrt overview ja

DNNRTライブラリには、コアとなる DNNRT と、データの入出力に使用する DNNVariable があります。

ここでは、0~9までの手書き文字を認識するためのサンプル(number_recognition.ino)を例に解説していきます。

3.3.1. 学習済みモデルの準備

Neural Network Console

学習済みモデルを作成するために、Neural Network Console (NNC)を使用します。こちらの、公式サイト からクラウド版の使用、またはWindows版インストーラがダウンロードできます。

学習
  1. クラウド版では、サンプルプロジェクトの image_recognition.MNIST.LeNet をベースに新しいプロジェクトを作成します。サンプルのプロジェクトを選択すると選択されたプロジェクトを元に新しいプロジェクトを作成します。新しいプロジェクトの名前を入力するダイアログボックスが表示されるので、好きな名前を入力してください。(ここでは、myproject とします)

    作成された myproject を選択すると編集画面が表示されます。

    edit
    図 7. 編集画面(クラウド版)

    Windows版では、LeNet.sdcproj を選択して使用します。

  2. ここでは、サンプルのネットワークモデルをそのまま使用して学習を行います。

    クラウド版では、編集画面の右上にある Run ボタンを押します。

    start
    図 8. 学習開始(クラウド版)

    Windows版では、Training の下にある三角ボタンを押します。

    start
    図 9. 学習開始(Windows版)
  3. ウィンドウ下部のコンソールに Training Completed が表示されれば学習は完了です。

    TRAINING
機械学習は非常に時間がかかります。
  1. 学習が完了したら学習結果を評価します。

    クラウド版では、学習画面の右上にある Run ボタンを押します。

    EVALUATE
    図 10. 評価開始(クラウド版)

    Windows版では、Evaluation の下にある三角ボタンを押します。

    EVALUATE
    図 11. 評価開始(Windows版)
  2. 評価が完了すると評価結果が表示されます。 x:image の列に表示されている画像と y:label の列に表示されている数字が一致しているはずです。DNNRTで使用するためにこの学習済みモデルをダウンロードします。

    クラウド版では、評価画面右上のドロップダウンリストから NNB (NNabla C Runtime file format) を選択し、下の Download Project を押します。

    DOWNLOAD

    Windows版では、ACTION メニューから、ExportNNB (NNabla C Runtime file format) を選択します。

    DOWNLOAD
  3. ダウンロードした学習済みモデル result.nnb (クラウド版)または model.nnb (Windows版)と認識させたい画像をSDカードの直下にコピーします。学習済みモデルは、network.nnb というファイル名に変更してください。このサンプルで対応している画像フォーマットはPGM (Portable Greyscale Map) のみです。PGMファイルを作れない場合は、こちらのサンプルPGM画像ファイルを使用してください。

以上で number_recognition.ino サンプルを動作させる準備は完了です。

3.3.2. 手書き文字認識サンプル

image_recognition.MNIST.LeNet および LeNet.sdcproj で作成された学習モデルは、28x28サイズの画像を1つ入力にとり、10個の配列を出力します。この10個の配列はインデックスが認識した数字を意味しており、配列の中にそれぞれの数字である確率が出力されます。例えば、配列の先頭(インデックス0)には、入力された画像が数字の「0」である確率が出力されます。

各数字の確率を表示する場合の例
DNNVariable output = dnnrt.outputVariable(0);

Serial.println(output[0]);   // 入力画像が「0」である確率
 ...
Serial.println(output[9]);   // 入力画像が「9」である確率

number_recognition.ino では、出力された確率の配列の中から一番大きい確率のインデックスを認識した数字として、その確率とともにシリアルに出力します。

入力させたい画像は、number_recognition.ino の以下の行で変更できます。

  File pgmfile("number4.pgm");

3.4. EEPROM ライブラリ

EEPROM は、電源を切っても内容が消去されない不揮発なデータを保持することができます。 Spresense では EEPROM が搭載されていないので、SPI-Flash メモリを用いて EEPROM をエミュレートしています。 このライブラリは、SPI-Flash によってエミュレートされた EEPROM に対して、書き込みと読み込みを可能にします。

EEPROM ライブラリの API 仕様については、Arduino EEPROM ライブラリ を参照してください。

EEPROM のサンプルコードは、Arduino IDE のメニューから ファイル → スケッチ例 → Spresense用のスケッチ例 EEPROM 以下に用意されています。 EEPROM ライブラリは、Arduino EEPROM ライブラリと互換性をもち Arduino 用のサンプルコードをそのまま動かすことができます。

EEPROM サイズは、EEPROM.h に定義されている E2END の値によって決められ、4000 バイトです。

Spresense ボードにおいて、アプリケーションからアクセスできる SPI-Flash の最大容量は 4MByte です。 この最大容量を超えない範囲で、E2END を変更することによって EEPROM のサイズをさらに増やすことも可能です。

3.5. GNSS ライブラリ

GNSS ライブラリは、Spresense の GNSS測位機能をコントロールし、位置情報を取得するためのライブラリです。Arduino のスケッチから簡単に使うことができます。

使用するにあたって、特別なハードウェアの設定は必要ありません。アンテナも Spresense メインボード上にマウントされていますので、見晴らしのよい屋外に出れば簡単に位置情報を得ることができます。ただし、起動時に衛星を捕捉するのに1〜2分かかりますので、アプリケーション設計時には留意してください。

本ライブラリを使用するにあたって、Spresense拡張ボードは必要ありません。メインボード単体で動作させることができます。

GNSS ライブラリには、2つのサンプルスケッチが提供されています。

  • gnss.ino は、GNSSで測位された情報を USBシリアルポートから出力する簡単なサンプルです。このサンプルでは位置情報を GNSS ライブラリ特有のフォーマットで出力されます。詳細については GNSS.h を参照してください。

  • gnss_tracker.ino は、少し複雑なサンプルです。このサンプルは、SDカードに位置情報を保存するので、Spresense拡張ボードが必要です。SDカードには、位置情報で一般的に使われている NMEA フォーマットで保存されますので、様々なアプリケーションから利用できます。

3.5.1. 詳細情報

さらに詳細の情報については、 Spresense SDK GNSS documentation を参照してください。

3.6. LowPower ライブラリ

LowPowerライブラリは、Spresenseがもつ省電力機能をサポートしています。

LowPowerライブラリは、主に以下の機能を提供しています。

  • Deep SleepCold Sleep など各種スリープ状態への遷移

    Deep Sleep

    最も消費電力が低いスリープモードです。CXD5247 PMIC (Power Management IC) のみ電源が入っており、CXD5602 は電源が OFF されます。

    Cold Sleep

    CXD5602 内で必要最小限の電源ドメインのみ ON されているスリープモードです。Deep Sleep に比べると消費電力は高くなりますが、GPIO の変化を起動要因のトリガとして、Cold Sleep 状態から起床することができます。

Sleep 中の消費電力に関して、拡張ボードに SD カードが挿入されていると SD カードの電源消費分により 約 5 mA ほど消費電流が増加します。
  • スリープ状態から起床したときの起動要因の取得

  • 起動要因の許可/禁止を設定する起動マスクの設定

各種APIの詳細は、APIリファレンスマニュアル LowPower Library API を参照してください。

LowPower ライブラリの基本的な使い方は、examples にあるサンプルスケッチをご覧ください。 サンプルスケッチは、Arduino IDE メニューの ファイル → スケッチ例 → Spresense 用のスケッチ例 LowPower から開くことができます。

Example Description

ExternalWakeup

GPIO外部ピンの状態変化によって、Cold Sleepから起床します

TimedWakeup

RTCアラームによって、Cold Sleepから起床します

TimedWakeupDeep

RTCアラームによって、Deep Sleepから起床します

Reboot

システムを再起動します

WatchdogReboot

ウォッチドッグタイマーによって、システムを再起動します

3.7. RTC ライブラリ

RTC (Real-Time Clock) ライブラリは、Spresense の RTC 絶対時刻を管理します。 Spresense がもつ RTC ハードウェアは 初期値 0 からはじまる単調増加カウンタです。 RTC は UNIX 時刻で管理されるため、初期値 0 は 1970年1月1日午前0時0分0秒を表します。 Deep Sleep や Cold Sleep といったスリープ期間中も時刻を保持し続けることができます。 ただし、電源がオフされると、RTC カウンタはリセットされ初期値 0 に戻ります。

RTCライブラリを使用する場合は、初めに必ずRTC.begin()を呼び出してください。 電源が供給されてから、RTC XTALが安定して発振するまでに約2秒かかります。 RTC.begin() の中で、この発振安定待ちを行いますので、 RTC.begin() の呼び出しから戻ってきた後で、RTC 機能を安全に使用することができます。

RTC ライブラリは、以下の機能を提供しています。 各種 API の詳細は、API リファレンスマニュアル RTC Library API を参照してください。

  • RTC.setTime() 絶対時刻を設定

  • RTC.getTime() 絶対時刻を取得

  • RTC.attachAlarm() アラームハンドラを登録

  • RTC.detachAlarm() アラームハンドラを解除

  • RTC.setAlarm() アラーム時刻を設定

  • RTC.setAlarmSeconds() 指定時間(秒数)の相対時刻アラームを設定

  • RTC.cancelAlarm() アラーム設定をキャンセル

RTC ライブラリの基本的な使い方は、examples にあるサンプルスケッチをご覧ください。 サンプルスケッチは、Arduino IDE メニューの ファイル → スケッチ例 → Spresense 用のスケッチ例 RTC から開くことができます。

その他、RTC ライブラリとは別に #include <time.h> をインクルードすることで、 strftime() や clock_gettime(CLOCK_REALTIME, tp) のような POSIX 標準の API もサポートされています。

詳細はNuttX User’s Manualを参照してください。 なお、NuttX Configurationにて Local time 機能は無効化されているため、localtime() はサポートされておりません。

3.8. SDHCI ライブラリ

SDHCI ライブラリは Spresense 拡張ボードにある micro SD にアクセスするためのライブラリです。

SDHCI ライブラリは、Arduino SD ライブラリ に類似した API 構成となっており、SD ライブラリを用いた既存のスケッチから簡単に移植することができます。

SPI インターフェースを用いた SD ライブラリとは異なり、SD Host Controller Interface の専用ハードウェアを用いて、SD カードへアクセスするため、次のような特徴をもちます。

  • SD カードは専用端子で接続されるため、SPI 端子を必要としません。SPI 端子を他の用途で使用することができます。

  • SPI 通信と比べて非常に高速です。SDR25 転送モードまでサポートしています。

また、特徴的な機能として、USB MSC (Mass Storage Class) 機能を提供します。 Spresense 拡張ボードにある USB と PC を接続すると、PC から SD カード上のファイルを直接操作することができます。

SDHCI ライブラリには、2つのスケッチのサンプルが提供されています。

  • UsbMsc.ino は、USB MSC 機能のサンプルです。このスケッチを動かすと、Spresense 拡張ボードの SD カードが PC 上のドライブとしてマウントされ、PC から SD カードに直接アクセスすることができるようになります。

  • UsbMscAndFileOperation.ino は、USB MSC 機能とファイル操作を組み合わせた複合アプリケーションになります。SD カード中のファイルに対して、アプリケーションプログラムからのファイル操作と、USB MSC による PC からのファイル操作は排他的に動作させる必要があり、同時に使用することはできません。このサンプルでは、アプリケーションプログラムからファイル一覧を取得・表示した後に、USB MSC 機能を有効にします。PC から USB MSC 機能を用いて、SD カード中のファイルを操作できるようになります。さらに、USB MSC 機能を終了することにより、再びプログラム中からファイル操作を行います。

3.9. Servo ライブラリ

Servo ライブラリは、Spresense に RCサーボを制御する機能を提供します。

Servo ライブラリは、Arduino で定義されているArduino Servo ライブラリ と同様に扱うことができます。

Spresense は4つの PWM をサポートしており、これらを使って RC サーボを制御することができます。

  • D06 PWM0

  • D05 PWM1

  • D09 PWM2

  • D03 PWM3

多くのサーボは 5V電源を要求し、また多くの電力を要求します。そのため、Spresense 拡張ボードから供給すると、モーターの回転に多くの電力を消費し、本体に電源が十分に供給されない可能性があります。そのため、モーターへの電源は外部電源で供給することを検討してください。

また、Spresense拡張ボードは、IOREFジャンパーで 3.3V もしくは 5V を選択できることも注意してください。ただ、多くのRCサーボは、3.3V も 5V も受け付けることができますが、仕様をよく確認する必要があります。

3.9.1. 制限

  • サーボ機能には PWM が必要です。したがって、Spresense の Servo ライブラリでコントロールできる RC サーボは最大4つになります。

3.10. Software Serial ライブラリ

Spresense Arduino Library は、2つのシリアルポートを有しています。USBコネクタのデバッグシリアルは、 Serial で、DO, D1 ピンは Serial2 に割り当てられています。

SoftwareSerial ライブラリは Spresense のデジタル端子をシリアル端子として使うことができるようになります。最大の転送レートは 250,000bps です。

SoftwareSerial ライブラリは Arduino の SoftwareSerial ライブラリと互換性があり、そのまま使うことができます。

3.10.1. 制限

  • 最大転送レートは、250,000bps

  • 使用できる GPIO ピンは (D0 - D28) です。 TX はどのピンでも使えますが、RX はいくつかの制限があります。TXは次のピンから 6 pins を選択できます: 0, 1, 10, 11, 12, 13, 16, 17, 18, 19, 20, 21, 23, 24, 25, 26, 27, 28、その時 RX は次のピンから 6 pins を選択できます: 2, 3, 4, 5, 6, 7, 8, 9, 14, 15, 22.

3.11. SPI ライブラリ

Spresense SPI ライブラリは Spresense に各種 SPI インターフェースを備えたスレーブデバイスを接続するための標準インターフェースを提供します。 Spresense SPI ライブラリは、Arduino SPI ライブラリ と互換性をもち同様に使うことができます。

Spresense ボードは、メインボードと拡張ボードのそれぞれに独立した SPI インターフェースを有しています。

各SPIインターフェースの端子を以下に示します。

表 5. SPI インターフェース端子
SPI インスタンス名 コネクタ MOSI MISO SCK SS IO電圧

SPI (or SPI4)

拡張ボード

D11

D12

D13

D10

3.3V or 5V (JP1ジャンパーにより切替)

SPI5

メインボード

D16

D17

D23

D24

1.8V

SPI というインスタンス名を使用した場合、拡張ボード上の SPI インターフェースが使われます。 メインボード上の SPI インターフェースを使う場合は、例えば、SPI5.beginTransaction() のように、 インスタンス名を SPI5 に置き換えて使用してください。

3.11.1. 機能と制限

  • Spresense SPI ライブラリは 8bit ならびに 16bit データ長の転送をサポートしています

  • SPI SS は自動的に個々のトランザクションを開始するときに LOW に落ちます。トランザクションが終了すると HIGH になります。これは高速転送のときに非常に便利な機能です。もし、この機能が検討しているアプリケーションにそぐわない場合は、他のデジタル端子を SS に割り当てて、digitalWrite() 関数で HIGH/LOW 制御することを検討してください

  • 16 bit data は Little Endian で転送されます

  • 最大転送スピードについては、ハードウェアドキュメント SPIの使用方法 を参照してください。

  • SPI ライブラリのサンプルについては、Arduino IDE から ファイル → スケッチ例 → Spresense 用のスケッチ例 → SPI を参照してください。

3.12. Wire ライブラリ

Spresense Wire ライブラリは、Spresense で I2C / TWI デバイスと通信することができます。I2C は多くのセンサーデバイスで採用されている通信インターフェースです。

Spresense Wire ライブラリは、Arduino Wire ライブラリ と同じ様に使用することができます。

Spresense メインボード/拡張ボードのピン配置を以下に示します。IO電圧は、メインボードでは 1.8V、拡張ボードでは 3.3V もしくは 5.0Vになります。拡張ボードとメインボードで同じピンを使っていますので、使用の際は注意してください。

  • D15 I2C_SCL Clock line

  • D14 I2C_SDA Data line

注意:拡張ボードのピンの物理配置は Arudino Uno と同じですが、I2Cのピン番号の配置が異なります。したがって、Arduino Uno 向けのスケッチを流用する場合は変更が必要になります。

拡張ボードのIO電圧は IOREF ジャンパーによって変更することができます。I2C のIO電圧もIOREF ジャンパーによって変更されます。

メインボード上のピンソケットからも I2C を利用できますが、IOREF に関係なく、IO電圧は1.8V固定です。

I2C 通信には通常プルアップレジスタが必要ですが、拡張ボードとメインボードでは必要ありません。

  • Spresense 拡張ボードは、1kΩのプルアップ抵抗がついていますので追加のコンポーネントは不要です。

  • Spresense メインボードは、4.7kΩのプルアップ抵抗が内蔵されていますので追加のコンポーネントは不要です。

3.12.1. 機能と制限

通信速度は3種類定義されています。起動時に選択します。

  • #define TWI_FREQ_100KHZ (100000) // standard mode

  • #define TWI_FREQ_400KHZ (400000) // fast mode

  • #define TWI_FREQ_1MHZ (1000000) // fast mode plus

デフォルトの通信速度は 100kHz です。

ライブラリは、二つの I2C アドレス長をサポートしています。

  • #define TWI_ADDR_LEN_7_BIT (7)

  • #define TWI_ADDR_LEN_10_BIT (10)

デフォルトのアドレス長は、7 bit です。

オリジナルの Arduino Wire ライブラリと同じ様に、Spresense Wire ライブラリも 32 byte buffer です。したがって、デバイスとの通信データはその範囲内に収める必要があります。それを超えるデータを受信した場合、超過分のデータは捨てられます。

3.13. Watchdog ライブラリ

Spresense Watchdog ライブラリは Spresense の システム状態を監視し、異常時にHW リセットをするための Hardware watchdog 機能を提供します。

このライブラリによって以下の機能をアプリケーションから使う事ができます。

  • HW リセットを実行するまでの時間を設定する

  • リセットまでの時間を取得する

  • リセットまでの時間をリセットする

例えば”10秒以内に loop() を抜けなければならないのにそれを経過してしまったらリセットするようにしたい”場合に使うことができます。

3.13.1. 使い方

このライブラリは以下の手順で使うことができます。また、 WatchdogClass のインスタンス Watchdog を使います。

  1. Watchdog.begin() でWatchdogを初期化する

  2. Watchdog.start(time) で監視を開始する

    time にリセットするまでの時間(ms)をセットします。 その時間を経過するとHW リセットが発生します。 time は最大40秒を設定できます

  3. Watchdog.kick() でリセットまでの時間をリセットする

    プログラムが正常に動作している場合はそれを通知してリセット時間をリセットします。

  4. Watchdogで監視する必要がなくなったら Watchdog.stop() を実行する

    Watchdog.stop() 及び Watchdog.kick() せずに所定時間が経過すると、HWリセットが発生してしまいます。

必要に応じて、HWリセットが発生するまでの時間を Watchdog.timeleft() で確認してください。

diag 19f5857c5fd9a3e66f5543fac9881375

3.13.2. サンプル

このライブラリのサンプルスケッチは、Arduino IDE上で ファイル > スケッチ例 > Watchdog > Watchdog_bite にあります。

4. Spresense Arduino Library 付録

4.1. Spresense Arduino board package のマニュアルインストール

Spresense Arduino board package をマニュアルでインストールした場合、ボードマネージャを使ったインストールに失敗することがあります。その場合は Spresense Arduino board packageのインストールに失敗する を参照しインストールを実施してください。

4.1.1. Windows版 Spresense Arduino Library のインストール

このチュートリアルでは、WinZip を使用していますが、Windows エクスプローラーメニューの"すべて展開(T)"も同様に利用できます。
  1. Arduino IDE のインストールフォルダを開きます。

    %userprofile%/AppData/Local/Arduino15

  2. ダウンロードしたファイル (manual-install-spresense-arduino-windows-latest.zip) を %userprofile%/AppData/Local/Arduino15 へドラッグします。ZIP ファイルを右クリックでメニューを開き Extract > Extract to here を選択してその場に展開します。

    tutorial arduino extract into arduino15
    図 13. Arduino15フォルダーへ Spresense Arduino board package を展開

    これで、ボードパッケージはインストールされています。

4.1.2. Linux版 Spresense Arduino Library のインストール

このチュートリアルは、64bit版 Ubuntu であり、 manual-install-spresense-arduino-linux-latest.zip が ~/Downloads へダウンロードされていることが前提となっています。

  1. Arduino IDE をインストールします。

    Arduino IDE を起動します。

    Arduino IDE を終了します。

    この一連の操作によって、Spresense Arduino board package をインストールするためのフォルダが生成されます。 ~/.arduino15/ が存在していることを確認してください。

  2. ターミナルを開いて、 manual-install-spresense-arduino-linux-latest.zip がダウンロードされているフォルダへ移動してください。

    zipファイルを解凍し、 ~/.arduino15/ 以下へコピーします。

    $ cd ~/Downloads
    $ unzip manual-install-spresense-arduino-linux-latest.zip
    $ rm -rf ~/.arduino15/packages/SPRESENSE
    $ cp -rfv ~/Downloads/Arduino15/* ~/.arduino15/
    $ rm -rf ~/Downloads/Arduino15
  3. これでボードパッケージはインストールされました。

4.1.3. Mac OSX版 Spresense Arduino Library のインストール

このチュートリアルはオペレーティングシステムが Mac OSX であり、 manual-install-spresense-arduino-macosx-latest.zip が ~/Downloads へダウンロードされていることが前提となっています。

  1. Arduino IDE を Mac OSX へインストールします。

    Arduino IDE を起動します。

    Arduino IDE を終了します。

    この一連の操作によって、Spresense Arduino board package をインストールするためのフォルダが生成されます。 ~/Library/Arduino15 が存在していることを確認してください。

  2. ターミナルを開いて、 manual-install-spresense-arduino-macosx-latest.zip がダウンロードされているフォルダへ移動してください。

    ~/Library/Arduino15 を解凍します。

    $ cd ~/Downloads
    $ unzip manual-install-spresense-arduino-macosx-latest.zip -d ~/Library/Arduino15
  3. これでボードパッケージはインストールされました。