산업 제조
산업용 사물 인터넷 | 산업자재 | 장비 유지 보수 및 수리 | 산업 프로그래밍 |
home  MfgRobots >> 산업 제조 >  >> Manufacturing Technology >> 제조공정

스마트 도시형 식물 자동 급수 시스템: 센서 기반 자동 수분 공급

부품 및 소모품

토양 수분 센서 ×2 아날로그 출력이 있는 모든 토양 수분 센서 사용 가능. 두 전극과 전압 분배기로도 대체 가능. 선택 사항.
빗물 감지 센서 ×1
우유 팩 (물통용) ×1 물을 담을 수 있고 자르고 고정할 수 있는 모든 용기 가능. 높은 곳에 설치해야 함.
연질 플라스틱 호스 ×1 어떤 호스든 가능. 줄넘기 줄의 양끝을 잘라 속이 빈 부분을 사용함.
점퍼 와이어 (일반) ×37 다소 여유있게 준비
아두이노 101용 SparkFun Inventor's Kit ×1 아두이노 101, 서보, 브레드보드, 포텐셔미터, LCD 포함
모델링 클레이 ×1
짧은 플라스틱 막대 ×1 또는 휘지 않는 막대. 물통 출수관 지지용.
330옴 저항 ×1

필요한 도구 및 기계

앱 및 온라인 서비스

프로젝트 개요

스마트 도시형 식물 자동 급수 시스템: 센서 기반 자동 수분 공급

이 장치는 도시 환경에서 식물 관수를 개선합니다. 아두이노 101로 구동되며, 내장 도구와 몇 가지 외부 센서를 사용하여 해당 환경에서 식물에 물을 주기 위한 최적의 조건을 계산하고, 계산된 시간에 자동으로 물을 줍니다.

작동 원리

중력과 압력

이 장치는 우유 팩, 플라스틱 호스, 클레이(밀봉용), 서보를 사용하여 만든 저수조에서 물을 공급받습니다. 이 용기는 장치보다 높은 곳에 위치하여 장치 위로 내리는 빗물을 모을 수 있도록 설계되었습니다.

스마트 도시형 식물 자동 급수 시스템: 센서 기반 자동 수분 공급

저수조는 주로 가정용 수도로 채워지지만 빗물로 보충됩니다. 팩 바닥에 구멍을 내고 출수관을 삽입하면 중력이 물을 관을 통해 끌어당깁니다. 서보가 물이 나가는 시점을 제어합니다. 평소에는 서보 암이 직립하여 물 흐름을 차단하고, 급수 시 135도 회전하여 물을 흘려보냅니다. 물의 압력은 저수조 안정성과 물 배출을 돕습니다.

TMP36 온도 센서와 인텔 퀴리 패턴 매칭 엔진 (PME)

이 조합은 식물 급수 최적 시간을 계산하는 데 사용됩니다. TMP36은 전자식 아날로그 출력을 가진 온도 센서로, 마이크로컨트롤러가 읽어 온도로 변환할 수 있습니다. 이 프로젝트에서는 식물 급수에 최적인 25°C에 가장 가까운 시간을 찾습니다. 시간당 30회, 2분 간격으로 기록하고, 각 기간이 끝날 때 29개 데이터(첫 번째 제외)의 평균을 계산합니다. 여기서 패턴 매칭 엔진이 작동합니다.

스마트 도시형 식물 자동 급수 시스템: 센서 기반 자동 수분 공급

인텔 퀴리 PME는 아두이노 101에 내장된 인공 신경망으로, 128개 뉴런으로 구성되어 데이터를 학습하고 분류합니다. GitHub에서 라이브러리를 제공합니다.

이 프로젝트에서는 PME가 하루 동안의 온도 데이터를 기록하고 25°C에 해당하는 최적 조건을 분류합니다. 결과가 다음 날 급수 시간이 됩니다.

데이터는 오전 8시부터 오후 9시까지 매시간 기록됩니다. 첫 학습 시 데이터는 온보드 시리얼 플래시에 저장되어 전원이 꺼져도 데이터를 유지합니다. 데이터셋 확보 후 최적 조건을 분류 시도하며, 성공 시 해당 시간이 다음 라운드의 급수 시간이 됩니다. 실패 시 월별 상수(해당 월의 최고 기온 시간)를 사용합니다. 이 월별 상수가 항상 식물 급수에 최적인 것은 아니므로 PME를 활용했습니다.

첫 학습 후 데이터는 초기화되고 다음 날 다시 학습하며, 선택된 시간에 식물에 물을 줍니다. 이 주기가 무한 반복되거나 전원이 차단될 때까지 계속되며, 재부팅 시 저장된 파라미터를 급수 시간으로 사용합니다.

인텔 퀴리 실시간 시계 (RTC) 및 블루투스 저에너지 (BLE)

인텔 퀴리 RTC는 장치의 모든 동작 시점을 제어하는 핵심 부품입니다. 특히 급수 시간과 데이터 기록 시간을 위한 '시간', 백업 피크 온도 상수를 위한 '월'을 추적하는 데 필수적입니다. 하지만 정확한 날짜는 코드나 사용자 입력으로 수동 설정해야 합니다. 이를 BLE로 해결했습니다.

스마트 도시형 식물 자동 급수 시스템: 센서 기반 자동 수분 공급

블루투스 저에너지는 저전력 장치를 위해 설계된 새로운 블루투스 버전으로, 센트럴-페리페럴 시스템으로 동작합니다. 센트럴(입력)이 페리페럴(출력)에 데이터를 쓰는 방식으로, 게시판 시스템처럼 센트럴이 데이터 게시판에 데이터를 올리면 모든 페리페럴이 읽습니다. 여기서는 모바일 기기의 nRF Connect를 센트럴로, 아두이노 101을 페리페럴로 사용했습니다. 모바일 기기가 아두이노에 연결하여 데이터를 전송합니다. 필요한 입력 필드 4개(시, 분, 일, 월)를 위해 모바일 기기에서 4번 데이터를 전송해야 합니다.

모바일 기기 입력은 16진수로 이루어지며, 10진수에서 변환하기 쉽지만 온라인 변환기를 사용해도 됩니다.

제작 방법

이 관수 솔루션 제작에는 약간의 회로 지식이 필요하지만 어렵지 않습니다. 몇 가지 비전기 부품도 필요합니다.

전기 부품

배터리 구동 시 (오래 가지 않을 수 있음)

USB 전원 구동 시 (벽면 어댑터 또는 노트북)

비전기 하드웨어 부품

도구

제작 단계

  1. 프리칭 다이어그램에 따라 회로를 구성합니다. 토양 수분 센서는 선택 사항이며, 빗물 센서와 서보는 원하는 위치까지 닿도록 전선을 연장해야 할 수 있습니다. 최종 회로 배치는 아래 두 번째 사진을 참조하세요.
스마트 도시형 식물 자동 급수 시스템: 센서 기반 자동 수분 공급
스마트 도시형 식물 자동 급수 시스템: 센서 기반 자동 수분 공급
  1. (USB 전원 사용 시 5단계로 이동). 두 배터리 박스에 배터리를 넣고 한 박스의 양극 리드와 다른 박스의 음극 리드를 연결합니다.
스마트 도시형 식물 자동 급수 시스템: 센서 기반 자동 수분 공급
  1. 전기 테이프로 두 박스를 고정합니다. 두 박스의 커버와 케이스가 각각 붙어 있도록 하고, 커버가 한 조각으로 분리 가능하게 합니다. 전원 스위치용 슬롯은 열어둡니다.
  2. 배터리 박스의 이중 커버를 아두이노 101과 브레드보드 아래쪽에 테이프로 고정합니다. 이렇게 하면 배터리를 보드 아래에서 슬라이드하여 쉽게 교체할 수 있습니다.
스마트 도시형 식물 자동 급수 시스템: 센서 기반 자동 수분 공급
  1. 장치를 공예 바구니에 넣고 한쪽에 두 개의 슬롯을 냅니다. 첫 번째는 프로그래밍용(USB 전원 사용 시), 두 번째는 장치에 없는 센서와 액추에이터용 출구입니다. 이 출구에서 느슨한 전선은 전기 테이프로 정리합니다.
스마트 도시형 식물 자동 급수 시스템: 센서 기반 자동 수분 공급
  1. 우유 팩의 윗부분을 잘라내어 물이 충분히 모일 수 있는 큰 입구와 충분한 용량을 만듭니다. 손잡이 밑부분 근처에서 자르는 것을 권장합니다.
  2. 팩 바닥의 가장 넓은 입구 바로 아래에 작은 구멍을 뚫고 플라스틱 호스 한 끝을 삽입합니다. 호스가 제자리에 고정될 만큼 충분히 작으면서 호스를 조이지 않을 만큼 충분히 크게 만듭니다.
스마트 도시형 식물 자동 급수 시스템: 센서 기반 자동 수분 공급
  1. 클레이로 구멍 위아래 호스 주변을 밀봉합니다. 클레이가 호스 내부로 들어가지 않게 주의하세요.
  2. 클레이와 전기 테이프로 서보를 우유 팩 바닥 가까이에 고정합니다. 호스 중간과 플라스틱 막대를 서보 혼에 테이프로 고정합니다. 플라스틱 막대도 호스 위쪽 끝에 테이프로 고정하세요. 8-10단계는 아래 사진을 참조하세요.
  3. 저수조를 높은 표면에 고정합니다. 필요시 테이프를 사용합니다.
스마트 도시형 식물 자동 급수 시스템: 센서 기반 자동 수분 공급
  1. 튜브 출구가 내려갔을 때 바로 아래에 식물을 둡니다. 토양 수분 센서를 사용하는 경우 흙에 꽂고, 빗물 센서는 식물 근처 바닥에 둡니다. 센서와 서보를 장치에 연결하고, 장치는 저수조와 식물에서 약간 떨어진 곳에 둡니다.

프로그래밍

첨부된 코드를 아두이노 101에 업로드합니다. 아두이노 IDE와 퀴리 코어 2.0.2 이상 사용 (가능한 경우). 코드에 유용한 주석이 많이 포함되어 있습니다.

장치 작동

장치를 처음 켜면 모바일 기기 연결을 기다립니다. nRF Connect로 기기가 연결되면 시간 입력을 기다립니다. 아래 다이어그램과 같이 10진수 시, 분, 일, 월을 16진수 코드로 순차적으로 nRF Connect에 입력합니다.

시간 입력 전에 ID 입력(임의의 숫자)을 먼저 전송해야 합니다.

스마트 도시형 식물 자동 급수 시스템: 센서 기반 자동 수분 공급

시간 입력 후 101은 모바일 기기 연결 해제를 기다립니다. 해제 후 오전 8시(당일 또는 다음 날)를 기다립니다.

오전 8시가 되면 보드는 플래시 메모리에 저장된 데이터가 있는지 확인합니다. 없으면 앞서 설명한 14시간 수집 과정을 거쳐 데이터를 분류하고 최적 시간을 결정한 후 수집 주기를 반복합니다. 데이터가 저장되어 있으면 그 데이터를 시간 상수로 사용하고 정상적으로 주기가 계속됩니다.

급수 시간에 비가 오거나 토양 수분이 과다(선택 사항)하면 당일 급수를 건너뛰고 다음 날을 기다립니다.

스마트 도시형 식물 자동 급수 시스템: 센서 기반 자동 수분 공급

이 솔루션은 자동 설정을 통해 도시 식물 관수를 더 간단하고 최적화되게 만듭니다. 저수조를 사용하여 식물에 직접 내리지 않는 빗물과 기존 수도를 함께 활용함으로써 빗물을 절약합니다.

이 프로젝트가 끊임없이 변화하는 세상을 조금 더 나은 곳으로 만드는 데 도움이 되기를 바랍니다!

코드

아두이노 101 관수 시스템

아두이노 101 관수 시스템 작동 코드입니다. 아두이노 IDE와 퀴리 코어 2.0.2로 업로드하세요. CuriePME는 GitHub에서 찾을 수 있습니다.

/* 도시 관수 솔루션 스케치. CuriePME를 사용해 온도 데이터를 학습하고 
   최적 식물 급수 조건(25°C)을 분류합니다. 해당 시간에 급수하고 데이터를 
   다시 학습하며 무한 반복합니다. 이 스케치는 대상 날짜 오전 8시 전에 
   실행해야 시작됩니다. 
   데이터 출처: WeatherSpark.com, Just 4 Growers */

#include "CuriePME.h"
#include <CurieBLE.h>
#include <CurieTime.h>
#include <SerialFlash.h>
#include <SPI.h>
#include <LiquidCrystal.h>
#include <Servo.h>

// 서보 핀 설정
Servo waterPipe;

// LCD 핀 설정
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

// 전역 상수/변수
#define thermometer A3
#define rainSensor 1
#define humidity1 A4
#define humidity2 A1

int tm1, tm2, tm3, tm4, tm5, tm6, tm7, tm8, tm9, tm10;
int tm11, tm12, tm13, tm14, tm15, tm16, tm17, tm18, tm19, tm20;
int tm21, tm22, tm23, tm24, tm25, tm26, tm27, tm28, tm29, tm30;
int average, progav;
float voltage, temperatureC;
int tm, hourTime = -1, minuteTime = -1, dayTime = -1, monthTime = -1, confirmTime = -1;

// BLE 서비스 데이터
BLEService plantService("19B10000-E8F2-537E-4F6C-D104768A1214");
// BLE 특성, 센트럴에서 읽기/쓰기 가능
BLEUnsignedCharCharacteristic timeCharacteristic("19B10001-E8F2-537E-4F6C-D104768A1214", BLERead | BLEWrite);

void setup() {
  waterPipe.attach(9);
  waterPipe.write(0);
  pinMode(rainSensor, INPUT);
  lcd.begin(16, 2);
  lcd.clear();
  
  if (!SerialFlash.begin(ONBOARD_FLASH_SPI_PORT, ONBOARD_FLASH_CS_PIN));
  lcd.setCursor(0, 0);
  lcd.print("시간 입력: BLE");
  
  // BLE 서비스 초기화
  BLE.begin();
  BLE.setLocalName("Arduino 101");
  BLE.setAdvertisedService(plantService);
  plantService.addCharacteristic(timeCharacteristic);
  BLE.addService(plantService);
  timeCharacteristic.setValue(0);
  BLE.advertise();
  
  lcd.setCursor(0, 1);
  lcd.print("대기 중");
  
  // BLE 연결 대기
  x: BLEDevice central = BLE.central();
  if (central) {
    lcd.setCursor(8, 1);
    lcd.print(" 완료");
    delay(3000);
    while (central.connected()) {
      if (timeCharacteristic.written()) {
        // 순차적으로 시간 변수 채우기 (확인용 1회 + 시/분/일/월 4회)
        if (confirmTime == -1) { confirmTime = timeCharacteristic.value(); }
        else if (hourTime == -1) { hourTime = timeCharacteristic.value(); }
        else if (minuteTime == -1) { minuteTime = timeCharacteristic.value(); }
        else if (dayTime == -1) { dayTime = timeCharacteristic.value(); }
        else if (monthTime == -1) { 
          monthTime = timeCharacteristic.value();
          lcd.clear();
          lcd.setCursor(0, 0);
          lcd.print("시간 설정됨.");
          lcd.setCursor(0, 1);
          lcd.print("기기 연결 해제.");
        }
      }
    }
  } else {
    goto x; // 연결 안 되면 루프
  }
  
  // 수집된 변수로 시간 설정 (초와 연도는 이 시스템에서 중요하지 않음)
  setTime(hourTime, minuteTime, 00, dayTime, monthTime, 2017);
  
  // PME 초기화
  lcd.clear();
  CuriePME.begin();
  lcd.setCursor(0, 0);
  lcd.print("저장 데이터 확인");
  delay(3000);
  
  const char *filename = "NeurData.dat";
  if (check_if_exists(filename) == true) {
    restoreNetworkKnowledge();
    lcd.setCursor(0, 1);
    lcd.print("발견!");
    delay(3000);
    lcd.clear();
    goto z;
  } else {
    lcd.setCursor(0, 1);
    lcd.print("없음!");
    delay(3000);
    lcd.clear();
  }
  
  /* setup의 나머지 부분: 하루 동안 온도 데이터 수집.
     시간당 30회 체크, 2분 간격. 각 시간 끝에서 첫 스캔 제외 
     29개 데이터의 산술 평균을 구해 PME에 학습시킴.
     오전 8시부터 오후 9시까지 14회 반복, 각기 다른 카테고리에 저장.
     완료 후 전체 데이터셋을 퀴리 플래시 메모리에 기본값으로 저장. */
  
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("학습 중");
  
  for (int i = 8; i < 22; i++) { // 14회 반복, 각기 다른 카테고리 저장
    // 30개 온도 데이터 수집 (0-255 사이 int로 매핑)
    voltage = analogRead(thermometer) * 3.3;
    voltage /= 1024.0;
    temperatureC = (voltage - 0.5) * 100;
    tm = map(temperatureC, -40, 125, 0, 255);
    tm1 = constrain(tm, 0, 255);
    delay(114000);
    
    // tm2 ~ tm30 동일하게 수집 (코드 생략 - 반복 구조)
    // ...
    
    // 첫 학습 기간에는 월별 피크 온도 시간에 급수
    if ((month() == 1 || month() == 2 || month() == 11 || month() == 12) && hour() == 12) {
      // 급수 로직 (비 오지 않고 토양 건조할 때)
    }
    // ... 월별 조건들 생략 ...
    
    delay(110000);
    // tm16 ~ tm30 수집
    // ...
    
    // 데이터를 온도 센서 사양으로 재변환
    tm1 = map(tm1, 0, 255, -40, 125); tm1 = constrain(tm1, -40, 125);
    // ... tm2 ~ tm30 동일 ...
    
    // 산술 평균 계산 및 메모리 커밋
    average = (tm2 + tm3 + ... + tm30) / 29;
    commitSample(i, average);
  }
  
  saveNetworkKnowledge(); // 새 데이터를 플래시 메모리에 저장
  
  z: delay(1);
}

void commitSample(int category, uint8_t s1) {
  uint8_t vector[1];
  vector[0] = s1;
  CuriePME.learn(vector, 1, category);
}

void loop() {
  // 무한 반복
  /* PME가 학습한 데이터 중 25°C(식물 급수 최적 온도)를 분류 시도.
     분류 성공 시 반환된 카테고리가 급수 시간이 됨.
     데이터 삭제 후 재학습, 무한 반복.
     분류 실패 시 앞서 정의한 월별 기본값 사용. */
  
  uint8_t vector[1];
  vector[0] = 25;
  int answer = CuriePME.classify(vector, 1);
  
  if (answer == CuriePME.noMatch) {
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("매칭 없음!");
    // 월별 기본값 사용
    if (month() == 1 || month() == 2 || month() == 11 || month() == 12) { answer = 12; }
    else if (month() == 3 || month() == 4 || month() == 10) { answer = 14; }
    else if (month() == 5 || month() == 6 || month() == 9) { answer = 15; }
    else if (month() == 7 || month() == 8) { answer = 16; }
  } else {
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("카테고리:");
    lcd.setCursor(0, 1);
    lcd.print(answer);
  }
  
  delay(3000);
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("최적화 완료");
  delay(3000);
  
  CuriePME.forget(); // 삭제 후 재학습 (플래시 메모리는 지우지 않음)
  
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("대기 중");
  while (hour() != 8); // 오전 8시까지 대기
  
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("학습 중");
  
  // 데이터 재학습 (setup과 유사한 루프)
  for (int i = 8; i < 22; i++) {
    // 온도 데이터 30개 수집 및 평균 계산
    // ...
    
    // PME가 결정한 시간에 급수
    if (hour() == answer) {
      // 급수 로직 (비 오지 않고 토양 건조할 때)
    }
    
    // 평균 계산 및 커밋
    average = (tm2 + tm3 + ... + tm30) / 29;
    progav = (tm30 - tm2) / 2;
    commitSample(i, average);
  }
}

/* 플래시 메모리 데이터 참고: 데이터는 한 번만 저장되며 이 코드로는 변경 불가.
   전원 손실 시 최초 사용 시 설정으로 기본값 복원됨.
   완전히 지우려면 IDE의 "CurieSerialFlash"에서 "EraseEverything" 업로드 후 
   이 스케치 재업로드하여 새 평균값 저장 필요. */

void saveNetworkKnowledge() {
  // 플래시 메모리 저장 코드 (전체 코드는 다운로드 참조)
}

회로도

회로 프리칭 다이어그램. 배터리는 왼쪽에 부착됩니다. 토양 수분 센서는 선택 사항입니다.

rainpoweredsmartirrigationsystem_OHtd4bVfb3.fzz

제조공정

  1. 티타늄: 핵심 특성, 응용, 산업 용도
  2. 카스타넷: 역사, 장인정신, 연주
  3. 접착제의 역사, 생산, 미래: 고대 접착제에서 현대 혁신까지
  4. 실: 종류, 역사, 생산, 그리고 품질 관리
  5. 아세틸렌: 생산, 용도, 취급 종합 개요
  6. 석면: 고대 용도부터 현대 건강 위험까지 종합 개요
  7. 주사위: 고대 도구에서 현대 게이밍까지 역사, 설계, 제조
  8. 주석: 청동기 시대에서 현대 산업까지 - 용도, 생산, 미래
  9. 라즈베리파이와 웹 대시보드로 만드는 자동 식물 급수 시스템
  10. 지멘스·벤틀리, 발전소 디지털화 가속화 공동 솔루션 발표