식물의 물 공급을 IoT한다 3 : Raspberry pi를 이용한 급수 타이밍 제어

마지막: 식물의 물을 IoT한다 2 : 모터 제어와 트랜지스터

누가 물을 통제해야 하는가?



전회와 전전회로, 물을 해야 할 타이밍과, 실제로 물을 하는 수단을 획득했다.
이들을 조합함으로써, 드디어 적절한 타이밍에서의 급수를 할 수 있게 된다.
단순히 Arduino 안에 그 프로그램을 짜넣어 버리면, 5V의 전원에 연결하는 것만으로 독립형 가동시킬 수 있다.
그것은 그것으로 유용할 것이지만, 이번에는 그것을 조금 확장시키고 싶다.

명령대로 따르기



Arduino군에게는 팔다리가 되도록 한다.
수분량이 몇%인지를 획득할 수 있어도, 몇%가 되면 급수를 할지 판단을 동시에 해야 하는 것은 아니다.
값의 획득과 그 값을 바탕으로 무엇을 판단하는지는 완전히 다른 문제이다.
그래서 Arduino에게는 "센서값을 보내라고 하면 보내고, 급수하라고 하면 급수를 한다"는 일만을 담당하게 한다.
지난번 시리얼 통신을 통해 Arduino와 PC에서 문자열을 교환했다.
시리얼 통신에서의 문자의 교환은 1문자씩이며, 게다가 지금의 json등이라고 하는 형식의 해석 기능 등 Arduino는 가지고 있지 않기 때문에, 받는 값은 고정 길이 형식으로 한다.

Arduino에 보내는 문자열 중 1문자를 명령으로 하고, 급수의 경우에 그 후 몇 초간 급수할지의 수치를 보낸다.

autoWatering.ino
int SENSOR_PIN = A0;    // select the input pin for the potentiometer
int MOTER_PIN = 2;      // select the pin for the LED

int CMD_SENSOERING = 0;
int CMD_WATERING = 1;

void setup() {
  pinMode(MOTER_PIN, OUTPUT);
  Serial.begin(115200);
}

void loop() {
  // シリアル値が来たら実行する
  int Vib = Serial.available();
  if (Vib > 0) {
    String VibON;

    // 固定長で一文字目は命令とする
    int command = Serial.read() - 48;

    // 残りの文字があればモーター稼働時間
    for (int i = 0; i < Vib - 1; i++) {
      VibON += String(Serial.read() - 48);
    }
    Serial.read(); // 最後は改行文字

    if (command == CMD_SENSOERING) {
      int value = analogRead(SENSOR_PIN);
      int per = 100 - (value - 200) / 3;
      Serial.println(per);
      Serial.flush();

    } else if (command == CMD_WATERING) {
      int v = VibON.toInt();
      if (0 < v) {
        digitalWrite(MOTER_PIN, HIGH);
        delay(v);
        digitalWrite(MOTER_PIN, LOW);
      }
    }
  }
}

이제 Arduino는 단지 명령을 받고 그대로 처리를 실행할 뿐인 기계가 되었습니다.
또한 센서값은 실행할 때마다 다소의 상하폭이 있었기 때문에 10회의 평균치로 했다.

Raspberry pi로 제어



다음과 같이 라즈파이와 Arduino를 연결한다.

구체적으로 라즈파이의 환경을 어떻게 구축했는지에 관해서는 이번에는 할애한다.
라즈파이는 즉 아주 작은 컴퓨터이므로, 최근의 녀석이라면 Wifi나 Bluetooth를 내장하고 있거나와 보통으로 사용하는 분에는 PC와 아무런 변화가 없기 때문이다.
식물은 실내 재배에 적합한 관엽 식물의 스파티필람.
이미 우리 집에 와서 2주가 지났지만, 순조롭게 잎의 수를 늘리고 있다.
한 번도 밖에 내놓은 적은 없지만 단 7W의 LED로도 충분한 광량을 확보할 수 있는 것으로 밝혀졌다.

자, 라즈파이에서 아래 파이썬 코드를 실행합니다.
이쪽은 급수용의 코드.
1회 실행하면 3초간의 급수를 실시한다.

temporaryWatering.py
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import serial
#ser = serial.Serial('/dev/cu.usbmodem141101', 115200) # Mac用
ser = serial.Serial('/dev/ttyACM0', 115200) # ラズパイ用
ser.write(b"13000")
ser.close()

이쪽은 센서치 취득.
한 번 실행하면 센서 값을 반환합니다.
센서값은 실행할 때마다 다소의 상하폭이 있었기 때문에 10회의 평균치로 했다.

receiveMoisture.py
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import serial
import time
#ser = serial.Serial('/dev/cu.usbmodem141101', 115200) # Mac用
ser = serial.Serial('/dev/ttyACM0', 115200) # ラズパイ用
sensor_value = 0
for i in range(10):
    ser.write(b"0")
    a = ser.readline()
    while ser.in_waiting:
        a = a + ser.readline()
    sensor_value += int(a.split(b'\r')[0])
    time.sleep(1)
sensor_value //= 10
print(sensor_value)
ser.close()

이것으로, 라즈파이로부터의 제어를 할 준비가 되었다.
이들을 조합하여 다음과 같이 완성된다.

autoWatering.py
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import time
import serial
import pymysql.cursors

# 通信は都度開閉する
#ser = serial.Serial('/dev/cu.usbmodem141101', 115200) # Mac用
ser = serial.Serial('/dev/ttyACM0', 115200) # ラズパイ用
ser.write(b"0")
a = ser.readline()
while ser.in_waiting:
    a = a + ser.readline()
sensor_value = int(a.split(b'\r')[0])
print(sensor_value)

if (sensor_value < 90):
    ser.write(b"13000")
ser.close()

try:
    conn = pymysql.connect(
        user='root',
        host='localhost',
        port=3306,
        db='auto_watering'
    )
    c = conn.cursor()
    sql = 'INSERT INTO moisture_list (moisture) VALUES (%s);'
    c.execute(sql, (sensor_value))
    c.execute('commit')
except Exception as e:
    print(e)

이것을 한 시간에 한 번의 크론으로 두드리기로 했다.

appendix



이것으로 마침내 자동 급수 시스템이 완성되었습니다.
이대로 해도 좋지만, 어차피 라즈파이에까지 제어를 확장시켰으므로, 다음은 드디어 IoT의 「I」의 부분에의 확장을 시도하고 싶다.

좋은 웹페이지 즐겨찾기