첨부 실행 코드는 나눔고딕코딩 폰트를 사용합니다.
유용한 소스 코드가 있으면 icodebroker@naver.com으로 보내주시면 감사합니다.
블로그 자료는 자유롭게 사용하세요.

728x90
반응형

▶ 부품 내역

구분 모델 수량 비고
SENSOR/TEMPERATURE DHT11 1  

▶ 회로 구성도

▶ MainPage.xaml

<Page x:Class="TestProject.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d"
    RequestedTheme="Dark">
    <Page.Resources>
        <Thickness x:Key="DashboardBorderMarginKey">3 3 3 3</Thickness>
        <Thickness x:Key="DashboardBorderThicknessKey">2</Thickness>
        <SolidColorBrush x:Key="DashboardBorderBrushKey">#ff0063b1</SolidColorBrush>
        <x:Double x:Key="DashboardFontSizeKey">25</x:Double>
        <SolidColorBrush x:Key="DashboardHeaderTextBrushKey">#ff0063b1</SolidColorBrush>
        <SolidColorBrush x:Key="DashboardTextBrushKey">White</SolidColorBrush>
        <SolidColorBrush x:Key="DisplayHeaderTextBrushKey">Yellow</SolidColorBrush>
        <SolidColorBrush x:Key="DisplayTextBrushKey">White</SolidColorBrush>
    </Page.Resources>
    <Grid Background="Black">
        <Grid.RowDefinitions>
            <RowDefinition Height="1*" />
            <RowDefinition Height="3*" />
        </Grid.RowDefinitions>
        <Grid Grid.Row="0">
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="*" />
                <ColumnDefinition Width="*" />
                <ColumnDefinition Width="*" />
                <ColumnDefinition Width="*" />
                <ColumnDefinition Width="*" />
            </Grid.ColumnDefinitions>
            <Grid.RowDefinitions>
                <RowDefinition Height="*" />
                <RowDefinition Height="*" />
            </Grid.RowDefinitions>
            <Border Grid.Column="0" Grid.Row="0"
                Margin="{StaticResource DashboardBorderMarginKey}"
                BorderThickness="{StaticResource DashboardBorderThicknessKey}"
                BorderBrush="{StaticResource DashboardBorderBrushKey}">
                <TextBlock
                    HorizontalAlignment="Center"
                    VerticalAlignment="Center"
                    FontSize="{StaticResource DashboardFontSizeKey}"
                    Foreground="{StaticResource DashboardHeaderTextBrushKey}"
                    TextWrapping="WrapWholeWords"
                    Text="시도 건수" />
            </Border>
            <Border Grid.Column="0" Grid.Row="1"
                Margin="{StaticResource DashboardBorderMarginKey}"
                BorderThickness="{StaticResource DashboardBorderThicknessKey}"
                BorderBrush="{StaticResource DashboardBorderBrushKey}">
                <TextBlock x:Name="attemptCountTextBlock"
                    HorizontalAlignment="Center"
                    VerticalAlignment="Center"
                    FontSize="{StaticResource DashboardFontSizeKey}"
                    Foreground="{StaticResource DashboardTextBrushKey}"
                    TextWrapping="WrapWholeWords" />
            </Border>

            <Border Grid.Column="1" Grid.Row="0"
                Margin="{StaticResource DashboardBorderMarginKey}"
                BorderThickness="{StaticResource DashboardBorderThicknessKey}"
                BorderBrush="{StaticResource DashboardBorderBrushKey}">
                <TextBlock
                    HorizontalAlignment="Center"
                    VerticalAlignment="Center"
                    FontSize="{StaticResource DashboardFontSizeKey}"
                    Foreground="{StaticResource DashboardHeaderTextBrushKey}"
                    TextWrapping="WrapWholeWords"
                    Text="평균 재시도 건수" />
            </Border>
            <Border Grid.Column="1" Grid.Row="1"
                Margin="{StaticResource DashboardBorderMarginKey}"
                BorderThickness="{StaticResource DashboardBorderThicknessKey}"
                BorderBrush="{StaticResource DashboardBorderBrushKey}" >
                <TextBlock x:Name="averageRetryCountTextBlock"
                    HorizontalAlignment="Center"
                    VerticalAlignment="Center"
                    FontSize="{StaticResource DashboardFontSizeKey}"
                    Foreground="{StaticResource DashboardTextBrushKey}"
                    TextWrapping="WrapWholeWords" />
            </Border>

            <Border Grid.Column="2" Grid.Row="0"
                Margin="{StaticResource DashboardBorderMarginKey}"
                BorderThickness="{StaticResource DashboardBorderThicknessKey}"
                BorderBrush="{StaticResource DashboardBorderBrushKey}">
                <TextBlock
                    HorizontalAlignment="Center"
                    VerticalAlignment="Center"
                    FontSize="{StaticResource DashboardFontSizeKey}"
                    Foreground="{StaticResource DashboardHeaderTextBrushKey}"
                    TextWrapping="WrapWholeWords"
                    Text="성공 건수" />
            </Border>
            <Border Grid.Column="2" Grid.Row="1"
                Margin="{StaticResource DashboardBorderMarginKey}"
                BorderThickness="{StaticResource DashboardBorderThicknessKey}"
                BorderBrush="{StaticResource DashboardBorderBrushKey}">
                <TextBlock x:Name="successCountTextBlock"
                    HorizontalAlignment="Center"
                    VerticalAlignment="Center"
                    FontSize="{StaticResource DashboardFontSizeKey}"
                    Foreground="{StaticResource DashboardTextBrushKey}"
                    TextWrapping="WrapWholeWords" />
            </Border>

            <Border Grid.Column="3" Grid.Row="0"
                Margin="{StaticResource DashboardBorderMarginKey}"
                BorderThickness="{StaticResource DashboardBorderThicknessKey}"
                BorderBrush="{StaticResource DashboardBorderBrushKey}">
                <TextBlock
                    HorizontalAlignment="Center"
                    VerticalAlignment="Center"
                    FontSize="{StaticResource DashboardFontSizeKey}"
                    Foreground="{StaticResource DashboardHeaderTextBrushKey}"
                    TextWrapping="WrapWholeWords"
                    Text="성공율" />
            </Border>
            <Border Grid.Column="3" Grid.Row="1"
                Margin="{StaticResource DashboardBorderMarginKey}"
                BorderThickness="{StaticResource DashboardBorderThicknessKey}"
                BorderBrush="{StaticResource DashboardBorderBrushKey}">
                <TextBlock x:Name="successRateTextBlock"
                    HorizontalAlignment="Center"
                    VerticalAlignment="Center"
                    FontSize="{StaticResource DashboardFontSizeKey}"
                    Foreground="{StaticResource DashboardTextBrushKey}"
                    TextWrapping="WrapWholeWords" />
            </Border>

            <Border Grid.Column="4" Grid.Row="0"
                Margin="{StaticResource DashboardBorderMarginKey}"
                BorderThickness="{StaticResource DashboardBorderThicknessKey}"
                BorderBrush="{StaticResource DashboardBorderBrushKey}">
                <TextBlock
                    HorizontalAlignment="Center"
                    VerticalAlignment="Center"
                    FontSize="{StaticResource DashboardFontSizeKey}"
                    Foreground="{StaticResource DashboardHeaderTextBrushKey}"
                    TextWrapping="WrapWholeWords"
                    Text="비율" />
            </Border>
            <Border Grid.Column="4" Grid.Row="1"
                Margin="{StaticResource DashboardBorderMarginKey}"
                BorderThickness="{StaticResource DashboardBorderThicknessKey}"
                BorderBrush="{StaticResource DashboardBorderBrushKey}">
                <TextBlock x:Name="rateTextBlock"
                    HorizontalAlignment="Center"
                    VerticalAlignment="Center"
                    FontSize="{StaticResource DashboardFontSizeKey}"
                    Foreground="{StaticResource DashboardTextBrushKey}"
                    TextWrapping="WrapWholeWords" />
            </Border>
        </Grid>
        <Grid Grid.Row="1">
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="*" />
                <ColumnDefinition Width="*" />
            </Grid.ColumnDefinitions>
            <Grid.RowDefinitions>
                <RowDefinition Height="*" />
                <RowDefinition Height="*" />
                <RowDefinition Height="*" />
            </Grid.RowDefinitions>
            <TextBlock Grid.Column="0" Grid.Row="0"
                HorizontalAlignment="Center"
                VerticalAlignment="Bottom"
                FontSize="50"
                Foreground="{StaticResource DisplayHeaderTextBrushKey}"
                Text="습도" />
            <TextBlock x:Name="humidityTextBlock" Grid.Column="0" Grid.Row="1"
                HorizontalAlignment="Center"
                VerticalAlignment="Top"
                Margin="10 10 10 10"
                FontSize="90"
                Foreground="{StaticResource DisplayTextBrushKey}" />

            <TextBlock Grid.Column="1" Grid.Row="0"
                HorizontalAlignment="Center"
                VerticalAlignment="Bottom"
                FontSize="50"
                Foreground="{StaticResource DisplayHeaderTextBrushKey}"
                Text="온도" />
            <TextBlock x:Name="temperatureTextBlock" Grid.Column="1" Grid.Row="1"
                Margin="10 10 10 10"
                HorizontalAlignment="Center"
                VerticalAlignment="Top"
                FontSize="90"
                Foreground="{StaticResource DisplayTextBrushKey}" />

            <TextBlock Grid.Column="0" Grid.Row="2"
                HorizontalAlignment="Right"
                VerticalAlignment="Center"
                Margin="0 0 20 0"
                FontSize="35"
                Foreground="{StaticResource DisplayHeaderTextBrushKey}"
                Text="최근 갱신 일시 :" />
            <TextBlock x:Name="lastUpdatedOffsetTextBlock" Grid.Column="1" Grid.Row="2"
                HorizontalAlignment="Left"
                VerticalAlignment="Center"
                Margin="20 0 0 0"
                FontSize="35"
                Foreground="{StaticResource DisplayTextBrushKey}" />
        </Grid>
    </Grid>
</Page>

 

▶ MainPage.xaml.cs

using System;
using System.Collections.Generic;
using System.Linq;
using Windows.Devices.Gpio;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Navigation;

using Sensors.DHT;

namespace TestProject
{
    /// <summary>
    /// 메인 페이지
    /// </summary>
    public sealed partial class MainPage : Page
    {
        //////////////////////////////////////////////////////////////////////////////////////////////////// Field
        ////////////////////////////////////////////////////////////////////////////////////////// Field

        #region Field

        /// <summary>
        /// 디스패처 타이머
        /// </summary>
        private DispatcherTimer dispatcherTimer = null;

        /// <summary>
        /// DHT 인터페이스
        /// </summary>
        private IDHT dht = null;

        /// <summary>
        /// GPIO 핀
        /// </summary>
        private GpioPin gpioPin = null;

        /// <summary>
        /// 현재 일시 오프셋
        /// </summary>
        private DateTimeOffset currentDateTimeOffset = DateTimeOffset.MinValue;


        /// <summary>
        /// 시도 건수
        /// </summary>
        private int attemptCount = 0;

        /// <summary>
        /// 재시도 카운트 리스트
        /// </summary>
        private List<int> retryCountList = new List<int>();

        /// <summary>
        /// 성공 건수
        /// </summary>
        private int successCount = 0;

        /// <summary>
        /// 습도
        /// </summary>
        private float humidity = 0f;

        /// <summary>
        /// 온도
        /// </summary>
        private float temperature = 0f;

        /// <summary>
        /// 최근 갱신 오프셋
        /// </summary>
        private DateTimeOffset lastUpdatedOffset = DateTimeOffset.MinValue;

        #endregion

        //////////////////////////////////////////////////////////////////////////////////////////////////// Constructor
        ////////////////////////////////////////////////////////////////////////////////////////// Public

        #region 생성자 - MainPage()

        /// <summary>
        /// 생성자
        /// </summary>
        public MainPage()
        {
            InitializeComponent();


            this.dispatcherTimer = new DispatcherTimer();

            this.dispatcherTimer.Interval = TimeSpan.FromSeconds(1);

            this.dispatcherTimer.Tick += dispatcherTimer_Tick;
        }

        #endregion

        //////////////////////////////////////////////////////////////////////////////////////////////////// Method
        ////////////////////////////////////////////////////////////////////////////////////////// Protected

        #region 네비게이션 올 때 처리하기 - OnNavigatedTo(e)

        /// <summary>
        /// 네비게이션 올 때 처리하기
        /// </summary>
        /// <param name="e">이벤트 인자</param>
        protected override void OnNavigatedTo(NavigationEventArgs e)
        {
            base.OnNavigatedTo(e);

            GpioController gpioController = GpioController.GetDefault();

            if(gpioController != null)
            {
                this.gpioPin = gpioController.OpenPin(17, GpioSharingMode.Exclusive);

                this.dht = new DHT11(this.gpioPin, GpioPinDriveMode.Input);

                this.dispatcherTimer.Start();

                this.currentDateTimeOffset = DateTimeOffset.Now;
            }
        }

        #endregion
        #region 네비게이션 갈 때 처리하기 - OnNavigatedFrom(e)

        /// <summary>
        /// 네비게이션 갈 때 처리하기
        /// </summary>
        /// <param name="e">이벤트 인자</param>
        protected override void OnNavigatedFrom(NavigationEventArgs e)
        {
            this.dispatcherTimer.Stop();

            if(this.gpioPin != null)
            {
                this.gpioPin.Dispose();

                this.gpioPin = null;
            }

            this.dht = null;

            base.OnNavigatedFrom(e);
        }

        #endregion

        ////////////////////////////////////////////////////////////////////////////////////////// Private
        //////////////////////////////////////////////////////////////////////////////// Event

        #region 디스패처 타이머 틱 처리하기 - dispatcherTimer_Tick(sender, e)

        /// <summary>
        /// 디스패처 타이머 틱 처리하기
        /// </summary>
        /// <param name="sender">이벤트 발생자</param>
        /// <param name="e">이벤트 인자</param>
        private async void dispatcherTimer_Tick(object sender, object e)
        {
            try
            {
                this.dispatcherTimer.Stop();

                DHTReading dhtReading = await this.dht.GetReadingAsync().AsTask();

                #region 시도 건수를 표시한다.

                this.attemptCount++;

                this.attemptCountTextBlock.Text = string.Format("{0:0}", this.attemptCount);

                #endregion
                #region 평균 재시도 건수를 표시한다.

                this.retryCountList.Add(dhtReading.RetryCount);

                int averageRetryCount = 0;

                if(this.retryCountList.Count() > 0)
                {
                    averageRetryCount = (int)this.retryCountList.Average();
                }

                this.averageRetryCountTextBlock.Text = string.Format("{0:0}", averageRetryCount);

                #endregion
                #region 성공 건수를 표시한다.

                if(dhtReading.IsValid)
                {
                    this.successCount++;
                }

                this.successCountTextBlock.Text = string.Format("{0:0}", this.successCount);

                #endregion
                #region 성공율을 표시한다.

                this.successRateTextBlock.Text = attemptCount > 0 ? string.Format("{0:0.0}%", 100f * (float)this.successCount / (float)attemptCount) : "0.0%";

                #endregion
                #region 비율을 표시한다.

                double totalSecondCount = DateTimeOffset.Now.Subtract(this.currentDateTimeOffset).TotalSeconds;

                double rate = this.successCount / totalSecondCount;

                this.rateTextBlock.Text = rate < 1 ? string.Format("{0:0.00} 초/읽기", 1d / rate) : string.Format("{0:0.00} 읽기/초", rate);

                #endregion

                if(dhtReading.IsValid)
                {
                    #region 습도를 표시한다.

                    this.humidity = Convert.ToSingle(dhtReading.Humidity);

                    this.humidityTextBlock.Text = string.Format("{0:0.0}% RH", this.humidity);

                    #endregion
                    #region 온도를 표시한다.

                    this.temperature = Convert.ToSingle(dhtReading.Temperature);

                    this.temperatureTextBlock.Text = string.Format("{0:0.0} ℃", this.temperature);

                    #endregion
                    #region 최근 갱신 일시를 표시한다.

                    this.lastUpdatedOffset = DateTimeOffset.Now;

                    this.lastUpdatedOffsetTextBlock.Text = GetLastUpdatedOffsetString();

                    #endregion
                }
            }
            finally
            {
                this.dispatcherTimer.Start();
            }
        }

        #endregion

        //////////////////////////////////////////////////////////////////////////////// Function

        #region 최근 갱신 오프셋 문자열 구하기 - GetLastUpdatedOffsetString()

        /// <summary>
        /// 최근 갱신 오프셋 문자열 구하기
        /// </summary>
        private string GetLastUpdatedOffsetString()
        {
            string returnValue = string.Empty;

            TimeSpan elapsed = DateTimeOffset.Now.Subtract(this.lastUpdatedOffset);

            if(this.lastUpdatedOffset == DateTimeOffset.MinValue)
            {
                returnValue = "미갱신";
            }
            else if(elapsed.TotalSeconds < 60d)
            {
                int totalSecondCount = (int)elapsed.TotalSeconds;

                if(totalSecondCount < 2)
                {
                    returnValue = "방금 갱신";
                }
                else
                {
                    returnValue = string.Format("{0:0} {1} 전", totalSecondCount, totalSecondCount == 1 ? "초" : "초");
                }
            }
            else if(elapsed.TotalMinutes < 60d)
            {
                int totalMinuteCount = (int)elapsed.TotalMinutes == 0 ? 1 : (int)elapsed.TotalMinutes;

                returnValue = string.Format("{0:0} {1} 전", totalMinuteCount, totalMinuteCount == 1 ? "분" : "분");
            }
            else if(elapsed.TotalHours < 24d)
            {
                int totalHourCount = (int)elapsed.TotalHours == 0 ? 1 : (int)elapsed.TotalHours;

                returnValue = string.Format("{0:0} {1} 전", totalHourCount, totalHourCount == 1 ? "시간" : "시간");
            }
            else
            {
                returnValue = "오래 전";
            }

            return returnValue;
        }

        #endregion
    }
}

 

728x90
반응형
Posted by 사용자 icodebroker

댓글을 달아 주세요