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

도시 식물 관수 솔루션

구성품 및 소모품

토양 수분 센서
아날로그 출력이 있는 모든 토양 수분 센서를 사용할 수 있습니다. 두 개의 전극과 전압 분배기도 사용할 수 있습니다. 선택 사항입니다.
× 2
레인 센서
× 1
우유 용기
물을 담을 수 있고 절단할 수 있고 표면에 고정할 수 있는 모든 용기가 적합합니다. 높은 표면에 장착해야 합니다.
× 1
부드러운 플라스틱 유연한 중공 튜빙
어떤 종류의 튜빙도 가능합니다. 나는 매우 유연하고 중앙이 비어 있기 때문에 끝이 잘린 줄넘기를 사용했습니다.
× 1
점퍼 와이어(일반)
다소 또는 적습니다.
× 37
Arduino 101용 SparkFun Inventor 키트
저는 Arduino 101, 서보, 브레드보드, 전위차계 및 LCD를 사용했습니다.
× 1
모델링 클레이
× 1
짧은 플라스틱 막대
또는 유연하지 않은 막대. 물탱크의 출구배관을 지지하는데 사용합니다.
× 1
저항 330옴
× 1

필요한 도구 및 기계

가위
십자 드라이버
전기 테이프
일반 테이프도 있습니다.

앱 및 온라인 서비스

Nordic Semiconductor nRF Connect SDK
Arduino IDE

이 프로젝트 정보

이 장치는 도시 환경에서 식물 관개를 개선합니다. Arduino 101로 구동되는 이 제품은 몇 가지 외부 센서와 함께 온보드 도구를 사용하여 자체 환경에서 식물에 물을 주기 위한 최적의 조건을 계산한 다음 계산된 시간에 식물 자체에 물을 줍니다.

다음 개념을 기반으로 합니다.

중력 및 압력

이 장치는 우유병, 플라스틱 튜브, 튜브 밀봉용 점토 및 서보를 사용하여 만든 저수지의 수원을 탭합니다. 이 컨테이너는 높은 위치 외에도 장치 위에서 빗물을 모을 수 있는 위치에 있습니다.

주전자는 주로 가정용 물 공급으로 채워지지만(비로 인해 항상 사용할 수 있는 것은 아님) 빗물로 보충됩니다. 물병에 물이 있으면 중력의 인력이 물병 안의 물을 지구 쪽으로 끌어당깁니다. 출구 파이프를 삽입할 수 있도록 용기 바닥에 구멍이 절단됩니다. 따라서 중력은 이 출구 파이프를 통해 물을 끌어당깁니다. 서보는 물이 파이프에서 완전히 빠져나갈 때를 조절합니다. 정상적인 상황에서 서보 암은 수직 위치에 있어 물이 파이프 밖으로 흘러나오는 것을 방지합니다. 그러나 식물에 물을 줄 때 팔이 135도 낮아져 물이 파이프에서 흘러 나와 식물에 물을 줄 수 있습니다. 이 작업이 완료되면 팔을 다시 들어 올립니다.

물병에 가해지는 물의 압력은 물병의 안정성을 도울 뿐만 아니라 물의 배출에도 도움이 되어 관개 중에 물이 지속적으로 흐를 수 있도록 합니다.

TMP36 온도 센서 및 Intel Curie 패턴 매칭 엔진

이러한 개념의 조합은 식물에 물을 줄 최적의 시간을 결정하는 계산을 유도하는 데 도움이 됩니다. TMP36은 온도계처럼 작동하지만 전자 아날로그 출력이 있는 온도 센서입니다. 이 출력은 마이크로컨트롤러와 같은 장치에서 읽고 온도로 변환할 수 있습니다. 이 프로젝트에서 장치는 섭씨 25도에 가장 가까운 식물에 물을 줄 최적의 시간을 계산하려고 합니다. 2분 간격으로 시간당 30개의 레코드를 만들고 각 기간이 끝날 때 이 중 29개의 평균을 계산합니다(첫 번째는 일반적으로 정확하지 않으므로 제외). 이것이 패턴 매칭 엔진이 필요한 곳입니다.

Intel Curie PME 또는 패턴 일치 엔진은 Arduino 101에 내장된 인공 신경망입니다. 해당 라이브러리는 GitHub에서 사용할 수 있습니다. 128개의 뉴런으로 구성되어 벡터에 저장된 데이터를 기존 데이터를 기반으로 학습하고 분류하거나 카테고리로 분류된 벡터를 분류할 수 있습니다. 사용 가능한 카테고리가 많을수록 PME는 더 많은 분류 옵션을 추구할 수 있습니다.

이 프로젝트를 위해 PME는 하루 동안의 온도 데이터를 기록하고 이 데이터 중에서 최적 조건인 섭씨 25도를 분류하려고 시도합니다. 결과는 다음날 식물에 물을 줄 시간이됩니다.

데이터는 오전 8시부터 오후 9시까지 매시간 기록됩니다. 이 작업이 처음 수행되면 데이터가 온보드 직렬 플래시에 저장됩니다. . 이렇게 하면 기기가 꺼져 있어도 데이터세트로 부팅할 수 있습니다. 데이터셋을 획득한 후 최적 조건 분류를 시도합니다. 그렇게 할 수 있는 경우 선택한 범주가 다음 라운드에 사용되는 시간이 됩니다. 그렇지 않은 경우 장치는 월별 상수를 사용하거나 매월 온도가 가장 높은 시간을 사용합니다. 식물에 물을 주기에 항상 최적의 온도는 아닙니다 , 그래서 PME를 활용했습니다.

첫 번째 학습 세션이 끝나면 데이터가 지워지고 다음 날 다시 학습되며 선택한 시간에 식물에 물을 줍니다. 이 주기는 무한히 반복되거나 장치의 전원이 분리될 때까지 반복되며, 다시 켜면 저장된 매개변수를 선택한 시간으로 사용하고 계속 진행됩니다.

Intel Curie 실시간 시계 및 Bluetooth 저에너지

Intel Curie RTC 또는 실시간 시계는 이 장치의 중요한 구성 요소입니다. RTC는 장치의 모든 것이 발생하는 시기를 제어합니다. 이 프로젝트의 경우 RTC는 식물에 물을 주는 데 사용되는 시간과 데이터를 기록하는 시간과 백업 피크 온도 상수를 결정하는 데 사용되는 월을 추적하는 데 특히 중요합니다. 그러나 이 RTC의 정확한 날짜는 코드에서 또는 사용자 입력을 통해 수동으로 설정해야 합니다. BLE로 해결했습니다.

Bluetooth Low Energy는 저전력 장치용으로 설계된 최신 버전의 Bluetooth입니다. 중앙 또는 입력이 주변 장치 또는 출력에 쓰는 중앙 주변 장치 시스템에서 작동합니다. 이것은 중앙에서 모든 주변 장치가 읽을 수 있도록 게시판에 데이터를 배치하는 게시판 시스템처럼 작동합니다. 이 경우 모바일 기기에는 노르딕 세미컨덕터의 nRF Connect를 중앙으로, 아두이노 101을 주변기기로 사용했습니다. 모바일 장치에는 Arduino에 연결하고 데이터를 보낼 수 있는 기능이 있습니다. 이 경우 모바일 장치는 필수 입력 필드마다 한 번씩 데이터를 네 번 보내야 합니다.

모바일 장치에서 입력되는 데이터는 16진수로 입력됩니다. 이것은 10진법에서 변환하기가 상당히 쉽지만 온라인 변환기를 사용할 수 있습니다.

제작 방법

이 관개 솔루션을 구축하려면 약간의 회로 지식이 필요하지만 너무 많이는 아닙니다. 또한 완료하려면 몇 가지 비전기적 구성 요소가 필요합니다. 전체 부품 목록은 다음과 같습니다.

전기 부품

<울>
  • 아두이노 101
  • <울>
  • 400 타이 브레드보드, +- 레일 포함
  • <울>
  • 회전 전위차계
  • <울>
  • 16x2 LCD
  • <울>
  • 330옴 저항기
  • <울>
  • TMP36 온도 센서
  • <울>
  • 180도 서보, 서보 혼 포함
  • <울>
  • 레인 센서 및 제어 보드
  • <울>
  • 토양 수분 센서 및 제어 보드(옵션, 하드웨어가 참조용으로 포함됨)
  • <울>
  • 상당한 양의 점퍼 와이어; Fritzing 다이어그램 참조
  • 배터리로 실행하려면(너무 오래 지속되지 않을 수 있음, 내가 사용한 설정):

    <울>
  • 켜기/끄기 스위치와 전선 리드가 있는 4xAA 배터리 상자 2개
  • <울>
  • 8X AA 1.2V NiMH 충전식 배터리
  • 벽 사마귀나 노트북에서 USB 전원으로 실행하려면:

    <울>
  • USB Male A - 필요에 따라 길이가 달라지는 Male B 케이블
  • 비전기 하드웨어 구성요소

    <울>
  • 우유 용기
  • <울>
  • 약 20-30cm 길이의 유연한 플라스틱 튜브
  • <울>
  • 점토, 뜨거운 접착제 또는 밀봉제로 사용할 수 있는 모든 것 모델링
  • <울>
  • 튜빙 암을 지지하는 플라스틱 막대
  • <울>
  • 기기를 담을 수 있는 바구니
  • <울>
  • 작은 벤치나 테이블과 같이 주전자를 담을 수 있는 높은 표면
  • <울>
  • 식물
  • 도구

    <울>
  • 일반 및 전기 테이프
  • <울>
  • 가위
  • <울>
  • 서보 혼을 서보에 부착하기 위한 십자 드라이버
  • 단계

    1. 아래 Fritzing 다이어그램에 따라 회로를 구성합니다. 토양 수분 센서는 선택 사항이며 레인 센서와 서보는 원하는 위치에 도달하기 위해 더 긴 와이어가 필요할 수 있습니다. 회로의 최종 배열은 아래 두 번째 사진을 참조하십시오.

    2. (USB 전원을 사용하는 경우 5단계로 건너뜁니다.) 두 개의 배터리 상자에 배터리를 넣고 한 상자의 양극 리드와 다른 상자의 음극 리드를 함께 묶습니다.

    3. 전기 테이프를 사용하여 상자를 함께 테이프로 붙입니다. 양쪽의 커버를 부착하고 양쪽의 케이스를 부착하고, 커버가 일체형으로 탈부착이 되도록 박스를 고정합니다. 전원 스위치용 슬롯을 열어 두십시오.

    4. 배터리 상자의 이중 덮개를 Arduino 101 및 브레드보드의 아래쪽에 테이프로 붙입니다. 이렇게 하면 배터리를 보드 아래에서 밀어서 쉽게 교체할 수 있습니다.

    5. 공예 바구니에 장치를 삽입하고 장치의 한쪽에 두 개의 슬롯을 자릅니다. 첫 번째 슬롯은 프로그래밍(또는 그렇게 하기로 선택한 경우 USB 전원)용이고 두 번째 슬롯은 장치에 있지 않은 센서 및 액추에이터용 콘센트입니다. 전기 테이프를 사용하여 이 콘센트에 느슨한 전선을 함께 고정하십시오.

    6. 우유병을 가져다가 상단을 잘라 물통의 입구가 물을 모을 수 있을 만큼 충분히 크고 용량이 충분하도록 합니다. 손잡이 바닥에 가까운 곳에서 자르는 것이 좋습니다.

    7. 용기 상단에 있는 가장 큰 부분 바로 아래에 있는 용기 바닥의 작은 구멍을 자릅니다. 플라스틱 튜브의 한쪽 끝을 이 구멍에 삽입합니다. 구멍이 파이프가 제자리에 고정될 만큼 충분히 작지만 파이프를 쥐어짜지 않을 만큼 충분히 큰지 확인합니다.

    8. 점토를 사용하여 구멍의 파이프 주변 상단 및 하단 영역을 밀봉합니다. 점토가 파이프 자체에 들어가지 않도록 하십시오.

    9. 점토와 전기 테이프를 사용하여 서보를 우유 용기 바닥에 가능한 한 낮게 고정합니다. 튜브의 중앙과 플라스틱 막대를 서보 혼에 테이프로 붙입니다. 플라스틱 막대가 튜브의 상단에도 테이프로 붙어 있는지 확인하십시오. 아래 그림을 8~10단계에 대한 참조로 사용하세요.

    10. 용기를 상승된 표면에 고정합니다. 필요한 경우 테이프를 사용하십시오.

    11. 내린 위치에 있을 때 관 배출구 바로 아래에 식물을 놓습니다. 수분 센서를 사용하는 경우 토양에 붙이고 레인 센서를 바닥을 따라 식물 가까이에 놓습니다. 센서와 서보를 장치에 연결하고 장치는 용기와 식물에서 약간 더 멀리 배치합니다.

    프로그래밍

    첨부된 코드로 Arduino 101을 프로그래밍합니다. Arduino IDE 및 Curie Core 2.0.2 이상(사용 가능한 경우)을 사용하여 업로드합니다. 코드에 유용한 주석이 많이 포함되어 있습니다.

    기기 작동

    장치를 처음 켜면 모바일 장치가 연결될 때까지 기다립니다. nRF Connect를 사용하여 장치를 연결하면 시간 입력을 기다립니다. 이렇게 하려면 아래 그림과 같이 nRF Connect에 기본 10시, 분, 일, 월의 16진수 코드를 순서대로 입력합니다.

    시간을 입력하기 전에 ID 입력 또는 임의의 숫자를 입력하고 전송해야 합니다.

    시간을 입력한 후 101은 모바일 장치의 연결이 끊길 때까지 기다립니다. 그렇게 한 후 오늘 또는 다음 날 오전 8시를 기다립니다.

    오전 8시에 도달하면 보드는 플래시 메모리 저장소에 저장된 것이 있는지 확인합니다. 그렇지 않은 경우 앞서 설명한 대로 14시간 수집 프로세스를 거쳐 데이터를 분류하고 최적의 시간을 결정하여 수집 주기를 반복합니다. 무언가가 저장되면 해당 데이터는 시간 상수로 사용되며 주기는 정상적으로 계속됩니다.

    보드가 식물에 물을 주는 시간 동안 비 또는 과도한 토양 수분(선택 사항)은 식물에 물을 주는 것을 방지합니다. 그런 다음 그날의 물주기를 건너뛰고 다음 날을 기다립니다.

    이 솔루션은 이를 처리하는 자동 설정을 사용하여 도시 식물 관개를 보다 간단하고 최적화하도록 설계되었습니다. 또한 저수지를 사용하여 기존 주택 공급과 함께 빗물을 절약하여 식물로 향하지 않는 비를 잘 사용합니다.

    바라건대 이 프로젝트가 우리의 끊임없이 변화하는 세상을 조금 더 나은 곳으로 만들 것입니다!

    <섹션 클래스="섹션 컨테이너 섹션 축소 가능" id="코드">

    코드

    <울>
  • Arduino 101 관개 시스템
  • Arduino 101 관개 시스템Arduino
    Arduino 101 관개 시스템을 작동하기 위한 코드입니다. Curie core 2.0.2 및 1.8.x 이상의 IDE를 사용하여 업로드합니다. CuriePME는 GitHub에서 찾을 수 있습니다.
    /*이것은 도시 관개 솔루션에 대한 스케치입니다. CuriePME를 사용하여 온도 데이터를 학습하고 이에 대한 최적의 식물 관수 조건을 분류합니다. 그런 다음 해당 시간에 식물에 물을 주고, 데이터를 다시 학습하고 무한 순환합니다. 이 스케치는 장치를 시작하기 위해 목표 날짜의 오전 8시 이전에 실행되어야 합니다. 데이터 출처:"WeatherSpark.com." 캐나다, 밴쿠버의 년중 평균 날씨 - Weather Spark. N.p., N.D. 편물. 2017년 7월 4일. ."단지 4명의 재배자:글로벌 가든 커뮤니티." 재배자를 위해. N.p., N.D. 편물. 2017년 7월 10일. . */// 이 코드와 함께 사용할 라이브러리. CuriePME를 제외한 모두 ide에서 찾을 수 있습니다. CuriePME는 GitHub 저장소에서 다운로드할 수 있습니다.#include "CuriePME.h#include #include #include #include #include #include // 서보 핀아웃 코드.서보 waterPipe;// LCD 핀아웃 코드.LiquidCrystal lcd(12, 11, 5, 4, 3, 2);// 전역 상수/변수.#define 온도계 A3 #define rainSensor 1#define 습도1 A4#define 습도2 A1int tm1;int tm2;int tm3;int tm4;int tm5;int tm6;int tm7;int tm8;int tm9;int tm10;int tm11;int tm12; int tm14;int tm15;int tm16;int tm17;int tm18;int tm19;int tm20;int tm21;int tm22;int tm23;int tm24;int tm25;int tm26;int tm2;int 평균;int progav;float 전압;float temperatureC;int tm;int hourTime =-1;int minTime =-1;int dayTime =-1;int monthTime =-1;int ConfirmTime =-1;// BLE 서비스 data.BLEService plantService("19B10000-E8F2-537E-4F6C-D104768A1214");// BLE 특성, 중앙에서 읽기/쓰기 가능.BLEUnsignedCharCharacteristic timeCha racteristic("19B10001-E8F2-537E-4F6C-D104768A1214", BLERead | BLEWrite);void setup() { // 한 번 실행됩니다. waterPipe.attach(9); waterPipe.write(0); 핀모드(레인센서, 입력); lcd.begin(16, 2); // LCD를 시작하고 지웁니다. lcd.clear(); if (!SerialFlash.begin(ONBOARD_FLASH_SPI_PORT, ONBOARD_FLASH_CS_PIN)); lcd.setCursor(0, 0); lcd.print("입력 시간:BLE"); // 이름, 서비스, 특성, 특성 값으로 BLE 서비스를 초기화합니다. BLE.시작(); BLE.setLocalName("아두이노 101"); BLE.setAdvertisedService(plantService); plantService.addCharacteristic(timeCharacteristic); BLE.addService(plantService); timeCharacteristic.setValue(0); // 중앙에서 작성될 때까지 0. BLE.광고(); lcd.setCursor(0, 1); lcd.print("대기 중"); // 연결 준비 완료.x:BLEDevice central =BLE.central(); if (central) { // 장치가 보드에 연결되어 있는 경우. lcd.setCursor(8, 1); lcd.print("완료"); 지연(3000); while (central.connected()) { // 장치가 아직 연결되어 있는 동안. if (timeCharacteristic.write()) { // 디바이스에서 각 바이트가 전송된 후 모든 시간 변수 슬롯을 순차적으로 채우는 코드. 데이터는 4번 전송되고 링크 확인을 위해 1번 전송됩니다. if (confirmTime ==-1) {confirmTime =timeCharacteristic.value(); } else if (hourTime ==-1) { hourTime =timeCharacteristic.value(); } else if (분시간 ==-1) { 분시간 =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 { x로 이동; // 장치가 아직 연결되지 않은 경우 루프백합니다. } // 수집된 변수로 시간을 설정합니다. 초와 연도는 이 시스템에서 중요하지 않습니다. setTime(시, 분, 00, 일, 월, 2017); // PME를 초기화합니다. lcd.clear(); CuriePME.begin(); lcd.setCursor(0, 0); lcd.print("저장 확인 중입니다."); 지연(3000); const char *파일명 ="NeurData.dat"; if (check_if_exists(filename) ==true) { restoreNetworkKnowledge(); lcd.setCursor(0, 1); lcd.print("찾았습니다!"); 지연(3000); lcd.clear(); 고토 z; } 그렇지 않으면 { lcd.setCursor(0, 1); lcd.print("찾을 수 없습니다!"); 지연(3000); lcd.clear(); } /* 설정의 나머지 부분은 하루 중 온도 데이터를 수집합니다. 2분 간격으로 시간당 30번의 검사를 하고, 시간이 끝나면 첫 번째 스캔을 제외한 모든 데이터의 산술 평균을 구하여 시간의 데이터 평균을 취합니다. 이 평균은 PME에 입력되고 학습됩니다. 이것은 오전 8시부터 오후 9시까지 반복되며, 이 시점에서 PME가 학습한 전체 데이터 세트는 장치의 전원이 꺼지거나 다시 시작해야 하는 경우에 대한 기본값으로 CurieFlash 메모리에 저장됩니다. */ lcd.clear(); lcd.setCursor(0, 0); lcd.print("학습"); for (int i =8; i <22; i++) // 이것을 14번 반복하고 각각 다른 카테고리에 저장합니다. { // 0과 255 사이에 매핑된 int로 저장된 30개의 온도 데이터를 수집합니다. voltage =analogRead(thermometer) * 3.3; 전압 // 1024.0; 온도C =(전압 - 0.5) * 100; tm =지도(온도C, -40, 125, 0, 255); tm1 =제약(tm, 0, 255); 지연(114000); // 위의 체크 지연을 보상합니다. 전압 =analogRead(온도계) * 3.3; 전압 // 1024.0; 온도C =(전압 - 0.5) * 100; tm =지도(온도C, -40, 125, 0, 255); tm2 =제약(tm, 0, 255); 지연(120000); 전압 =analogRead(온도계) * 3.3; 전압 // 1024.0; 온도C =(전압 - 0.5) * 100; tm =지도(온도C, -40, 125, 0, 255); tm3 =제약(tm, 0, 255); 지연(120000); 전압 =analogRead(온도계) * 3.3; 전압 // 1024.0; 온도C =(전압 - 0.5) * 100; tm =지도(온도C, -40, 125, 0, 255); tm4 =제약(tm, 0, 255); 지연(120000); 전압 =analogRead(온도계) * 3.3; 전압 // 1024.0; 온도C =(전압 - 0.5) * 100; tm =지도(온도C, -40, 125, 0, 255); tm5 =제약(tm, 0, 255); 지연(120000); 전압 =analogRead(온도계) * 3.3; 전압 // 1024.0; 온도C =(전압 - 0.5) * 100; tm =지도(온도C, -40, 125, 0, 255); tm6 =제약(tm, 0, 255); 지연(120000); 전압 =analogRead(온도계) * 3.3; 전압 // 1024.0; 온도C =(전압 - 0.5) * 100; tm =지도(온도C, -40, 125, 0, 255); tm7 =제약(tm, 0, 255); 지연(120000); 전압 =analogRead(온도계) * 3.3; 전압 // 1024.0; 온도C =(전압 - 0.5) * 100; tm =지도(온도C, -40, 125, 0, 255); tm8 =제약(tm, 0, 255); 지연(120000); 전압 =analogRead(온도계) * 3.3; 전압 // 1024.0; 온도C =(전압 - 0.5) * 100; tm =지도(온도C, -40, 125, 0, 255); tm9 =제약(tm, 0, 255); 지연(120000); 전압 =analogRead(온도계) * 3.3; 전압 // 1024.0; 온도C =(전압 - 0.5) * 100; tm =지도(온도C, -40, 125, 0, 255); tm10 =제약(tm, 0, 255); 지연(120000); 전압 =analogRead(온도계) * 3.3; 전압 // 1024.0; 온도C =(전압 - 0.5) * 100; tm =지도(온도C, -40, 125, 0, 255); tm11 =제약(tm, 0, 255); 지연(120000); 전압 =analogRead(온도계) * 3.3; 전압 // 1024.0; 온도C =(전압 - 0.5) * 100; tm =지도(온도C, -40, 125, 0, 255); tm12 =제약(tm, 0, 255); 지연(120000); 전압 =analogRead(온도계) * 3.3; 전압 // 1024.0; 온도C =(전압 - 0.5) * 100; tm =지도(온도C, -40, 125, 0, 255); tm13 =제약(tm, 0, 255); 지연(120000); 전압 =analogRead(온도계) * 3.3; 전압 // 1024.0; 온도C =(전압 - 0.5) * 100; tm =지도(온도C, -40, 125, 0, 255); tm14 =제약(tm, 0, 255); 지연(120000); 전압 =analogRead(온도계) * 3.3; 전압 // 1024.0; 온도C =(전압 - 0.5) * 100; tm =지도(온도C, -40, 125, 0, 255); tm15 =제약(tm, 0, 255); // 첫 번째 학습 기간 동안 식물 물주기는 해당 월의 최고 기온에서 수행됩니다. if ((월() ==1 || 월() ==2 || 월() ==11 || 월() ==12) &&시() ==12) { lcd.clear(); lcd.setCursor(0, 0); lcd.print("실행 중..."); // 비가 오지 않고 토양 수분이 충분히 낮으면 식물에 물을 줍니다. int readRain =digitalRead(rainSensor); if (readRain ==HIGH) { lcd.setCursor(0, 1); lcd.print("지금 비가 옵니다."); 고토 a2; } // 수분 센서를 사용하려면 주석 처리를 제거합니다. //else if (analogRead(humidity1)> 400 || analogRead(humidity2)> 400) // 토양에 맞게 조정합니다. //{ //lcd.setCursor(0, 1); //lcd.print("흙이 너무 습합니다."); // 이동 ​​a2; //} else { waterPipe.write(135); 지연(7000); // 7초 동안 물을 줍니다. waterPipe.write(0); } lcd.setCursor(0, 1); lcd.print("완료");a2:지연(3000); lcd.clear(); lcd.setCursor(0, 0); lcd.print("학습"); } else if ((month() ==3 || month() ==4 || month() ==10) &&hour() ==14) { lcd.clear(); lcd.setCursor(0, 0); lcd.print("실행 중..."); lcd.clear(); lcd.setCursor(0, 0); lcd.print("실행 중..."); // 비가 오지 않고 토양 수분이 충분히 낮으면 식물에 물을 줍니다. int readRain =digitalRead(rainSensor); if (readRain ==HIGH) { lcd.setCursor(0, 1); lcd.print("지금 비가 옵니다."); goto31; } // 수분 센서를 사용하려면 주석 처리를 제거합니다. //else if (analogRead(humidity1)> 400 || analogRead(humidity2)> 400) // 토양에 맞게 조정합니다. //{ //lcd.setCursor(0, 1); //lcd.print("흙이 너무 습합니다."); // 이동 ​​a31; //} else { waterPipe.write(135); 지연(7000); // 7초 동안 물을 줍니다. waterPipe.write(0); } lcd.setCursor(0, 1); lcd.print("완료");a31:지연(3000); lcd.clear(); lcd.setCursor(0, 0); lcd.print("학습"); lcd.clear(); lcd.setCursor(0, 0); lcd.print("학습"); } else if ((month() ==5 || month() ==6 || month() ==9) &&hour() ==15) { lcd.clear(); lcd.setCursor(0, 0); lcd.print("실행 중..."); lcd.clear(); lcd.setCursor(0, 0); lcd.print("실행 중..."); // 비가 오지 않고 토양 수분이 충분히 낮으면 식물에 물을 줍니다. int readRain =digitalRead(rainSensor); if (readRain ==HIGH) { lcd.setCursor(0, 1); lcd.print("지금 비가 옵니다."); 고토3; } // 수분 센서를 사용하려면 주석 처리를 제거합니다. //else if (analogRead(humidity1)> 400 || analogRead(humidity2)> 400) // 토양에 맞게 조정합니다. //{ //lcd.setCursor(0, 1); //lcd.print("흙이 너무 습합니다."); // 이동 ​​a3; //} else { waterPipe.write(135); 지연(7000); // 7초 동안 물을 줍니다. waterPipe.write(0); } lcd.setCursor(0, 1); lcd.print("완료");a3:지연(3000); lcd.clear(); lcd.setCursor(0, 0); lcd.print("학습"); } else if ((month() ==7 || month() ==8) &&hour() ==16) { lcd.clear(); lcd.setCursor(0, 0); lcd.print("실행 중..."); lcd.clear(); lcd.setCursor(0, 0); lcd.print("실행 중..."); // 비가 오지 않고 토양 수분이 충분히 낮으면 식물에 물을 줍니다. int readRain =digitalRead(rainSensor); if (readRain ==HIGH) { lcd.setCursor(0, 1); lcd.print("지금 비가 옵니다."); 고토 a4; } // 수분 센서를 사용하려면 주석 처리를 제거합니다. //else if (analogRead(humidity1)> 400 || analogRead(humidity2)> 400) // 토양에 맞게 조정합니다. //{ //lcd.setCursor(0, 1); //lcd.print("흙이 너무 습합니다."); // 이동 ​​a4; //} else { waterPipe.write(135); 지연(7000); // 7초 동안 물을 줍니다. waterPipe.write(0); } lcd.setCursor(0, 1); lcd.print("완료");a4:지연(3000); lcd.clear(); lcd.setCursor(0, 0); lcd.print("학습"); } 지연(110000); 전압 =analogRead(온도계) * 3.3; 전압 // 1024.0; 온도C =(전압 - 0.5) * 100; tm =지도(온도C, -40, 125, 0, 255); tm16 =제약(tm, 0, 255); 지연(120000); 전압 =analogRead(온도계) * 3.3; 전압 // 1024.0; 온도C =(전압 - 0.5) * 100; tm =지도(온도C, -40, 125, 0, 255); tm17 =제약(tm, 0, 255); 지연(120000); 전압 =analogRead(온도계) * 3.3; 전압 // 1024.0; 온도C =(전압 - 0.5) * 100; tm =지도(온도C, -40, 125, 0, 255); tm18 =제약(tm, 0, 255); 지연(120000); 전압 =analogRead(온도계) * 3.3; 전압 // 1024.0; 온도C =(전압 - 0.5) * 100; tm =지도(온도C, -40, 125, 0, 255); tm19 =제약(tm, 0, 255); 지연(120000); 전압 =analogRead(온도계) * 3.3; 전압 // 1024.0; 온도C =(전압 - 0.5) * 100; tm =지도(온도C, -40, 125, 0, 255); tm20 =제약(tm, 0, 255); 지연(120000); 전압 =analogRead(온도계) * 3.3; 전압 // 1024.0; 온도C =(전압 - 0.5) * 100; tm =지도(온도C, -40, 125, 0, 255); tm21 =제약(tm, 0, 255); 지연(120000); 전압 =analogRead(온도계) * 3.3; 전압 // 1024.0; 온도C =(전압 - 0.5) * 100; tm =지도(온도C, -40, 125, 0, 255); tm22 =제약(tm, 0, 255); 지연(120000); 전압 =analogRead(온도계) * 3.3; 전압 // 1024.0; 온도C =(전압 - 0.5) * 100; tm =지도(온도C, -40, 125, 0, 255); tm23 =제약(tm, 0, 255); 지연(120000); 전압 =analogRead(온도계) * 3.3; 전압 // 1024.0; 온도C =(전압 - 0.5) * 100; tm =지도(온도C, -40, 125, 0, 255); tm24 =제약(tm, 0, 255); 지연(120000); 전압 =analogRead(온도계) * 3.3; 전압 // 1024.0; 온도C =(전압 - 0.5) * 100; tm =지도(온도C, -40, 125, 0, 255); tm25 =제약(tm, 0, 255); 지연(120000); 전압 =analogRead(온도계) * 3.3; 전압 // 1024.0; 온도C =(전압 - 0.5) * 100; tm =지도(온도C, -40, 125, 0, 255); tm26 =제약(tm, 0, 255); 지연(120000); 전압 =analogRead(온도계) * 3.3; 전압 // 1024.0; 온도C =(전압 - 0.5) * 100; tm =지도(온도C, -40, 125, 0, 255); tm27 =제약(tm, 0, 255); 지연(120000); 전압 =analogRead(온도계) * 3.3; 전압 // 1024.0; 온도C =(전압 - 0.5) * 100; tm =지도(온도C, -40, 125, 0, 255); tm28 =제약(tm, 0, 255); 지연(120000); 전압 =analogRead(온도계) * 3.3; 전압 // 1024.0; 온도C =(전압 - 0.5) * 100; tm =지도(온도C, -40, 125, 0, 255); tm29 =제약(tm, 0, 255); 지연(120000); 전압 =analogRead(온도계) * 3.3; 전압 // 1024.0; 온도C =(전압 - 0.5) * 100; tm =지도(온도C, -40, 125, 0, 255); tm30 =제약(tm, 0, 255); 지연(120000); // 데이터를 온도 센서의 사양으로 다시 변환합니다. tm1 =맵(tm1, 0, 255, -40, 125); tm1 =제약(tm1, -40, 125); tm2 =맵(tm2, 0, 255, -40, 125); tm2 =제약(tm2, -40, 125); tm3 =맵(tm3, 0, 255, -40, 125); tm3 =제약(tm3, -40, 125); tm4 =맵(tm4, 0, 255, -40, 125); tm4 =제약(tm4, -40, 125); tm5 =맵(tm5, 0, 255, -40, 125); tm5 =제약(tm5, -40, 125); tm6 =맵(tm6, 0, 255, -40, 125); tm6 =제약(tm6, -40, 125); tm7 =맵(tm7, 0, 255, -40, 125); tm7 =제약(tm7, -40, 125); tm8 =맵(tm8, 0, 255, -40, 125); tm8 =제약(tm8, -40, 125); tm9 =맵(tm9, 0, 255, -40, 125); tm9 =제약(tm9, -40, 125); tm10 =맵(tm10, 0, 255, -40, 125); tm10 =제약(tm10, -40, 125); tm11 =맵(tm11, 0, 255, -40, 125); tm11 =제약(tm11, -40, 125); tm12 =맵(tm12, 0, 255, -40, 125); tm12 =제약(tm12, -40, 125); tm13 =map(tm13, 0, 255, -40, 125); tm13 =constrain(tm13, -40, 125); tm14 =map(tm14, 0, 255, -40, 125); tm14 =constrain(tm14, -40, 125); tm15 =map(tm15, 0, 255, -40, 125); tm15 =constrain(tm15, -40, 125); tm16 =map(tm16, 0, 255, -40, 125); tm16 =constrain(tm16, -40, 125); tm17 =map(tm17, 0, 255, -40, 125); tm17 =constrain(tm17, -40, 125); tm18 =map(tm18, 0, 255, -40, 125); tm18 =constrain(tm18, -40, 125); tm19 =map(tm19, 0, 255, -40, 125); tm19 =constrain(tm19, -40, 125); tm20 =map(tm20, 0, 255, -40, 125); tm20 =constrain(tm20, -40, 125); tm21 =map(tm21, 0, 255, -40, 125); tm21 =constrain(tm21, -40, 125); tm22 =map(tm22, 0, 255, -40, 125); tm22 =constrain(tm22, -40, 125); tm23 =map(tm23, 0, 255, -40, 125); tm23 =constrain(tm23, -40, 125); tm24 =map(tm24, 0, 255, -40, 125); tm24 =constrain(tm24, -40, 125); tm25 =map(tm25, 0, 255, -40, 125); tm25 =constrain(tm25, -40, 125); tm26 =map(tm26, 0, 255, -40, 125); tm26 =constrain(tm26, -40, 125); tm27 =map(tm27, 0, 255, -40, 125); tm27 =constrain(tm27, -40, 125); tm28 =map(tm28, 0, 255, -40, 125); tm28 =constrain(tm28, -40, 125); tm29 =map(tm29, 0, 255, -40, 125); tm29 =constrain(tm29, -40, 125); tm30 =map(tm30, 0, 255, -40, 125); tm30 =constrain(tm30, -40, 125); // Find the arithmetic mean and commit it to memory. average =(tm2 + tm3 + tm4 + tm5 + tm6 + tm7 + tm8 + tm9 + tm10 + tm11 + tm12 + tm13 + tm14 + tm15 + tm16 + tm17 + tm18 + tm19 + tm20 + tm21 + tm22 + tm23 + tm24 + tm25 + tm26 + tm27 + tm28 + tm29 + tm30) / 29; commitSample(i, average); } saveNetworkKnowledge(); // Save this new data to flash memory.z:delay(1);}void commitSample (int category, uint8_t s1){ // Commit to memory a single vector (the average), along with the category, which represents the hour of that data. uint8_t vector[1]; vector[0] =s1; CuriePME.learn(vector, 1, category);}void loop() { // Infinitely repeats. /* This code attempts to classify the optimum temperature for watering plants, 25 Celsius, among the data learned by the PME. If it can classify the data, the returned category becomes the hour at which the plant will be watered. The data is then erased and relearned, which infinitely repeats. IF IT CANNOT CLASSIFY THE DATA, it will take the monthly defaults from earlier in the sketch. */ 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("NO MATCHES!"); 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("Category:"); lcd.setCursor(0, 1); lcd.print(answer); } 지연(3000); lcd.clear(); lcd.setCursor(0, 0); lcd.print("Optimization Done"); 지연(3000); CuriePME.forget(); // Erase and relearn. This does not erase the flash memory. lcd.clear(); lcd.setCursor(0, 0); lcd.print("Waiting"); while (hour() !=8); lcd.clear(); lcd.setCursor(0, 0); lcd.print("Learning"); // Learn the data again. for (int i =8; i <22; i++) { 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(120000); voltage =analogRead(thermometer) * 3.3; voltage /=1024.0; temperatureC =(voltage - 0.5) * 100; tm =map(temperatureC, -40, 125, 0, 255); tm2 =constrain(tm, 0, 255); delay(120000); voltage =analogRead(thermometer) * 3.3; voltage /=1024.0; temperatureC =(voltage - 0.5) * 100; tm =map(temperatureC, -40, 125, 0, 255); tm3 =constrain(tm, 0, 255); delay(120000); voltage =analogRead(thermometer) * 3.3; voltage /=1024.0; temperatureC =(voltage - 0.5) * 100; tm =map(temperatureC, -40, 125, 0, 255); tm4 =constrain(tm, 0, 255); delay(120000); voltage =analogRead(thermometer) * 3.3; voltage /=1024.0; temperatureC =(voltage - 0.5) * 100; tm =map(temperatureC, -40, 125, 0, 255); tm5 =constrain(tm, 0, 255); delay(120000); voltage =analogRead(thermometer) * 3.3; voltage /=1024.0; temperatureC =(voltage - 0.5) * 100; tm =map(temperatureC, -40, 125, 0, 255); tm6 =constrain(tm, 0, 255); delay(120000); voltage =analogRead(thermometer) * 3.3; voltage /=1024.0; temperatureC =(voltage - 0.5) * 100; tm =map(temperatureC, -40, 125, 0, 255); tm7 =constrain(tm, 0, 255); delay(120000); voltage =analogRead(thermometer) * 3.3; voltage /=1024.0; temperatureC =(voltage - 0.5) * 100; tm =map(temperatureC, -40, 125, 0, 255); tm8 =constrain(tm, 0, 255); delay(120000); voltage =analogRead(thermometer) * 3.3; voltage /=1024.0; temperatureC =(voltage - 0.5) * 100; tm =map(temperatureC, -40, 125, 0, 255); tm9 =constrain(tm, 0, 255); delay(120000); voltage =analogRead(thermometer) * 3.3; voltage /=1024.0; temperatureC =(voltage - 0.5) * 100; tm =map(temperatureC, -40, 125, 0, 255); tm10 =constrain(tm, 0, 255); delay(120000); voltage =analogRead(thermometer) * 3.3; voltage /=1024.0; temperatureC =(voltage - 0.5) * 100; tm =map(temperatureC, -40, 125, 0, 255); tm11 =constrain(tm, 0, 255); delay(120000); voltage =analogRead(thermometer) * 3.3; voltage /=1024.0; temperatureC =(voltage - 0.5) * 100; tm =map(temperatureC, -40, 125, 0, 255); tm12 =constrain(tm, 0, 255); delay(120000); voltage =analogRead(thermometer) * 3.3; voltage /=1024.0; temperatureC =(voltage - 0.5) * 100; tm =map(temperatureC, -40, 125, 0, 255); tm13 =constrain(tm, 0, 255); delay(120000); voltage =analogRead(thermometer) * 3.3; voltage /=1024.0; temperatureC =(voltage - 0.5) * 100; tm =map(temperatureC, -40, 125, 0, 255); tm14 =constrain(tm, 0, 255); delay(120000); voltage =analogRead(thermometer) * 3.3; voltage /=1024.0; temperatureC =(voltage - 0.5) * 100; tm =map(temperatureC, -40, 125, 0, 255); tm15 =constrain(tm, 0, 255); // The time in the day at which to water the plant, as determined by the PME. if (hour() ==answer) { lcd.clear(); lcd.setCursor(0, 0); lcd.print("Running..."); // Water the plant if it is not raining and soil moisture is low enough. int readRain =digitalRead(rainSensor); if (readRain ==HIGH) { lcd.setCursor(0, 1); lcd.print("Raining right now."); goto a5; } // Uncomment to use moisture sensors. //else if (analogRead(humidity1)> 400 || analogRead(humidity2)> 400) // Adjust these to match your soil. //{ // lcd.setCursor(0, 1); // lcd.print("Soil too moist."); // goto a5; //} else { waterPipe.write(135); delay(7000); // Water for 7 seconds. waterPipe.write(0); } lcd.setCursor(0, 1); lcd.print("Done");a5:delay(3000); lcd.clear(); lcd.setCursor(0, 0); lcd.print("Learning"); } delay(110000); voltage =analogRead(thermometer) * 3.3; voltage /=1024.0; temperatureC =(voltage - 0.5) * 100; tm =map(temperatureC, -40, 125, 0, 255); tm16 =constrain(tm, 0, 255); delay(120000); voltage =analogRead(thermometer) * 3.3; voltage /=1024.0; temperatureC =(voltage - 0.5) * 100; tm =map(temperatureC, -40, 125, 0, 255); tm17 =constrain(tm, 0, 255); delay(120000); voltage =analogRead(thermometer) * 3.3; voltage /=1024.0; temperatureC =(voltage - 0.5) * 100; tm =map(temperatureC, -40, 125, 0, 255); tm18 =constrain(tm, 0, 255); delay(120000); voltage =analogRead(thermometer) * 3.3; voltage /=1024.0; temperatureC =(voltage - 0.5) * 100; tm =map(temperatureC, -40, 125, 0, 255); tm19 =constrain(tm, 0, 255); delay(120000); voltage =analogRead(thermometer) * 3.3; voltage /=1024.0; temperatureC =(voltage - 0.5) * 100; tm =map(temperatureC, -40, 125, 0, 255); tm20 =constrain(tm, 0, 255); delay(120000); voltage =analogRead(thermometer) * 3.3; voltage /=1024.0; temperatureC =(voltage - 0.5) * 100; tm =map(temperatureC, -40, 125, 0, 255); tm21 =constrain(tm, 0, 255); delay(120000); voltage =analogRead(thermometer) * 3.3; voltage /=1024.0; temperatureC =(voltage - 0.5) * 100; tm =map(temperatureC, -40, 125, 0, 255); tm22 =constrain(tm, 0, 255); delay(120000); voltage =analogRead(thermometer) * 3.3; voltage /=1024.0; temperatureC =(voltage - 0.5) * 100; tm =map(temperatureC, -40, 125, 0, 255); tm23 =constrain(tm, 0, 255); delay(120000); voltage =analogRead(thermometer) * 3.3; voltage /=1024.0; temperatureC =(voltage - 0.5) * 100; tm =map(temperatureC, -40, 125, 0, 255); tm24 =constrain(tm, 0, 255); delay(120000); voltage =analogRead(thermometer) * 3.3; voltage /=1024.0; temperatureC =(voltage - 0.5) * 100; tm =map(temperatureC, -40, 125, 0, 255); tm25 =constrain(tm, 0, 255); delay(120000); voltage =analogRead(thermometer) * 3.3; voltage /=1024.0; temperatureC =(voltage - 0.5) * 100; tm =map(temperatureC, -40, 125, 0, 255); tm26 =constrain(tm, 0, 255); delay(120000); voltage =analogRead(thermometer) * 3.3; voltage /=1024.0; temperatureC =(voltage - 0.5) * 100; tm =map(temperatureC, -40, 125, 0, 255); tm27 =constrain(tm, 0, 255); delay(120000); voltage =analogRead(thermometer) * 3.3; voltage /=1024.0; temperatureC =(voltage - 0.5) * 100; tm =map(temperatureC, -40, 125, 0, 255); tm28 =constrain(tm, 0, 255); delay(120000); voltage =analogRead(thermometer) * 3.3; voltage /=1024.0; temperatureC =(voltage - 0.5) * 100; tm =map(temperatureC, -40, 125, 0, 255); tm29 =constrain(tm, 0, 255); delay(120000); voltage =analogRead(thermometer) * 3.3; voltage /=1024.0; temperatureC =(voltage - 0.5) * 100; tm =map(temperatureC, -40, 125, 0, 255); tm30 =constrain(tm, 0, 255); delay(120000); tm1 =map(tm1, 0, 255, -40, 125); tm1 =constrain(tm1, -40, 125); tm2 =map(tm2, 0, 255, -40, 125); tm2 =constrain(tm2, -40, 125); tm3 =map(tm3, 0, 255, -40, 125); tm3 =constrain(tm3, -40, 125); tm4 =map(tm4, 0, 255, -40, 125); tm4 =constrain(tm4, -40, 125); tm5 =map(tm5, 0, 255, -40, 125); tm5 =constrain(tm5, -40, 125); tm6 =map(tm6, 0, 255, -40, 125); tm6 =constrain(tm6, -40, 125); tm7 =map(tm7, 0, 255, -40, 125); tm7 =constrain(tm7, -40, 125); tm8 =map(tm8, 0, 255, -40, 125); tm8 =constrain(tm8, -40, 125); tm9 =map(tm9, 0, 255, -40, 125); tm9 =constrain(tm9, -40, 125); tm10 =map(tm10, 0, 255, -40, 125); tm10 =constrain(tm10, -40, 125); tm11 =map(tm11, 0, 255, -40, 125); tm11 =constrain(tm11, -40, 125); tm12 =map(tm12, 0, 255, -40, 125); tm12 =constrain(tm12, -40, 125); tm13 =map(tm13, 0, 255, -40, 125); tm13 =constrain(tm13, -40, 125); tm14 =map(tm14, 0, 255, -40, 125); tm14 =constrain(tm14, -40, 125); tm15 =map(tm15, 0, 255, -40, 125); tm15 =constrain(tm15, -40, 125); tm16 =map(tm16, 0, 255, -40, 125); tm16 =constrain(tm16, -40, 125); tm17 =map(tm17, 0, 255, -40, 125); tm17 =constrain(tm17, -40, 125); tm18 =map(tm18, 0, 255, -40, 125); tm18 =constrain(tm18, -40, 125); tm19 =map(tm19, 0, 255, -40, 125); tm19 =constrain(tm19, -40, 125); tm20 =map(tm20, 0, 255, -40, 125); tm20 =constrain(tm20, -40, 125); tm21 =map(tm21, 0, 255, -40, 125); tm21 =constrain(tm21, -40, 125); tm22 =map(tm22, 0, 255, -40, 125); tm22 =constrain(tm22, -40, 125); tm23 =map(tm23, 0, 255, -40, 125); tm23 =constrain(tm23, -40, 125); tm24 =map(tm24, 0, 255, -40, 125); tm24 =constrain(tm24, -40, 125); tm25 =map(tm25, 0, 255, -40, 125); tm25 =constrain(tm25, -40, 125); tm26 =map(tm26, 0, 255, -40, 125); tm26 =constrain(tm26, -40, 125); tm27 =map(tm27, 0, 255, -40, 125); tm27 =constrain(tm27, -40, 125); tm28 =map(tm28, 0, 255, -40, 125); tm28 =constrain(tm28, -40, 125); tm29 =map(tm29, 0, 255, -40, 125); tm29 =constrain(tm29, -40, 125); tm30 =map(tm30, 0, 255, -40, 125); tm30 =constrain(tm30, -40, 125); average =(tm2 + tm3 + tm4 + tm5 + tm6 + tm7 + tm8 + tm9 + tm10 + tm11 + tm12 + tm13 + tm14 + tm15 + tm16 + tm17 + tm18 + tm19 + tm20 + tm21 + tm22 + tm23 + tm24 + tm25 + tm26 + tm27 + tm28 + tm29 + tm30) / 29; progav =(tm30 - tm2) / 2; commitSample(i, average); }}/* A quick note on the flash memory data:The data will only ever be saved once; that is, it cannot be changed with this code. As a result, if the device loses power, IT WILL DEFAULT TO THE SETTINGS OF THE FIRST TIME IT WAS USED WHEN IT IS REACTIVATED, even if the monthly averages have changed. Keeping the device on an extra day will allow it to software obtain new averages, but the flash memory will stay the same. To erase flash completely, upload "EraseEverything" from "CurieSerialFlash" in the IDE. Then reupload this sketch to save new averages to the flash memory.*/void saveNetworkKnowledge() // Code for saving to flash memory....This file has been truncated, please download it to see its full contents.

    회로도

    Fritzing diagram for the circuit. Note that batteries would be attached on the left. The soil moisture sensors are optional. rainpoweredsmartirrigationsystem_OHtd4bVfb3.fzz

    제조공정

    1. 티타늄
    2. 캐스터네츠
    3. 접착제
    4. 스레드
    5. 아세틸렌
    6. 석면
    7. 주사위
    8. 주석
    9. 웹사이트를 통한 Raspberry Pi 자동 식물 관수
    10. Siemens, Bentley, 플랜트 디지털화 가속화 솔루션 출시