デモ動画
部品
使用するハードウェアを次に示します。
| 部品名 | 個数 |
|---|---|
| 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
に
編集
をしました。
(メッセージ: 初版)
ログインしてコメントを投稿する