前回はこちら
この記事はソニー製SPRESENSEの消費電力について実機測定した結果をまとめたものです(N数=1)
メインボード + Cameraでの消費電力
条件(前回と同じ)
- USBではなくバッテリー供給口の方から5Vを入力
- メインボードのLEDは除去したものしかなかったので、それを使用(大体200μAくらい節電だった気がする)
- n数は1。端末依存って言われたらそれまでだけど、仕事柄数十台のSPRESENSEを扱っているので大体同じ感じな印象
結果だけ知りたい人向け
- カメラを付けただけなら、カメラ非搭載時と消費電力は変わらず
- idle : 8mA
- coldSleep : 1.3mA
- deepSleep : 50μA
- 1枚撮影後
- idle : 85mA
- coldSleep : 7mA
- deepSleep : 50μA
- CallBackによるストリーミング取得
- idle:65mA
ただ単純に接続しただけの場合
1. idle状態
2. coldsleep
3. deepsleep
前回の非カメラ接続時と比較しても、誤差の範囲内ですね。
他のマイコンだとカメラを起動せずに接続しただけで1~2mA程度増えることもあるので、非常に優秀。
カメラを起動して1枚撮影を実施した場合
1. 撮影後、idle状態
検証ソース
#include <Camera.h>
#define BAUDRATE (115200)
void printError(enum CamErr err)
{
Serial.print("Error: ");
switch (err){
case CAM_ERR_NO_DEVICE:
Serial.println("No Device");
break;
case CAM_ERR_ILLEGAL_DEVERR:
Serial.println("Illegal device error");
break;
case CAM_ERR_ALREADY_INITIALIZED:
Serial.println("Already initialized");
break;
case CAM_ERR_NOT_INITIALIZED:
Serial.println("Not initialized");
break;
case CAM_ERR_NOT_STILL_INITIALIZED:
Serial.println("Still picture not initialized");
break;
case CAM_ERR_CANT_CREATE_THREAD:
Serial.println("Failed to create thread");
break;
case CAM_ERR_INVALID_PARAM:
Serial.println("Invalid parameter");
break;
case CAM_ERR_NO_MEMORY:
Serial.println("No memory");
break;
case CAM_ERR_USR_INUSED:
Serial.println("Buffer already in use");
break;
case CAM_ERR_NOT_PERMITTED:
Serial.println("Operation not permitted");
break;
default:
break;
}
}
void setup()
{
CamErr err;
Serial.begin(BAUDRATE);
while (!Serial){
; /* wait for serial port to connect. Needed for native USB port only */
}
Serial.println("Prepare camera");
err = theCamera.begin();
if (err != CAM_ERR_SUCCESS){
printError(err);
}
Serial.println("Start streaming");
Serial.println("Set Auto white balance parameter");
err = theCamera.setAutoWhiteBalanceMode(CAM_WHITE_BALANCE_DAYLIGHT);
if (err != CAM_ERR_SUCCESS){
printError(err);
}
Serial.println("Set still picture format");
err = theCamera.setStillPictureImageFormat(
CAM_IMGSIZE_QUADVGA_H,
CAM_IMGSIZE_QUADVGA_V,
CAM_IMAGE_PIX_FMT_JPG);
if (err != CAM_ERR_SUCCESS){
printError(err);
}
}
void loop()
{
sleep(1);
Serial.println("call takePicture()");
CamImage img = theCamera.takePicture();
if (img.isAvailable()){
Serial.print("Image data size = ");
Serial.print(img.getImgSize(), DEC);
while(true){
;
}
}
else{
Serial.println("Failed to take picture");
}
}
カメラを起動すると当然ながら消費電力はいっきに100mA程度まで跳ね上がります。
分平均を見ると85mA
となっているので、やはり撮影後そのまま何かしらの処理を行うとロスが大きそうです。
2. 撮影後、coldSleep
検証ソース
#include <Camera.h>
#include <LowPower.h>
#define BAUDRATE (115200)
void printError(enum CamErr err)
{
Serial.print("Error: ");
switch (err){
case CAM_ERR_NO_DEVICE:
Serial.println("No Device");
break;
case CAM_ERR_ILLEGAL_DEVERR:
Serial.println("Illegal device error");
break;
case CAM_ERR_ALREADY_INITIALIZED:
Serial.println("Already initialized");
break;
case CAM_ERR_NOT_INITIALIZED:
Serial.println("Not initialized");
break;
case CAM_ERR_NOT_STILL_INITIALIZED:
Serial.println("Still picture not initialized");
break;
case CAM_ERR_CANT_CREATE_THREAD:
Serial.println("Failed to create thread");
break;
case CAM_ERR_INVALID_PARAM:
Serial.println("Invalid parameter");
break;
case CAM_ERR_NO_MEMORY:
Serial.println("No memory");
break;
case CAM_ERR_USR_INUSED:
Serial.println("Buffer already in use");
break;
case CAM_ERR_NOT_PERMITTED:
Serial.println("Operation not permitted");
break;
default:
break;
}
}
void setup()
{
CamErr err;
Serial.begin(BAUDRATE);
while (!Serial){
; /* wait for serial port to connect. Needed for native USB port only */
}
LowPower.begin();
Serial.println("Prepare camera");
err = theCamera.begin();
if (err != CAM_ERR_SUCCESS){
printError(err);
}
Serial.println("Start streaming");
Serial.println("Set Auto white balance parameter");
err = theCamera.setAutoWhiteBalanceMode(CAM_WHITE_BALANCE_DAYLIGHT);
if (err != CAM_ERR_SUCCESS){
printError(err);
}
Serial.println("Set still picture format");
err = theCamera.setStillPictureImageFormat(
CAM_IMGSIZE_QUADVGA_H,
CAM_IMGSIZE_QUADVGA_V,
CAM_IMAGE_PIX_FMT_JPG);
if (err != CAM_ERR_SUCCESS){
printError(err);
}
}
void loop()
{
sleep(1);
Serial.println("call takePicture()");
CamImage img = theCamera.takePicture();
if (img.isAvailable()){
Serial.print("Image data size = ");
Serial.print(img.getImgSize(), DEC);
while(true){
LowPower.deepSleep(70);
}
}
else{
Serial.println("Failed to take picture");
}
}
分平均を見ると6.54mA
と、無負荷時の1.4mA
からはだいぶ増えています。
この状態ですと乾電池などで動くIoT端末としては無視できない電力消費かと思います。
2. 撮影後、deepSleep
本命のdeepSleepですが、分平均は無負荷時と同じ47μA
と、かなりいい線いっています!
これならIoT端末にも使えそうですね!
※とはいっても、私が扱うLPWA系だと処理の関係上deepSleep不可とかいう制約もあったりするので、実はあんまり喜べなかったり・・・・・・
カメラを起動してストリーミング撮影を実施した場合
ストリーミング中
最後にcallBack関数を使用して裏で取得し続けた場合です。サンプルプログラムもこのタイプですね。
結果としては1枚撮影後idleの状態よりも消費電力は少なくなりました。誤差の範囲、というには20mAもあるので無視できない結果です。
このあたりcallBackとtakePicture()
の処理がもしかしたら何か関係しているかもしれないですね。
いかがだったでしょうか。
ぶっちゃけ私はcoldSleepでカメラを使っているので、思ったより省エネになっていないじゃん、と愕然としてます(焦)
次回は拡張ボードかESP32S3の電力調査をお届けする予定です。
ESP32S3は最近手に入れたXIAO ESP32S3 (sense)で計測したものとなります。
まぁ今扱っているからわかるんですが、とにかくカメラ回りが酷いのなんの(笑)
フォーラムでも結構ひどい言われ様だったりするのですが、しかしAIが搭載できたりSDカードよりも小さいといったメリットはどうにかデメリットを上回りそうです(笑)
でわでわ、良いマイコンライフを!