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

DasFilisera 스마트 온실: 고급 식물 생장 모니터링 시스템

부품 및 소모품

부품 수량 비고
DHT22 온도/습도 센서 1
DS18B20 방수 온도 센서 1
토양 온습도 센서 FS200-SHT25 1
4채널 릴레이 모듈 1
2채널 릴레이 모듈 1
초음파 거리 센서 HC-SR04 1
아두이노 MKR1000 1

앱 및 온라인 서비스

프로젝트 소개

식물의 환경 조건을 실시간으로 파악하며 더 스마트하게 식물과 채소를 재배하세요. 아두이노 MKR1000만 있으면 충분합니다.

DasFilisera 스마트 온실: 고급 식물 생장 모니터링 시스템

식물 생장에 필요한 환경 조건

식물 생장은 온도, 습도, 조도, 미네랄 영양분, 산소 등 여러 이상적인 환경 조건에 의존합니다.

온실에 적절한 양의 물을 공급하거나 적정 온도를 유지하는 것은 까다로운 과정이지만, 올바른 도구를 사용하면 훨씬 수월해집니다.

하드웨어 개요

DasFilisera 스마트 온실: 고급 식물 생장 모니터링 시스템

온도/습도 측정

TH1 – 외부 온도: 방수 DS18B20 센서 – D1 핀 연결

TH2 – 내부 온도/습도: DHT22 센서 – D0 핀 연결

TH3 – 토양 상태: FS200/SHT25 센서 – SCL/SDA 핀(12/11번) 연결

수위 측정

W1 – 수위 측정용 초음파 센서 HC-SR04 사용. Echo 핀 A0, Trigger 핀 A1 연결. 이 값으로 4채널 릴레이(R1)를 통해 밸브 제어 가능.

공기 온도/산소 제어

A1 – 온도/습도 값을 기반으로 창문 개폐 시점 결정 – R2 릴레이 사용. 기후 조건에 맞춰 임계값 조정 필요.

릴레이 R1 / R2

창문 개폐, 펌프 구동 등 각종 제어 명령을 릴레이로 전송. R1은 디지털 핀 7,8,9,10에 연결, R2는 핀 5,6에 연결.

DasFilisera 스마트 온실: 고급 식물 생장 모니터링 시스템

MKR1000 – aREST

모든 센서와 액추에이터를 연결한 후, aREST 라이브러리를 이용해 MKR1000에서 데이터를 수집하고 JSON 형식의 웹 인터페이스로 제공합니다. 제공된 라이브러리와 .ino 파일을 사용하고, 와이파이 라우터 설정에 맞게 수정하세요.

DasFilisera 스마트 온실: 고급 식물 생장 모니터링 시스템

데이터 및 인터페이스

장치 인터페이스가 준비되면 로컬 네트워크에서 데이터를 수집해 시각화할 수 있습니다.

Visual Studio 2015와 .NET으로 윈도우 애플리케이션을 제작해 온실의 실시간 상태, 일일 히스토리, 각종 로그를 확인할 수 있습니다.

DasFilisera 스마트 온실: 고급 식물 생장 모니터링 시스템
DasFilisera 스마트 온실: 고급 식물 생장 모니터링 시스템
DasFilisera 스마트 온실: 고급 식물 생장 모니터링 시스템
DasFilisera 스마트 온실: 고급 식물 생장 모니터링 시스템
DasFilisera 스마트 온실: 고급 식물 생장 모니터링 시스템

클라우드 저장은 DasData 온실 설정을 사용하거나 직접 데이터 채널을 생성하면 됩니다.

DasFilisera 스마트 온실: 고급 식물 생장 모니터링 시스템

애플리케이션 폴더의 Settings.txt에서 DsKey와 AKey를 수정하세요. 정상 작동하면 데이터가 온라인에 나타납니다.

DasFilisera 스마트 온실: 고급 식물 생장 모니터링 시스템

DasData의 해커스터 채널을 팔로우하면 향후 업데이트 소식을 받아볼 수 있습니다.

온실 자동화

온실 구성과 크기에 따라 어떤 밸브나 모터를 구동할지 결정하세요. 모든 제어는 릴레이를 통해 수행됩니다.

소스 코드

Filisera_Arduino (C/C++)

아두이노/지누이노 MKR1000 보드용 aREST 라이브러리 사용

/* DASFilisera using aREST Library for the Arduino/Genuino MKR1000 board.
aREST - Written in 2016 by Marco Schwartz under a GPL license. */
// 필수 라이브러리 임포트
#include 
#include 
#include 
#include "DHT.h"
#include 
#include 
#include 
#include 

// *************************
// ** 온도 센서들 **
// *************************
#define DHTPIN 0  // 내부 습도/온도/열지수
#define DHTTYPE DHT22  // DHT 22 (AM2302), AM2321
#define ONE_WIRE_BUS 1
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);

float umidSol = 0;  // 토양 습도
float umidAer = 0;  // 공기 습도
float tempIn = 0;   // 실내 온도
float tempOut = 0;  // 실외 온도
float tempSol = 0;  // 토양 온도
float umidexIn = 0; // 체감 온도

// 수위 측정용 초음파 센서
#define echoPin A0  // Echo 핀 A0
#define trigPin A1  // Trigger 핀 A1
long duration;      // 거리 계산을 위한 지속 시간
int HR_dist = 0;    // 계산된 거리
int minimumRange = 5;    // 최소 소나 범위
int maximumRange = 200;  // 최대 소나 범위
unsigned long pulseduration = 0;
int nivelCm, nivelRamasCm;
int nivelProc, nivelVol;
int empty = 100;
int full = 100;
int sqrLevel, sqrInvertLevel;

// 와이파이 상태
int status = WL_IDLE_STATUS;

// aREST 인스턴스 생성
aREST rest = aREST();

// 와이파이 설정
char ssid[] = "WIFI_AP";
char password[] = "WIFI_PASSW";

// 수신 대기 TCP 포트
#define LISTEN_PORT 80

// 서버 인스턴스 생성
WiFiServer server(LISTEN_PORT);

// 센서 초기화
DHT dht(DHTPIN, DHTTYPE);

// 릴레이 핀
int aVentil, aLateral;
int inReleu1Ventil = 6;
int inReleu2Ventil = 7;
int inReleu3Ventil = 8;
int inReleu4Ventil = 9;
int inReleu1Lateral = 10;
int inReleu2Lateral = 11;

// API로 노출할 함수 선언
int ledControl(String command);

void setup(void) {
  // 시리얼 시작
  Serial.begin(115200);

  // 변수 초기화 및 REST API 노출
  // rest.variable("temperature", &temperature);
  // rest.variable("humidity", &humidity);

  // 함수 노출
  rest.function("led", ledControl);

  // 장치 이름과 ID 설정
  rest.set_id("1");
  rest.set_name("mkr1000");

  // 와이파이 연결
  while (status != WL_CONNECTED) {
    Serial.print("Attempting to connect to SSID: ");
    Serial.println(ssid);
    status = WiFi.begin(ssid, password);
    // 연결 대기 10초
    delay(10000);
  }
  Serial.println("WiFi connected");

  // 서버 시작
  server.begin();
  Serial.println("Server started");

  // IP 주소 출력
  IPAddress ip = WiFi.localIP();
  Serial.print("IP Address: ");
  Serial.println(ip);

  // DHT 초기화 - 내부
  DHT dht(DHTPIN, DHTTYPE);
  // sensors.begin();  // 외부 온도 센서 시작

  pinMode(trigPin, OUTPUT);
  pinMode(echoPin, INPUT);

  // 변수 초기화 및 REST API 노출
  rest.variable("Vol_container", &sqrLevel);
  rest.variable("Umiditate_sol", &umidSol);
  rest.variable("Umiditate_aer", &umidAer);
  rest.variable("Temp_in", &tempIn);
  rest.variable("Temp_out", &tempOut);
  rest.variable("Temp_sol", &tempSol);
  // rest.variable("Umidex_in", &umidexIn);

  // sensors.requestTemperatures();  // 외부 온도 요청
}

void loop() {
  getmyDistance();  // 거리 측정
  // getSoilVals();  // 토양 값 읽기 (주석 처리됨)
  getInsideVals();  // 실내 값 읽기
  // getOutSideVals();  // 실외 값 읽기 (주석 처리됨)

  // REST 호출 처리
  WiFiClient client = server.available();
  if (!client) {
    return;
  }
  while (!client.available()) {
    delay(1);
  }
  rest.handle(client);
}

void getmyDistance() {
  digitalWrite(trigPin, LOW);
  delayMicroseconds(2);
  digitalWrite(trigPin, HIGH);
  delayMicroseconds(10);
  digitalWrite(trigPin, LOW);
  duration = pulseIn(echoPin, HIGH);
  // 거리 계산
  HR_dist = duration / 58.2;
  // sqrLevel = empty - HR_dist;
  if (HR_dist >= maximumRange || HR_dist <= minimumRange) {
    sqrLevel = 0;
  } else {
    sqrLevel = empty - HR_dist;
    Serial.println(HR_dist);
  }
  delay(100);
}

void getDistance() {
  digitalWrite(trigPin, LOW);
  delayMicroseconds(10);
  // 10µs 펄스 전송으로 Ping 활성화
  digitalWrite(trigPin, HIGH);
  delayMicroseconds(10);
  digitalWrite(trigPin, LOW);
  // 수신 펄스 길이 측정
  pulseduration = pulseIn(echoPin, HIGH);
  // 펄스 길이의 절반
  pulseduration = pulseduration / 2;
  // 센티미터로 변환
  nivelRamasCm = int(pulseduration / 29);
  nivelCm = empty - nivelRamasCm;
  nivelVol = map(nivelRamasCm, full, empty, 100, 0);
  // 센티미터 단위 수위 출력
  if (nivelCm >= -5 && nivelCm <= 135) {
    double a = nivelCm / 100 * nivelVol;
    int sqrLevel = 240 - nivelCm;
    int sqrInvertLevel = 120 + nivelRamasCm;
    if (nivelCm > 65 && nivelCm <= 85) {
    }
    if (nivelCm > 85 && nivelCm <= 100) {
    }
  }
}

long microsecondsToCentimeters(long microseconds) {
  // 음속 340m/s = 29µs/cm
  // 왕복 거리이므로 절반으로 나눔
  return microseconds / 29 / 2;
}

void getInsideVals() {
  float h = dht.readHumidity();  // 습도 읽기
  float t = dht.readTemperature();  // 섭씨 온도 읽기
  // float f = dht.readTemperature(true);  // 화씨 온도 읽기
  umidAer = h;
  tempIn = t;
  // 읽기 실패 시 조기 리턴
  if (isnan(h) || isnan(t)) {
    Serial.println("Failed to read from DHT sensor!");
    return;
  }
  // 화씨 열지수 계산 (기본값)
  // float hif = dht.computeHeatIndex(f, h);
  // 섭씨 열지수 계산 (isFahreheit = false)
  // float hic = dht.computeHeatIndex(t, h, false);
  // umidexIn = hic;
}

void getOutSideVals() {
  tempOut = sensors.getTempCByIndex(0);
  Serial.println("Temperature Out: ");
  Serial.print(tempOut);
}

void getSoilVals() {
  umidSol = SHT2x.GetHumidity();
  tempSol = SHT2x.GetTemperature();
  Serial.println("Humidity Soil(%RH): ");
  Serial.print(umidSol);
  Serial.print(" Temperature Soil (C): ");
  Serial.print(tempSol);
}

// sensors.requestTemperatures();  // 외부 온도 요청

// API로 접근 가능한 커스텀 함수
int ledControl(String command) {
  // 명령에서 상태 가져오기
  int state = command.toInt();
  digitalWrite(6, state);
  return 1;
}

libraries.zip (C/C++)

Filisera에서 사용된 라이브러리 모음 (다운로드만 가능)

Filisera - vb.zip (VBScript)

.NET Visual Studio 프로젝트 (다운로드만 가능)

Filisera - VS (VBScript)

아두이노에서 데이터를 읽어 인터페이스를 표시하는 .NET 파일

Imports System.Globalization
Imports System.IO
Imports System.Net
Imports System.Threading
Imports System.Windows.Forms.DataVisualization.Charting
Imports Newtonsoft.Json

Public Class Form1
    Private _deviceIP As String = ""  ' 장치 IP
    Private intVolumContainer, intUmidSol, intUmidSera, intTempAfara, intTempSera, intTempSol, intUmidex As String  ' 변수들
    Private strR1, strR2 As String  ' 릴레이
    Public Count As CountDown  ' 카운트다운 타이머
    Private _dasResult As String = ""  ' 장치 센서 읽기 결과
    Private _AKey As String = ""  ' DasData 사용자 키
    Private _DSKey As String = ""  ' DasData 데이터셋 키
    Private _myDas As New dasData.das

    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        Count = New CountDown(50, 0)  ' 5초 업데이트 주기
        AddHandler Count.Tick, AddressOf Count_Tick
        AddHandler Count.TimesOut, AddressOf Times_up
        Try
            ' Settings.txt에서 설정 읽기
            Dim path As String = Directory.GetCurrentDirectory()
            Dim FILE_NAME As String = path & "\Settings.txt"
            Dim myText As String = ""
            If System.IO.File.Exists(FILE_NAME) = True Then
                Dim objReader As New System.IO.StreamReader(FILE_NAME, System.Text.Encoding.Default)
                Do While objReader.Peek() <> -1
                    myText &= objReader.ReadLine()
                Loop
                Dim _settingItems() As String = myText.Split(" ")
                _deviceIP = _settingItems(0)  ' 장치 IP
                _AKey = _settingItems(1).Replace("akey:", "")
                _DSKey = _settingItems(2).Replace("dskey:", "")
                cbxEnabled.Text = "Device: " & _deviceIP
                txtInfo.Text = "IP device: " & _deviceIP & vbNewLine & "AKey: " & _AKey & vbNewLine & "DSKey: " & _DSKey & vbNewLine
                strR1 = _settingItems(3).Replace("relay1:", "")
                txtInfo.Text += "Relay1: " & strR1 & vbNewLine
                strR2 = _settingItems(4).Replace("relay2:", "")
                txtInfo.Text += "Relay2: " & strR2 & vbNewLine
                objReader.Dispose()
                objReader.Close()
            End If
        Catch ex As Exception
            lblDevice.Text = ex.Message.ToString
        End Try
        cmdCheckDevice()  ' 로컬 설정
        Thread.CurrentThread.CurrentCulture = New CultureInfo("en-US")
        ' Thread.CurrentThread.CurrentUICulture = New CultureInfo("ro-RO")
        cmdStartFilisera()
    End Sub

    Private Sub Count_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs)
        cmdGetSensorValues()
        cmdTriggers()
        If CDate(dtFrom.Text).ToString("dd.MM.yyyy") = Date.Now().ToString("dd.MM.yyyy") Then
            cmdStartFilisera()
        End If
    End Sub

    Private Sub Times_up(ByVal sender As System.Object, ByVal e As System.EventArgs)
        ' Count.Reset()
        ' Count.Pause()
    End Sub

    Private Sub cmdStartFilisera()
        Try
            dtFrom.MaxDate = DateTime.Now
            _dasResult = _myDas.getDas(_DSKey, "json", 0, 100)
            cmdFillData()
        Catch ex As Exception
            lblDevice.Text += ex.Message.ToString
        End Try
    End Sub

    Private Sub cbxEnabled_CheckedChanged(sender As Object, e As EventArgs) Handles cbxEnabled.CheckedChanged
        cmdCheckDevice()
    End Sub

    Private Sub cmdCheckDevice()
        Try
            If cbxDemo.Checked = False Then
                lblDevice.Text = ("Enable device!")
                lblEvenimente.Text = Date.Now.ToString("dd.MM.yyyy HH:mm:ss")
                If cbxEnabled.Checked = True Then
                    Dim pingsender As New Net.NetworkInformation.Ping
                    If Not pingsender.Send(_deviceIP).Status = Net.NetworkInformation.IPStatus.Success Then
                        lblDevice.Text = ("Device not availble on the local network!")
                        cbxEnabled.Checked = False
                        btnTemperatura.Enabled = False
                        btnVolumContainer.Enabled = False
                        Count.Reset()
                        Count.Pause()
                        MessageBox.Show("Device at " & _deviceIP & " not found!")
                    Else
                        lblDevice.Text = ("Device connected!")
                        btnTemperatura.Enabled = True
                        btnVolumContainer.Enabled = True
                        cmdGetSensorValues()
                        Timer1.Enabled = True
                        cmdAddData()
                        Count.Start()
                    End If
                Else
                End If
            Else
                btnTemperatura.Enabled = True
                btnVolumContainer.Enabled = True
                cmdGetSensorValues()
                Timer1.Enabled = True
                cmdAddData()
                Count.Start()
            End If
        Catch ex As Exception
        End Try
    End Sub

    Private Sub btnVolumContainer_Click(sender As Object, e As EventArgs) Handles btnVolumContainer.Click
        ' https://192.168.0.102/digital/7/1
        ' 버튼으로 물 차단
        Dim _ItemsR1() As String = strR1.Split(",")
        If btnVolumContainer.Text.Contains("Open") Then
            cmdRelay(_ItemsR1(0), 1)
            cmdRelay(_ItemsR1(1), 1)
            cmdRelay(_ItemsR1(2), 0)
            cmdRelay(_ItemsR1(3), 0)
            btnVolumContainer.Text = "Close water"
        Else
            cmdRelay(_ItemsR1(0), 0)
            cmdRelay(_ItemsR1(1), 0)
            cmdRelay(_ItemsR1(2), 1)
            cmdRelay(_ItemsR1(3), 1)
            btnVolumContainer.Text = "Open water"
        End If
    End Sub

    Private Sub btnTemperatura_Click(sender As Object, e As EventArgs) Handles btnTemperatura.Click
        ' 버튼으로 창문 차단
        Dim _ItemsR2() As String = strR2.Split(",")
        If btnTemperatura.Text.Contains("Open") Then
            cmdRelay(_ItemsR2(0), 1)
            cmdRelay(_ItemsR2(1), 1)
            btnTemperatura.Text = "Close window"
        Else
            cmdRelay(_ItemsR2(0), 0)
            cmdRelay(_ItemsR2(1), 0)
            btnTemperatura.Text = "Open window"
        End If
    End Sub

    Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick
        cmdAddData()
    End Sub

    Private Sub btnTestCloud_Click(sender As Object, e As EventArgs) Handles btnTestCloud.Click
        Try
            cmdStartFilisera()
        Catch ex As Exception
            MessageBox.Show("Lost connection with DasData!")
        End Try
    End Sub

    Private Function cmdRelay(ByVal _DPin As String, ByVal _cmd As Int16)
        Try
            Dim _urlCommand As String = _deviceIP & "/digital/" & _DPin & "/" & _cmd
            Dim client As New WebClient()
            client.Headers.Add("user-agent", "Arduino/4.0 (compatible; MSIE 6.0; Windows NT 5.2; .NET CLR 1.0.3705;)")
            Dim data As Stream = client.OpenRead(_urlCommand)
            Dim reader As New StreamReader(data)
            Dim s As String = reader.ReadToEnd()
            ' txtInfo.Text += (s)
            data.Close()
            reader.Close()
        Catch ex As Exception
        End Try
    End Function

    Private Sub dtFrom_ValueChanged(sender As Object, e As EventArgs) Handles dtFrom.ValueChanged
        Try
            ' 날짜 선택 기반 데이터 조회
            _dasResult = _myDas.getDas(_DSKey, "jsond", CDate(dtFrom.Text).ToString("dd.MM.yyyy"), CDate(dtFrom.Text).ToString("dd.MM.yyyy"))
            cmdFillData()
        Catch ex As Exception
            MessageBox.Show(ex.Message.ToString)
        End Try
    End Sub

    Private Sub cmdGetSensorValues()
        Try
            ' 장치에서 센서 값 읽기
            If cbxDemo.Checked = False Then
                Dim client As New WebClient()
                client.Headers.Add("user-agent", "Arduino/4.0 (compatible; MSIE 6.0; Windows NT 5.2; .NET CLR 1.0.3705;)")
                Dim data As Stream = client.OpenRead("https://" & _deviceIP & "/index.html")
                Dim reader As New StreamReader(data)
                Dim s As String = reader.ReadToEnd()
                s = s.Replace("""", "").Replace("}", "").Replace("{", "").Replace(" ", "").Replace("variables:", "")
                Dim sItems() As String = s.Split(",")
                intVolumContainer = cmdGetVal(sItems(0))
                intUmidSol = cmdGetVal(sItems(1))
                intUmidSera = cmdGetVal(sItems(2))
                intTempSera = cmdGetVal(sItems(3))
                intTempAfara = cmdGetVal(sItems(4))
                intTempSol = cmdGetVal(sItems(5))
                data.Close()
                reader.Close()
            Else
                intVolumContainer = _rnd(60)
                intUmidSol = _rnd(80)
                intUmidSera = _rnd(20)
                intTempSera = _rnd(45)
                intTempAfara = _rnd(57)
                intTempSol = _rnd(66)
            End If
            ggVolum.Value = intVolumContainer
            rgVolum.Value = intVolumContainer
            ggUmidSol.Value = intUmidSol
            ggUmidSera.Value = intUmidSera
            ggTempSera.Value = intTempSera
            ggTempOut.Value = intTempAfara
            ggTempSol.Value = intTempSol
        Catch ex As Exception
            ' {"variables" {"Volum_container": 0, "Umiditate_sol": 0.00, "Umiditate_aer": 36.60, "Temp_in": 26.50, "Temp_out": 0.00, "Temp_sol": 0.00, "Umidex_in": 26.37}, "id": "1", "name": "FiliSera", "hardware": "arduino", "connected": true}
        End Try
    End Sub

    Private Function cmdGetVal(ByVal _sItem As String)
        Try
            ' 문자열 분할 후 값 추출
            Dim _s() As String = _sItem.Split(":")
            Return _s(1)
        Catch ex As Exception
        End Try
    End Function

    Private Sub cmdAddData()
        Try
            ' DasData 클라우드 스토리지로 데이터 전송
            Dim _strFiliseraDataSend As String = intVolumContainer & "|" & intUmidSol & "|" & intUmidSera & "|" & intTempAfara & "|" & intTempSera & "|" & intTempSol
            '& "|" & intUmidex & "|"
            Dim _dasResult As String = _myDas.sendDas(_strFiliseraDataSend, _DSKey, _AKey)
        Catch ex As Exception
            cmdLogMe("ERROR..." & ex.Message.ToString(), "error")
        End Try
    End Sub

    Private Sub cmdFillData()
        Try
            ' 인터페이스에 모든 데이터 채우기
            Dim dataSet As DataSet = JsonConvert.DeserializeObject(Of DataSet)(_dasResult)
            Dim dataTable As DataTable = dataSet.Tables(0)
            ' 그리드뷰
            DataGridView1.DataSource = dataSet.Tables(0)
            DataGridView1.AutoGenerateColumns = True
            ' 차트
            ChartTemp.DataSource = dataTable
            ChartTemp.Series.Clear()
            chartUmid.DataSource = dataTable
            chartUmid.Series.Clear()
            chartVolum.DataSource = dataTable
            chartVolum.Series.Clear()
            Dim i As Integer = 0
            Dim j As Integer = 0
            Dim k As Integer = 0
            For Each table In dataSet.Tables
                For Each row In table.Rows
                    For Each col In table.Columns
                        Dim colName As String = col.ColumnName.ToString
                        If colName <> "id" And colName <> "AIDate" Then
                            Try
                                Dim serieName As String = RTrim(colName)
                                ' 수위
                                If colName.Contains("Nivel") Then
                                    chartVolum.Series.Add(serieName)
                                    chartVolum.Series(serieName).LabelFormat = "N1"
                                    chartVolum.Series(i).ChartType = SeriesChartType.Line
                                    chartVolum.Series(i).BorderWidth = 2
                                    chartVolum.Series(i).BorderDashStyle = ChartDashStyle.Solid
                                    chartVolum.Series(serieName).YValueMembers = RTrim(colName)
                                    chartVolum.Series(serieName).XValueMember = "AIDate"
                                    i += 1
                                End If
                                ' 습도
                                If colName.Contains("Umid") Then
                                    chartUmid.Series.Add(serieName)
                                    chartUmid.Series(serieName).LabelFormat = "N1"
                                    chartUmid.Series(j).ChartType = SeriesChartType.Line
                                    chartUmid.Series(j).BorderWidth = 2
                                    chartUmid.Series(j).BorderDashStyle = ChartDashStyle.Solid
                                    chartUmid.Series(serieName).YValueMembers = RTrim(colName)
                                    chartUmid.Series(serieName).XValueMember = "AIDate"
                                    j += 1
                                End If
                                ' 온도
                                If colName.Contains("Temp") Then
                                    ChartTemp.Series.Add(serieName)
                                    ChartTemp.Series(serieName).LabelFormat = "N1"
                                    ChartTemp.Series(k).ChartType = SeriesChartType.Line
                                    ChartTemp.Series(k).BorderWidth = 2
                                    ChartTemp.Series(k).BorderDashStyle = ChartDashStyle.Solid
                                    ChartTemp.Series(serieName).YValueMembers = RTrim(colName)
                                    ChartTemp.Series(serieName).XValueMember = "AIDate"
                                    k += 1
                                End If
                            Catch ex As Exception
                            End Try
                        End If
                    Next
                    Exit For
                Next
            Next
            ' 차트 데이터 바인딩
            ChartTemp.DataBind()
            ChartTemp.Visible = True
            chartUmid.DataBind()
            chartUmid.Visible = True
            chartVolum.DataBind()
            chartVolum.Visible = True
        Catch ex As Exception
            cmdLogMe("ERROR..." & ex.Message.ToString(), "error")
        End Try
    End Sub

    Private Sub cmdTriggers()
        ' 트리거 설정 및 로그 저장
        Select Case intVolumContainer
            Case > 80
                cmdLogMe("HIGH HIGH - Container volume - stop water", "0")
            Case > 70
                ' cmdLogMe("HIGH - Container volume - water will start", "1")
            Case < 20
                ' cmdLogMe("LOW - Container volume low - water will stop", "1")
            Case < 10
                cmdLogMe("LOW LOW - Container volume high high high - start water", "0")
        End Select
        Select Case intTempSera
            Case > 38
                cmdLogMe("HIGH HIGH - Temperature in green house - open windows", "0")
            Case > 30
                ' cmdLogMe("HIGH - Temperature in green house - prepare windows", "1")
            Case < 10
                ' cmdLogMe("LOW - Temperature in green house - prepare windows", "1")
            Case < 10
                cmdLogMe("LOW LOW - Container volume high high high - start water", "0")
        End Select
    End Sub

    Public Function _rnd(ByVal n As Integer) As Integer
        ' 난수 생성기 초기화
        Dim r As New Random(System.DateTime.Now.Millisecond)
        Return r.Next(1, n)
    End Function

    Private Sub cmdLogMe(message As String, _type As String)
        Try
            Dim _strLog As String = "adeewdf4-4aa34-14ass24-8436-aea1"  ' 로그용 DasData DS 키
            lstEvenimente.Items.Add((System.DateTime.Now & " " & message) + Constants.vbNewLine)
            ' DasData에 로그 저장
            _myDas.sendDas(message & "|" & _type, _strLog, _AKey)
        Catch ex As Exception
            cmdLogMe("ERROR..." & ex.Message.ToString(), "error")
        End Try
    End Sub
End Class

소스 파일 – Filisera

https://github.com/dasdata/DasFilisera

회로도

센서 및 릴레이 연결 PDF 파일

제조공정

  1. 5달러 I2C 센서로 라즈베리 파이 온도 로거 만들기
  2. 라즈베리 파이 다중 DS18B20 1-와이어 센서 연결으로 정확한 온도 모니터링
  3. 라즈베리 파이와 TMP006 적외선 온도 센서: 파이썬 라이브러리 및 설정 가이드
  4. 라즈베리 파이와 파이썬으로 원격 온도 센서 만들기 – 단계별 가이드
  5. DS1820 원와이어 온도 센서를 라즈베리 파이 GPIO로 연결하는 방법
  6. DS18B20 원와이어 디지털 온도계를 라즈베리 파이에 연결하기 – 단계별 가이드
  7. 라즈베리 파이 & DS18B20으로 다중 센서 온도 & 조도 모니터링 시스템 구축
  8. MCP9808, InfluxDB, Grafana로 라즈베리 파이 홈 온도 모니터 구축하기
  9. 정밀 베어링 온도 센서/검출기(BTD): 원리, 설치, SKF 제품군
  10. NASA 고다드 랩온칩 센서: 실시간 유량·온도 모니터링