LoginSignup
1
0

今更ながらSPRESENSEの消費電力調べてみた②

Posted at

前回はこちら

この記事はソニー製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状態

  • 電源投入直後
    メイン_カメラidle_1.png

  • 1分間平均
    メイン_カメラidle_2.png

2. coldsleep

  • 電源投入直後
    メイン_カメラcoldS_1.png

  • 1分間平均
    メイン_カメラcoldS_2.png

  • 検証ソースは前回と同じ

3. deepsleep

  • 電源投入直後
    メイン_カメラdeepS_1.png

  • 1分間平均
    メイン_カメラdeepS_2.png

  • 検証ソースは前回と同じ

前回の非カメラ接続時と比較しても、誤差の範囲内ですね。
他のマイコンだとカメラを起動せずに接続しただけで1~2mA程度増えることもあるので、非常に優秀。

カメラを起動して1枚撮影を実施した場合

1. 撮影後、idle状態

  • 電源投入直後
    メイン_カメラ_撮影_idle_1.png

  • 1分間平均
    メイン_カメラ_撮影_idle_2.png

  • カメラ起動時
    メイン_カメラ_撮影_idle_3.png

検証ソース
#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

  • 電源投入直後
    メイン_カメラ_撮影_coldS_1.png

  • 1分間平均
    メイン_カメラ_撮影_coldS_2.png

  • カメラ起動時
    メイン_カメラ_撮影_coldS_3.png

検証ソース
#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

  • 電源投入直後
    メイン_カメラ_撮影_deepS_1.png

  • 1分間平均
    メイン_カメラ_撮影_deepS_2.png

  • カメラ起動時
    メイン_カメラ_撮影_deepS_3.png

  • 検証ソース

    • coldSleepをdeepSleepにしただけ

本命のdeepSleepですが、分平均は無負荷時と同じ47μAと、かなりいい線いっています!
これならIoT端末にも使えそうですね!
※とはいっても、私が扱うLPWA系だと処理の関係上deepSleep不可とかいう制約もあったりするので、実はあんまり喜べなかったり・・・・・・

カメラを起動してストリーミング撮影を実施した場合

ストリーミング中

  • 電源投入直後
    メイン_カメラ_撮影_streaming_1.png

  • 1分間平均
    メイン_カメラ_撮影_streaming_2.png

最後にcallBack関数を使用して裏で取得し続けた場合です。サンプルプログラムもこのタイプですね。
結果としては1枚撮影後idleの状態よりも消費電力は少なくなりました。誤差の範囲、というには20mAもあるので無視できない結果です。
このあたりcallBackとtakePicture()の処理がもしかしたら何か関係しているかもしれないですね。

いかがだったでしょうか。
ぶっちゃけ私はcoldSleepでカメラを使っているので、思ったより省エネになっていないじゃん、と愕然としてます(焦)

次回は拡張ボードかESP32S3の電力調査をお届けする予定です。
ESP32S3は最近手に入れたXIAO ESP32S3 (sense)で計測したものとなります。

まぁ今扱っているからわかるんですが、とにかくカメラ回りが酷いのなんの(笑)
フォーラムでも結構ひどい言われ様だったりするのですが、しかしAIが搭載できたりSDカードよりも小さいといったメリットはどうにかデメリットを上回りそうです(笑)

でわでわ、良いマイコンライフを!

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0