はじめに
今回2022年 SPRESENSE™ 活用コンテストにてspresense本体と、拡張ボード、カメラモジュールをご提供いただけたので、
やってみたかった100均自作水槽のIoT化にチャレンジしてみる。
ちなみに今回IoT化する水槽はこちら。
【100均自作】小型オーバーフロー&アクアポニックス水槽 #1水槽作り
※正確には植物も栽培するアクアポニックス+オーバーフロー水槽です
やはりspresenseといえばGPSを搭載している事が最大の特徴だと思っているので、お試しで少しだけ利用してみる。
加えてカメラモジュールも約500万画素とマイコンとは思えない性能を持っているため、ここもしっかりと利用します
(マイコンでカメラといえばESP32-CAMが思い浮かびますが、SPRESENSEの性能は倍以上らしい、期待大)。
あとやはりマイコンということで省電力化はできる限り行いたい(公式な使用方法から外れない程度で)
よって搭載した機能は以下の通り。
- GPSで正確な時間を取得する
- 毎朝ある時間になったら、自動で魚に餌やりをする(自動餌やり装置を自作)
- 餌やりのタイミングで定点カメラが植物の様子を撮影し、SDに保存
- その後スリープして、朝付近にまた起動させ正確な時間を読みに行く(省電力化)
使用物品
- spresense本体
- 拡張ボード
- カメラモジュール
- SD
- 100均のケース
- サーボモータ(Amazon格安品)
- ジャンパーワイヤー
コードと接続
プログラミングに関しては完全なる初学者のため、動いてるだけで良しとした(ifが便利すぎで初学者使いがち)
SPRESENSEとの接続は、サーボモータの信号線をD15ピンに繋げただけですね!!
水槽IoT化装置
#include <Camera.h>
#include <SDHCI.h>
#include <Servo.h>
//GPS
#include <Arduino.h>
#include <LowPower.h>
#include <RTC.h>
#include <GNSS.h>
SpGnss Gnss;
#define MY_TIMEZONE_IN_SECONDS (9 * 60 * 60) // JST
int state = false;
/////
//servo
static Servo servo;
/////
SDClass theSD;
void setup() {
//servo
servo.attach(PIN_D15);
servo.write(0);
//GPS
LowPower.clockMode(CLOCK_MODE_32MHz);
Serial.begin(115200);
while (!Serial);
RTC.begin();
LowPower.begin();
pinMode(LED0, OUTPUT); //Get time from GPS
pinMode(LED1, OUTPUT); //take a picture
pinMode(LED2, OUTPUT); //GPS connect
digitalWrite(LED0, LOW);
digitalWrite(LED1, LOW);
digitalWrite(LED2, LOW);
// Initialize and start GNSS library
int ret;
ret = Gnss.begin();
assert(ret == 0);
ret = Gnss.start();
assert(ret == 0);
/////
}
void loop() {
//GPS
Serial.print(".");
state = !state;
digitalWrite(LED2, (state)? HIGH: LOW);
// Wait for GNSS data
if (Gnss.waitUpdate()) {
SpNavData NavData;
// Get the UTC time
Gnss.getNavData(&NavData);
SpGnssTime *time = &NavData.time;
// Check if the acquired UTC time is accurate
if (time->year >= 2000) {
Serial.println(".");
Serial.println("Get time from GPS");
digitalWrite(LED0, HIGH);
char buf[128];
// Convert SpGnssTime to RtcTime
RtcTime gps(time->year, time->month, time->day,
time->hour, time->minute, time->sec, time->usec * 1000);
gps += MY_TIMEZONE_IN_SECONDS;
sprintf(buf, "%04d/%02d/%02d %02d:%02d:%02d\t",
gps.year(), gps.month(), gps.day(),
gps.hour(), gps.minute(), gps.second());
Serial.print("Data: ");
Serial.println(buf);
int t = gps.hour();
delay(1000);
digitalWrite(LED0, LOW);
/////
//Shooting conditions
if(t < 10){
digitalWrite(LED2, LOW);
Serial.println("Re GPS connect after 10 min");
//deepsleep
digitalWrite(LED0, LOW);
digitalWrite(LED1, LOW);
digitalWrite(LED2, LOW);
Serial.println("deepsleep start (10 min)");
LowPower.deepSleep(10 * 60);
}else{
theCamera.begin();
while(!theSD.begin());
theCamera.setStillPictureImageFormat(
CAM_IMGSIZE_QUADVGA_H ,CAM_IMGSIZE_QUADVGA_V
,CAM_IMAGE_PIX_FMT_JPG);
digitalWrite(LED1, HIGH);
CamImage img = theCamera.takePicture();
if (img.isAvailable()) {
char filename[16] = {0};
sprintf(filename, "%04d%02d%02d%02d%02d%02d.JPG",
gps.year(), gps.month(), gps.day(),
gps.hour(), gps.minute(), gps.second());
File myFile = theSD.open(filename, FILE_WRITE);
myFile.write(img.getImgBuff(), img.getImgSize());
myFile.close();
Serial.println("take a picture");
digitalWrite(LED1, LOW);
}
//servo ON
Serial.println("servo ON");
servo.write(180);
delay(3000);
servo.write(0);
delay(1000);
//deepsleep
digitalWrite(LED0, LOW);
digitalWrite(LED1, LOW);
digitalWrite(LED2, LOW);
Serial.println("deepsleep start (23 h)");
LowPower.deepSleep(23 * 60 * 60);
}
}
}
}
完成品はこちら
※一日一回しか作動しないため、設置前のデモ動画を掲載しています(自動餌やり装置とSPRESENSE)
ズボラな私的には、IoT化で餌やりを自動化出来たことがかなりのメリットでした。
また、写真は期待通りの高画質で大満足ですね。
定点カメラで撮影ができると成長過程が見れて、ますます植物を育てたくなりますね。
今後の展望
実は腑に落ちてない部分もあり…
省電力化(deepsleep使ってるのにサーボモーターには常に電流が流れている件)やコード(とりあえず動いてる感)にまだまだ改善の余地がありですね。
照明もUSB給電なので、リレーモジュールを組み込めばライトのOnOFFも管理できそうです。
ひとまず形にはなったので、これで完成としたいと思います。
省電力化にアドバイスがあったら是非お願いします!!
投稿者の人気記事
-
gadgewota
さんが
2022/09/12
に
編集
をしました。
(メッセージ: 初版)
ログインしてコメントを投稿する