katiのアイコン画像
kati 2026年01月10日作成 © MIT
製作品 製作品 閲覧数 24
kati 2026年01月10日作成 © MIT 製作品 製作品 閲覧数 24

見守りシステム

見守りシステム

デモ動画

ここに動画が表示されます

部品

使用するハードウェアを次に示します。

部品名 個数
Spresenseメインボード 1
Spresense拡張ボード 1
Spresense HDRカメラボード 1
ILI9341搭載2.8インチSPI制御タッチパネル付TFT液晶 MSP2807 1 1
温度・湿度・気圧センサ BME280 1

使用するソフトウェアを次に示します。

ソフトウェア名
Arduino IDE

設計図

「見守りシステム」は、一人身の高齢者や、遠く離れて生活している高齢者の親の生活状況を監視し、その結果を液晶に表示し、Wi-Fiを使って(この機能については未実装)介護者や家族のパソコンや携帯のブラウザを通して確認できる、見守り機能を持ちます。

「見守りシステム」は、次に示すハードウェアにより構成されます。

キャプションを入力できます

「見守りシステム」は、次のようにして開発しました。

  • Spresenseメインボード上で動作するプログラムはArduino IDEを使って開発します。
  • 定期的に HDRカメラボードからの画像データや、温度・湿度・気圧センサ BME280 からの温度・湿度データを取得して液晶モジュールに表示します。

接続図

Spresenseメインボードに カメラコネクタによりHDRカメラボード を接続し、Spresenseメインボードと接続したSpresense拡張ボードに、SPIインタフェースを持つ液晶モジュールを次のように接続します。なお、温度・湿度・気圧センサ BME280は、I2Cインタフェースにより温度・湿度データを取得します。

キャプションを入力できます

ハードウェア

液晶モジュールは、背面からSpresense拡張ボードにSPIインタフェースにより接続します。Spresenseメインボードに接続されたHDRカメラボードからの画像データと、温度・湿度・気圧センサ BME280からの温度・湿度データは、定期的に取得して液晶モジュールに表示します。

キャプションを入力できます

ソースコード

プログラム「見守りシステム」のSpresenseメインボード上で動作するコード「 SpresenseContest2025.ino」は、Arduino IDEを使用して開発します。

コード「 SpresenseContest2025.ino」は、4秒ごとにHDRカメラボードからのカメラ画像を、ビットマップに変換して液晶モジュールに表示します。同時に温度・湿度・気圧センサ BME280から取得した温度、気圧、湿度の値を液晶モジュールの画面に重ねて表示します。

SpresenseContest2025.ino

#include "SPI.h" #include "Adafruit_ILI9341.h" #include <Camera.h> #define SEALEVELPRESSURE_HPA (1013.25) #include <BME280I2C.h> #include <Wire.h> BME280I2C bme; // Default : forced mode, standby time = 1000 ms // Oversampling = pressure ×1, temperature ×1, humidity ×1, filter off, #define TFT_CS 10 #define TFT_RST 9 #define TFT_DC 8 Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC, TFT_RST); /**************************************************************************** * Print error message ****************************************************************************/ 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 CamCB(CamImage img) { /* Check the img instance is available or not. */ if (img.isAvailable()) { float temp(NAN), hum(NAN), pres(NAN), prest(NAN); BME280::TempUnit tempUnit(BME280::TempUnit_Celsius); BME280::PresUnit presUnit(BME280::PresUnit_Pa); bme.read(pres, temp, hum, tempUnit, presUnit); Serial.print("Temp: "); Serial.print(temp); Serial.print("°" + String(tempUnit == BME280::TempUnit_Celsius ? 'C' : 'F')); Serial.print("\t\tHumidity: "); Serial.print(hum); Serial.print("% RH"); Serial.print("\t\tPressure: "); prest = pres / 100.0; Serial.print(prest); Serial.println(" hPa"); /* 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. */ //tft.fillRect(0, 0, 100, 240, ILI9341_WHITE); tft.fillRect(0, 0, 100, 240, ILI9341_WHITE); //tft.drawRGBBitmap(100, 0, (uint16_t *)img.getImgBuff(), 320, 240); tft.drawRGBBitmap(100, 0, (uint16_t *)img.getImgBuff(), 320, 240); tft.setTextSize(2); tft.setCursor(0, 0); tft.setTextColor(ILI9341_BLACK); tft.println(); tft.println("TEMP(*C):"); tft.println(temp); tft.println(); tft.println("PRES(hPa):"); tft.println(prest); tft.println(); tft.println("HUM(%):"); tft.println(hum); tft.println(); delay(4000); } else { Serial.println("Failed to get video stream image"); } } void setup() { CamErr err; Serial.begin(115200); Serial.println("ILI9341 text start!"); tft.begin(); tft.setRotation(1); Wire.begin(); while (!bme.begin()) { Serial.println("Could not find BME280 sensor!"); delay(1000); } switch (bme.chipModel()) { case BME280::ChipModel_BME280: Serial.println("Found BME280 sensor! Success."); break; case BME280::ChipModel_BMP280: Serial.println("Found BMP280 sensor! No Humidity available."); break; default: Serial.println("Found UNKNOWN sensor! Error!"); } Serial.println("Prepare camera"); err = theCamera.begin(); if (err != CAM_ERR_SUCCESS) { printError(err); } /* Start video stream. */ Serial.println("Start streaming"); err = theCamera.startStreaming(true, CamCB); if (err != CAM_ERR_SUCCESS) { printError(err); } } void loop(void) { }

感想と展望

今回は、SPRESENSE Wi-Fi Add-onボード iS110Bが入手できなかったため、Wi-Fiによる通信機能が実装できませんでした。時間が取れれば、 Add-onボードを入手して取得したカメラ画像や温度等の環境情報を、携帯に転送してみたいと考えています。

  • kati さんが 2026/01/10 に 編集 をしました。 (メッセージ: 初版)
ログインしてコメントを投稿する