SPRESENSEでデータを収集し、表示する


図

IoTシステムには画像認識や音声解析など、「データ」を収集し解析する機能が求められています。データには、カメラから採取した「画像データ」やマイクから収録した「音声データ」などがあります。こうしたデータを活用することにより、インタラクティブなシステムを実現することができます。近年は、こうしたデータの解析にマルチコアを活用、並列化することにより、優れたレスポンス性を達成する製品も増えています。

今回の初心者講座では、どのように処理するか・並列化していくかを学ぶ前段階として、どのようなデータを(What)、どのようにして(How)どこに収集すべきか(Where)を解説いたします。今回の内容を学習することで、IoTシステムの要となる「画像データ」や「音声データ」といったマルチメディアデータの取り扱い方法への理解も深まるでしょう。

図

▼目次

マルチコアで処理する「データ」を準備しよう

それでは、マルチコア・アーキテクチャにてCPUコアが処理する「データ」ついて考えてみましょう。システムを構成するプログラムは「入力データ」を、決められたルールに従って解析・加工し「出力データ」を生成します(図1)。

入力データ

記録媒体(SDカードなど)に記録された情報をはじめ、センサーによって収集された時系列データ(音声データも含む)、カメラによって撮影された画像データ、他のプログラムにより加工されたデータなどがあります。

出力データ

記録媒体に保存するファイルのデータをはじめ、LCDディスプレイに表示するための画像データ、ネットワークへ送り出すパケットデータ、他の関数へ渡すための中間データ(加工中のデータ)などがあります。

図
図1:入力データと出力データの関係

プログラムの処理対象となるデータはメモリに格納される

CPUコアは、プログラムを読み解き、全ての演算をCPUコア内部のレジスタにて行います。レジスタに無い情報(画像データの特定箇所、など)が必要な場合は、CPUコアはメモリ(メインメモリ、RAM)からレジスタへデータを複製します。同様に、処理が完了したデータは、CPUがレジスタからメモリへ書き戻します。これはシングルコア/マルチコア・アーキテクチャ共通の動作です。

データをメモリ上に展開する方法

メモリにも無いデータ(未録音/未撮影のデータ)が必要な場合、CPUはデバイスドライバを実行し「ペリフェラル(周辺回路)」を制御、外部のハードウェアに撮影・録音させ、新しいデータをメモリへ追加させます。出力が確定したデータ(LCD用の全ピクセル情報など)も同様に、CPUがデバイスドライバを実行し、メモリの内容をペリフェラルの機器へ出力します(図2)。

そのため「マルチコア・プログラミングを学びたい」「マルチコアを活用した高度でスマートなIoTシステムを開発したい」といった場合、処理したい画像データや音声データを、どのようにしてメモリへ取得するのか/メモリから出力するのかを把握しておくことが大切です。一例を挙げると「void board_gpio_write(uint32_t pin, int value);にピン番号と設定値を付けて実行すれば、関数の内部でGPIOデバイスドライバが実行され、外部へ情報を出力できる」といった理解です。

図
図2:CPUコアで処理したいデータはすべてメモリ上に格納する

バス・アービトレーション

ところで、デバイスドライバはマルチコアにより並列実行できるのでしょうか。次の内容は「正確ではない」理解です

×「マルチコア・アーキテクチャなので、6コアで同時にデバイスドライバを実行すれば、6倍高速にデータを収集できる」

CPU、メモリ、ペリフェラルはすべて「バス」と呼ばれる通信路で結合されています。そのため、すべてのコアがペリフェラルへアクセスした場合、ペリフェラルへアクセス権利を奪い合う、バスのアービトレーション(調停)が多発します。高速化に挑戦しているものの、いまいち性能が向上しない場合、こうしたハードウェアの影響であることもあります。

Spresense SDKの概要|Spresense SDK 開発ガイド

一例としてASMPアーキテクチャで高速化する場合、以下のように処理を各コアに専任させることで、並列化による効果を高めることができます。

○「ASMPの特徴を活かして、メインコアはデバイスドライバで情報を集める。メインコアが集めた情報はサブコアが分散処理し、スループットを向上させる」

デバッガを活用し、処理する対象のデータを確認する

実際に画像データや音声データを収集・解析・出力するプログラムを開発する場合、初期段階でデータの収集やデータの出力を制御するプログラムに不備がないかを、デバッガで確認することにより「ペリフェラルの問題」なのか「解析処理の実装ミス」なのかを切り分け易くなります。

Spresense SDK、ICEデバッガ、Visual Studio Codeを連携されたデバッグ環境を図3に示します。デバッガを使うことにより、プログラム実行中の任意の場所でシステムを一時停止し、デバイスの内容を覗くことができます。例えば、カメラのデバイスドライバにどのような設定をしているか、カメラのデバイスドライバからエラーが出力されていないか、指定したデータ格納アドレスの内容が更新されているか、といった情報を手元で確認することができます(図4)。是非ご活用ください。

実行の様子は本ページ後半に動画にて掲載しています。

図
図3:ICEデバッガを使うことにより、処理対象のデータを確認できる

図
図4:Visual Studio Code + Spresense SDKでデータを可視化する(画面左にメモリやレジスタに格納されているデータが表示されている)

サンプルアプリケーションで学ぶ、データの収集・記録・表示方法

それでは、データの収集・記録・表示方法を、ASMPアーキテクチャであるSPRESENSE上で動作するサンプルアプリケーションを活用して学びましょう。なお、本動画では簡単なはんだ付けのみで、カメラ、LCD、マイク、GPIOを配線ミス無く利用できる「APS学習用ボード」を利用しています。お試しの際は、是非ご活用ください。

図

カメラから画像データを収集、画像データをLCDへ出力する

ここでは、画像データの収集方法と出力方法を、SPRESENSEのサンプルアプリケーション「examples/camera」を使って紹介します。cameraアプリケーションは、カメラを制御し、撮影した画像データをメモリ上に格納します。カメラからの画像データはYUV形式です。画像データはCPUによりLCD用のRGB形式のデータへと変換、LCDデバイスドライバのSPI通信によってLCDへ出力されます。本例ではLCDに「ILI9341」の2.2inch版を利用しています(APS学習ボード搭載のコネクタに接続することができます)。

本サンプルアプリケーションは、YUV形式からRGB形式への変換をメインコアで処理しています。マルチコアを活用し、変換処理を並列化することにより秒間あたりの処理枚数(fps:frames per second)を向上させることができます(今後の初心者講座にて紹介予定です)。

フレームレート|Wikipedia

参考となる開発資料

実行手順

事前準備

Spresense SDKをインストールします。こちらの手順をお手元のPCで実施ください。

入出力制御アプリケーションのインストール

※ SPRESENSEのシリアルポートがCOM4として認識している場合

$ cd ~/
$ cd spresense/sdk/
$ tools/config.py --kernel release
$ tools/config.py examples/camera
$ make menuconfig
[CXD56xx Configuration]
  [SPI] <= 'Y'
[Drivers]
  [LCD Drivers] <= 'Y'
	[ILI9340 LCD Single Chip Driver] <= 'Y'
	  [Number of supported display driver] <= '1'
	  [(1) LCD Display] <= 'Y'
[Video Support]
  [Video Support] <= 'Y'	
[Examples]
  [Camera example] <= 'Y'
    [Output LCD] <= 'Y'
$ make buildkernel
$ make
$ ls ./nuttx.spk
$ tools/flash.sh -c COM4 nuttx.spk
SPRESENSEでの操作(TeraTerm)
nsh> camera
# 1秒間隔で、カメラから画像データを取得
# 画像データをSDカードに保存
# 画像データをRGBに変換しLCDへ表示

マイクから音声データを収集する

次に、音声データの収集方法と出力方法を、SPRESENSEのサンプルアプリケーション「examples/audio_recorder」を使って紹介します。audio_recorderアプリケーションは、Spresenseに搭載されたオーディオ機能を制御し、アナログマイクで録音(APS学習ボードの場合)、音声データをメモリへ転送。メモリに格納された音声データをSPRESENSE Extension Board上のmicro SDカードにWAV形式として保存します。

WAV|Wikipedia

音声データは、産業用の異常検知システムをはじめ、多くのコンシューマー向けのIoT製品など、様々な分野に活用されています。例えば、人間の会話に反応できるロボットでは、音声データをDNN(Deep-Neural-Network)により解析、コマンド文字列(ASCII)へと変換し、次の動きを決定しています。ユーザーフレンドリーなインタフェースに欠かせないデータです。

参考となる開発資料

実行手順

事前準備

Spresense SDKをインストールします。こちらの手順をお手元のPCで実施ください。

入出力制御アプリケーションのインストール

※ SPRESENSEのシリアルポートがCOM4として認識している場合

$ cd ~/
$ cd spresense/sdk/
$ tools/config.py --kernel release
$ tools/config.py examples/audio_recorder
$ make buildkernel
$ make
$ ls ./nuttx.spk
$ tools/flash.sh -c COM4 nuttx.spk
SPRESENSEでの操作(TeraTerm)
nsh> audio_recorder
# マイクから録音し、データをSDカードに保存

入力ピンの状態を取得、出力ピンの状態を設定する

続いて、入力ピン・出力ピンの制御方法をSPRESENSEに同梱されているシステムツール「GPIO command」を例にご紹介します。本動画で採り上げている「APS学習ボード」には、外部からの操作を入力するためのプッシュスイッチ2個(GPIO readで状態を取得)と、Spresenseの内部状態を出力できるLED2個(GPIO writeで制御)が搭載されています(図5)。

図
図5:APS学習ボードに接続されている入力ピンと出力ピン(GPIO)

マイコン(マイクロコントローラ)の出力ピンと言えばLEDの点滅を想像しがちですが、実際はON/OFF制御の要であるため、高い汎用性を備えています。例えば、ソリッドステートリレーを接続することで100V家電のON/OFF制御が可能ですし、ヒーターや冷却システムの出力を制御することも可能です。

入力ピンも同様に、プッシュスイッチだけでなく、照度センサーで明るさの閾値判定結果を取得することをはじめ、立ち入り禁止エリアに人が入っているかどうかをラインセンサーから判定することや、クラウドからのイベントをトリガーにローカル処理を開始することなど、幅広い用途に活用いただけます。

参考となる開発資料

実行手順

事前準備

Spresense SDKをインストールします。こちらの手順をお手元のPCで実施ください。

入出力制御アプリケーションのインストール

※ SPRESENSEのシリアルポートがCOM4として認識している場合

$ cd ~/
$ cd spresense/sdk/
$ tools/config.py --kernel release
$ tools/config.py examples/hello
$ make menuconfig
[System tools]
  [GPIO Command] <= 'Y'
  [GPIO Inturrput Command] <= 'Y'
$ make buildkernel
$ make
$ ls ./nuttx.spk
$ tools/flash.sh -c COM4 nuttx.spk
SPRESENSEでの操作(TeraTerm)
nsh> gpio stat
# 全てのピン情報を出力

nsh> gpio stat 39
nsh> gpio conf 39 -m 0 -i
nsh> gpio read 39
# APS学習ボード プッシュスイッチ(左) の制御

nsh> gpio stat 29
nsh> gpio conf 29 -m 0 -i
nsh> gpio read 29
# APS学習ボード プッシュスイッチ(右) の制御

nsh> gpio stat 47
nsh> gpio write 47 1
nsh> gpio write 47 0
# APS学習ボード LED(左:緑色) の制御

nsh> gpio stat 46
nsh> gpio write 46 1
nsh> gpio write 46 0
# APS学習ボード LED(右:橙色) の制御

Visual Studio Codeを活用し、データの動きを可視化する

最後に、Spresense SDKとVisual Studio Codeを活用し、サンプルアプリケーションが扱っているデータを可視化してみましょう。ツールの設定方法は下記をご参照ください。

 Spresense SDK スタートガイド (IDE 版)|Sony Developer World

Visual Studio Codeでcameraアプリケーションを解析する

本動画では、Spresense SDKに同梱されている「examples/camera」がどのようにデータを扱っているのかを解析する方法を紹介しています。cameraアプリケーションは1秒毎にカメラを制御し、カメラの情報をメモリ上へ収集、収集したデータをYUV形式からRGB形式へと変換、LCDへ出力するプログラムです。デバッガを使うことにより、プログラムの任意の地点で「どのようなデータが交換され、処理されたのか」を可視化できます。

今後、カメラを使ったIoTアプリケーションを開発したい方に、最適な教材です。また、GPIO Commandなど他のペリフェラルを制御するプログラムも解析することができます。併せてお試しください。

実行手順

ICEデバッガの準備

本動画で利用しているNXP LPC-Link2のセットアップ方法は下記をご参照ください。

第3回:ICEデバッガの準備:NXP LPC-Link2

拡張機能をインストールする
  • Japanese Language Packをインストールする
  • Spresense 拡張機能をインストールする
    ※C/C++拡張機能、Cortex Debug機能が自動的に追加されます
サンプルのビルド方法を設定する
  • spresenseのフォルダを開く
  • ターミナルを開く
  • Spresense MSYS2パスの設定
  • Spresense カーネルコンフィグ
  • Spresense SDKコンフィグ
    • Examples - Cameraを選択
    • Drivers - LCD Drivers - LCDを有効化
    • LCD Drivers - ILI9340を有効化
    • Number of supported display driver - 1を設定
    • Examples - Camera - Output LCDを有効化
    • CXD56xx Configuration - SPIを有効化
ビルドし、デバイスへ書き込む
  • カーネルのビルド
  • アプリケーションのビルド
  • PCとSpresense間にICEデバッガを接続
  • ブートローダの書き込み(初回実行時のみ)
  • ビルドと書き込み
プログラムを実行する
  • 通常実行(※開始済)
  • デバッグ実行
    • ブレークポイントを設定
    • デバッグウィンドウを開く
    • デバッグ実行を開始
    • (以降デバッグ作業)

まとめ

マルチコア・プログラミングを理解するためには、処理する「プログラム」を検討・設計・実装することはもちろん、処理対象となる「データ」の流れを把握することが重要です。今回は、マルチコア・プログラミングが処理する対象「データ」について、その流れと、Spresense上に画像データや音声データを収集する方法、画像データを出力する方法を解説しました。次回は「プログラム」の動きをデバッガを使って紹介いたします。

是非、ご期待ください!

補足:Windows環境でウィルス対策ソフトが動作した場合

Windows上でSpresense SDKを実行した際、一部の条件において「Spresense SDKを構成する一部のファイルがウィルス(脅威)と判定」され、Windowsによって自動的に検疫(削除)され「ファイルが見つからない」旨を意味するエラーが発生することがあります(図6)。回復させる場合は、Windowsの「ウィルスと驚異の防止」設定から検疫されたファイルを確認し、復元ボタンをクリックしてください(図7)。

Windows Defender AV で検疫済みのファイルを復元する

図
図6:Spresense SDKの一部がWindowsによりウィルス(脅威)として判定され、検疫された場合に表示されるエラーの例(No such file ot directory)

図
図7:Spresense SDKがWindowsのウィルス対策機能に阻害された場合の対処方法