また、温度だけでなく日照不足も補うため、LED照明を追加した。
24時間点灯は植物の負担になるらしいので朝夕に手動でON/OFFしているが、
このON/OFFを自動化したい。(ときどき付け忘れるので…)
(↑こんな感じ 見た目はめちゃくちゃ怪しいけど、健全な草花なのでご安心を)
温度モニタリングと時間での照明ON/OFFを実現するため、
Raspberry Pi Zero WとArduino Nanoを連携させてシステムを構築した。
仕様は以下2つ。
・照明の12V電源を朝7時にON、夜19時にOFFする
・温室内の4点の温度をAmbient.ioに毎分送信する
先にAmbientの表示結果を載せる。
こんな風に4点がグラフ化できる。何か月分もさかのぼって見ることもできる優れもの。
環境検討
ESP32とかPi Zeroなら単独でもできないこともないが、安いArduino Nano互換機を大量に持っているので2ボード構成を選択した。
わざわざ2つを繋ぐのは少しダサいけど、いくつかメリットもある。
ArduinoはAnalog INで直接読めるからLM35やLM61のような安い温度計測ICを使えるが、
Piから直接読めるセンサはお値段が高め。
ESP32はADCの誤差が大きい。また、ESP32自体がPi Zero Wより高い。
対して、Pi+Arduinoなら、Internet部分をPythonで簡単に書けるうえに安く作れる。
その代わり、PiとArduinoのSerial通信を書く必要がある。
簡単に表にまとめるとこんな感じ。
Arduino + Pi | Piのみ | ESP32 | |
主要部品 | Arduino Nano Pi Zero W LM61 *4 | Pi Zero W DS18B20 *4 | ESP32 LM61 * 4 |
概算費用 | 400円 1,320円 60円*4 (1,960円) | 1,320円 320円*4 (2,540円) | 2,200円 60円*4 (2,240円) |
開発言語 | C/C++ Python ※ボード間通信有 | Python | C/C++ |
ソース
本日はソースの掲示のみ。中身の説明とハードウェアは後日掲載します。
・Raspberry Pi
#! /usr/bin/python3 import serial as sl import ambient from datetime import datetime as dt am = ambient.Ambient(<AmbientのID>, "<AmbientのKey>") tim = dt.now() count = 0 acc = [0.0, 0.0, 0.0, 0.0] s = sl.Serial("/dev/ttyUSB0", 9600) while True: try: txt = s.readline() ary = txt.decode().strip().split(" ") if len(ary) != 11: continue else: t = [float(x) for x in [ary[1], ary[4], ary[7], ary[10]]] count += 1 for idx in range(4): acc[idx] += t[idx] if (dt.now() - tim).total_seconds() >= 60: t = [x / count for x in acc] count = 0 acc = [0.0, 0.0, 0.0, 0.0] tim = dt.now() tmp = {'d1':t[0], 'd2':t[1], 'd3':t[2], 'd4':t[3]} am.send(tmp) ## Ambientへ送信 # DC12VのON/OFF if 7 <= tim.hour and tim.hour <= 19: s.write(b"t") else: s.write(b"f") except Exception as e: print(e) s.close()
・Arduino
void sendTemp(); bool serialFlag = false; unsigned long tim = 0; const unsigned char PWR = 3; // D3 void setup(){ Serial.begin(9600); delay(20); pinMode(LED_BUILTIN, OUTPUT); pinMode(PWR, OUTPUT); digitalWrite(LED_BUILTIN, HIGH); digitalWrite(PWR, HIGH); } void loop(){ if(millis() - tim > 1000){ sendTemp(); tim = millis(); } } void serialEvent(){ while(Serial.available()){ char c = Serial.read(); switch(c){ case 'T': case 't': // AC12V ON digitalWrite(LED_BUILTIN, HIGH); digitalWrite(PWR, HIGH); break; case 'F': case 'f': // AC12V OFF digitalWrite(LED_BUILTIN, LOW); digitalWrite(PWR, LOW); break; default: break; } } } void sendTemp(){ float t[4]; t[0] = analogRead(A7) * 500.0/1024 - 60; t[1] = analogRead(A6) * 500.0/1024 - 60; t[2] = analogRead(A5) * 500.0/1024 - 60; t[3] = analogRead(A4) * 500.0/1024 - 60; Serial.write("S0: "); Serial.print(t[0]); Serial.write(" / S1: "); Serial.print(t[1]); Serial.write(" / S2: "); Serial.print(t[2]); Serial.write(" / S3: "); Serial.println(t[3]); }
以上。続きは後編へ。
0 件のコメント:
コメントを投稿