공기정화 식물-인공지능-IOT

화분의 젖은 인공토 저항값 측정센서 제작, ThingSpeak 데이터 전송, Capacitive 센서와의 비교

coding art 2021. 1. 1. 13:42
728x90

화분에서 수분 값을 측정하기 위한 적절한 센서는 저장형과 Capacitive 두가지 유형이 있다. 그 중 저항형은 전극 자체가 수분에 용해될뿐 아니라 그 측정 값 정밀도가 의심된다. 따라서 다음과 같이 구리판 전극을 사용 제작하여 100K옴 저항을 사용하여 분압 배선하도록 한다. 인공토의 저항은 급수하였을 경우 100K~1M옴 범위까지 변동한다. 즉 측정 초기에 1.5V 수준에서 인공토 저항값이 커짐에 따라 5V 가까이 커지게 된다.

이러한 원리에 따라 수분에 용해되지 않는 구리판 전극을 제작해 보자. 구리판에 구멍을 뚫어 배선을 납땜한다. 배선도에 따라 아날로그 핀에 연결할 위치에서 배선을 분기하여 100K옴 저항을 연결 후 5V 커넥터를 만들고 수축튜브로 피복을 입힌다.

화분의 인공토 수분 상태와 실내 온습도를 측정할 수 있도록 Capacitive Moisture 센서와 DHT11 온습도 센서를 다음과 같이 배선한다. Capacitive Moisture 센서 값은 전극판 전압 측정 값과 비교하기 위해서 함께 설치하자.

젖은 인공토에 가해지는 변동성 전압을 측정하기 위해 esp32 보드의 아날로그 핀 GPIO 33번을 사용하여 배선하자. 기준 전압은 5V를 사용하도록 한다. 3.3V 도 사용 가능하다. 32번 핀에는 이미 Capacitive Moisture 센서를 배선하였으며 오른 쪽 22SCL 핀에는 DHT11을 배선하자.

저항 측정 방식과 Capacitive Moisture 측정 방식은 상호 관련성이 없지만 적어도 인공토가 건조해져 급수를 할 시기가 되면 공통적으로 임계값을 관찰 할 수 있을 것이다.

 

화분에서 수분을 측정할 수 있는 IOT 시스템 코드를 살펴보자. ESP 보드에서 측정된 데이터는 WiFi.h 라이브러리를 사용 무선 와이파이를 통해 사물인터넷 ThingSpeak 서버에 전달된다. 이때에 반드시 ThingSpeak.h 라이브러리가 필요하며 이 라이브러리는 라이브러리 관리에서 검색에 의해 찾은 후 쉽게 설치할 수 있다.

Setup에서 Serial.begin(), WiFi.mode() ThingSpeak.begin() 명령을 실행하자. loop() 시작 점에서 무선와이파이 접속 작업을 시작한다.

loop() 문에서 DHT11 온습도 센서 값을 읽는 if 제어문 내부에서 analogRead() 명령을 사용하여 Capacitive 센서 값과 아날로그 저항값을 읽는다. Capacitive 센서 값은 % 처리하고 전압값은 5V 기준에 대해서 환산한다.

 

아래와 같이 ThingSpeak 매뉴얼에 따라 Field 변수들을 세팅 후 ThingSpeak.writeFields 명령을 사용하여 측정값을 ThingSpeak에 전송한다.

코드가 완성되었으면 보드명 DOIT ESP32 DEV K1을 지정하고 포트를 확인 후 ESP32 보드의 BOOT 버튼을 누른 상태에서 업로딩 작업을 실시하고 완료되면 RESET 버튼을 누른다.

 

측정 실험 결과를 살펴보자. 전극에 의한 아날로그 전압 측정 결과에 의하면 초기부터 건조해짐에 따라 점차 인공토 저항 측정값이 100K옴 저항 대비 증가함에 따라 측정되는 전압이 상승함을 알 수 있다.

반면에 Capacitive Moisture 센서들에 의한 측정 결과는 선형적인 증가가 아니라 우묵한 바닥을 통과하여 증가하는 경향을 공통적으로 보여준다. 이는 센서 설치 후 정상상태에 도달하기까지 조정현상으로 볼 수 있다. 즉 반응 시간이 거의 24시간에 달할 정도로 상당히 길다는 점이다. 하지만 반응시간이 경과되면전압 측정 방식과 마찬가지로 측정값이 상승하게 된다.

100k옴 저항을 사용하여 측정해 본 결과 건조도 80% 선에서 인공토에 걸리는 전압이 5V 로 포화가 되어 버렸음이 확인되었다. 100k옴 대비 인공토의 저항 값이 M옴 이상인 상태가 된 듯 하다. 따라서 100K 옴 저항을 1M옴으로 바꾸어 측정해 본 결과 측정값이 5V에서 2.5V 수준으로 낮아졌다. Capacitive 센서의 건조도 측정값이 80근처에서 90근처로 상승함에 따라 측정 전압값이 더욱 높아질 여유가 생겼다.

따라서 100K 옴 저항을 500K옴 가변저항으로 바꾸어 최적으로 조정해서 측정해 본 결과 다음 그림에서처럼 Capacitive 센서에서 처럼 비슷한 패턴을 볼 수 있었다.

esp보드에서 전원을 OFF 한 상태에서 찾은 최적 저항 값을 측정해 보니 27K옴으로 측정되었다. 가변저항 전체 저항 값은 238K 옴으로 측정되었다. 참고로 두 극판 사이이의 저항 값을 멀티메터로 측정해 보니 약 150~180 K옴 값이 측정되었다.

 

//ThingSpeak_esp32_dracena_compacta_probe

 

#include "ThingSpeak.h"

#include <WiFi.h>

#include <DHT11.h>

 

char ssid[] = "droidan1234"; // your network SSID (name)

char pass[] = "dddddddddd"; // your network password

 

WiFiClient client;

 

unsigned long myChannelNumber = 185411;//Your channel ID

const char * myWriteAPIKey = "J5WGWY8OMQEH6BKR";//Your channel API write key

 

int sensor = 32;//수분센서 핀

int elode = 33;//전극 전압 측정 핀

int pin = 19; //DHT11 핀번호

int hg = 4095;

int lw = 1840;

unsigned long sampling_time =300000;

 

DHT11 dht11(pin);

 

void setup() {

Serial.begin(115200); //Initialize serial

WiFi.mode(WIFI_STA);

ThingSpeak.begin(client); // Initialize ThingSpeak

pinMode(pin, INPUT);

}

 

void loop() {

int err,xsoil,xvolt;

float volt, temp, humi,soil;

if(WiFi.status() != WL_CONNECTED) {

Serial.print("Attempting to connect to SSID: ");

while(WiFi.status() != WL_CONNECTED) {

WiFi.begin(ssid,pass); // Connect to WPA/WPA2 network

Serial.print(".");

delay(5000);

}

Serial.println("\nConnected.");

}

 

if((err=dht11.read(humi, temp))==0) {

xsoil = analogRead(sensor);

if( xsoil < lw ) xsoil = lw;

if( xsoil > hg ) xsoil = hg;

soil = 100.0*(xsoil-lw)/(hg - lw);

xvolt = analogRead(elode);

volt = 5.0*xvolt/4095;

Serial.print(volt, 2);

Serial.print(soil,0);

Serial.print(temp, 0);

Serial.print(humi, 0);

Serial.println();

}

else {

Serial.println();

Serial.print("Error No :");

Serial.print(err);

Serial.println();

}

 

// Write to ThingSpeak. There are up to 8 fields in a channel

// set the fields with the values

ThingSpeak.setField(1, volt);

ThingSpeak.setField(2, soil);

ThingSpeak.setField(3, temp);

ThingSpeak.setField(4, humi);

int x = ThingSpeak.writeFields(myChannelNumber, myWriteAPIKey);

delay(sampling_time); // Wait 20 seconds to update the channel again

 

}//End