SPRESENSEのカメラとさくらのモノプラットフォームで撮影した画像をアップロードする

さくらインターネットでは、LTE回線とIoTプラットフォームをセットにした 「さくらのモノプラットフォーム」 (以下 "モノプラ") を提供しています。

デバイス向けの[API仕様](https://manual.sakura.ad.jp/cloud/iotpf/device-adapter/dev-ada_access_guide_curl.html)を公開しているため、LTEに接続できるデバイスであれば、モノプラの仕組みを利用できます。

さくらインターネットでは、Nordic の nRF9160 向けの[ライブラリ](https://github.com/sakura-internet/sipf-lib_nrfconnect)とファームウェアを提供しています。

今回はソニーセミコンダクタのT.HayakawaさんにベースとなるSPRESENSE向けのライブラリを作っていただいたので、さくらインターネットのGitHub Organizationで公開しました。

https://github.com/sakura-internet/arduino-sipf-client

今回はこれを使って、SPRESENSEに接続したカメラで撮影した写真をモノプラのファイル送信機能を使ってアップロードする例を示します。

このコードはライブラリ内のサンプル [camera_upload.ino](https://github.com/sakura-internet/arduino-sipf-client/blob/main/examples/mono_platform_sample/camera_upload/camera_upload.ino) として同梱されています。

## 組み立て

**SPRESENSE** と **SPRESENSE LTE拡張ボード** と **SPRESENSE カメラボード** を利用します。

拡張ボードとSPRESENSEは重ねる形で接続し、カメラボードはフラットケーブルで接続します。 (写真ではHDRカメラを接続しています)

![IMG_2675.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/73788/93d13962-60ea-85d0-0595-4c72b3828bbb.jpeg)


## Arduino IDEの準備

Arduino IDEを使ってのSPRESENSEの開発環境のセットアップについては公式の [Spresense Arduino スタートガイド](https://developer.sony.com/develop/spresense/docs/arduino_set_up_ja.html) を参照してください。

また、Arduino IDEのLibrary Managerから、 「sipf-arduino-library」 と 「ArduinoHTTPClient」 をインストールしてください。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/73788/7c37dd8c-df06-8b95-5a16-e1738b9c5925.png)

## サンプルスケッチを開く

メニューから [File]→[Examples]→[sipf-arduino-client]→[mono_platform_sample]→[camera_uplaod] を開いてください。

そのまま書き込み実行すると、周期的に写真を撮り、プラットフォームに画像をアップロードします。
シリアルコンソールに "Upload OK" と出力されていれば、正常にアップロードされています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/73788/7130ac01-b8c1-15bf-7590-b7f299c16a8b.png)


## アップロードされた写真を確認する

モノプラットフォームで扱うファイルは、「プロジェクト」の「ファイル送受信」タブで確認することができます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/73788/13ac5c2c-ff8e-6e44-e2b0-d18f820fe558.png)

`image.jpg` という名前でSPRESENSEからアップロードしたファイルが見えていますので、右のダウンロードボタンを押すとダウンロードできます。

![image (21).jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/73788/712dffac-cc69-d3ae-1148-aa9c23d07139.jpeg)

また、アップロード後に、モノプラットフォームのオブジェクト送信機能を使って、撮影回数をファイル名を送信しているため、WebSocketなどのサービスアダプタで以下のようなJSONを受信することができます。


```json
{
  "id": "e46ec684-b408-4c77-902a-a10f81363984",
  "device_id": "7424",
  "timestamp_src": "1970-01-01T00:00:00.000Z",
  "timestamp_platform_from_src": "2023-06-11T08:04:44.933Z",
  "timestamp_platform_to_dst": "2023-06-11T08:04:45.093Z",
  "type": "object",
  "payload": [
    {
      "type": "uint32",
      "tag": "01",
      "value": 19
    },
    {
      "type": "string.utf8",
      "tag": "02",
      "value": "image.jpg"
    }
  ]
}
```

クラウド側のAPIと組み合わせることで、アップロードされたら何かをする、などの処理を組むことができます。

## 撮影ができない場合 (No memory エラー)

解像度やJPEGの画質を上げた場合、撮影エラー (No memory) になる場合があります。
その場合は

### `setStillPictureImageFormat()` 関数の `jpgbufsize_divisor` 引数をデフォルトの7から6にしてみる。

これによって、JPEG撮影の場合のバッファサイズが増えます。JPEGの画質を高画質にした場合や、複雑な画像を撮影した場合にだけエラーになる症状などはこれによって解決する可能性があります。

### Arduinoメニューの "Tools" → "Memory" を 1536KB にする

それでもメモリが足りない場合には、Arduinoのプログラムが実行されるスレッドに対するメモリ割り当てが少ない可能性があります。
Toolメニューからメモリ割り当てを大きくしてみてください。