diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..141a718
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,310 @@
+## Ignore Visual Studio temporary files, build results, and
+## files generated by popular Visual Studio add-ons.
+##
+## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore
+
+# User-specific files
+*.suo
+*.user
+*.userosscache
+*.sln.docstates
+
+# User-specific files (MonoDevelop/Xamarin Studio)
+*.userprefs
+
+# Build results
+[Dd]ebug/
+[Dd]ebugPublic/
+[Rr]elease/
+[Rr]eleases/
+x64/
+x86/
+bld/
+[Bb]in/
+[Oo]bj/
+[Ll]og/
+
+# Visual Studio 2015 cache/options directory
+.vs/
+# Uncomment if you have tasks that create the project's static files in wwwroot
+#wwwroot/
+
+# MSTest test Results
+[Tt]est[Rr]esult*/
+[Bb]uild[Ll]og.*
+
+# NUNIT
+*.VisualState.xml
+TestResult.xml
+
+# Build Results of an ATL Project
+[Dd]ebugPS/
+[Rr]eleasePS/
+dlldata.c
+
+# Benchmark Results
+BenchmarkDotNet.Artifacts/
+
+# .NET Core
+project.lock.json
+project.fragment.lock.json
+artifacts/
+**/Properties/launchSettings.json
+
+*_i.c
+*_p.c
+*_i.h
+*.ilk
+*.meta
+*.obj
+*.pch
+*.pdb
+*.pgc
+*.pgd
+*.rsp
+*.sbr
+*.tlb
+*.tli
+*.tlh
+*.tmp
+*.tmp_proj
+*.log
+*.vspscc
+*.vssscc
+.builds
+*.pidb
+*.svclog
+*.scc
+
+# Chutzpah Test files
+_Chutzpah*
+
+# Visual C++ cache files
+ipch/
+*.aps
+*.ncb
+*.opendb
+*.opensdf
+*.sdf
+*.cachefile
+*.VC.db
+*.VC.VC.opendb
+
+# Visual Studio profiler
+*.psess
+*.vsp
+*.vspx
+*.sap
+
+# Visual Studio Trace Files
+*.e2e
+
+# TFS 2012 Local Workspace
+$tf/
+
+# Guidance Automation Toolkit
+*.gpState
+
+# ReSharper is a .NET coding add-in
+_ReSharper*/
+*.[Rr]e[Ss]harper
+*.DotSettings.user
+
+# JustCode is a .NET coding add-in
+.JustCode
+
+# TeamCity is a build add-in
+_TeamCity*
+
+# DotCover is a Code Coverage Tool
+*.dotCover
+
+# AxoCover is a Code Coverage Tool
+.axoCover/*
+!.axoCover/settings.json
+
+# Visual Studio code coverage results
+*.coverage
+*.coveragexml
+
+# NCrunch
+_NCrunch_*
+.*crunch*.local.xml
+nCrunchTemp_*
+
+# MightyMoose
+*.mm.*
+AutoTest.Net/
+
+# Web workbench (sass)
+.sass-cache/
+
+# Installshield output folder
+[Ee]xpress/
+
+# DocProject is a documentation generator add-in
+DocProject/buildhelp/
+DocProject/Help/*.HxT
+DocProject/Help/*.HxC
+DocProject/Help/*.hhc
+DocProject/Help/*.hhk
+DocProject/Help/*.hhp
+DocProject/Help/Html2
+DocProject/Help/html
+
+# Click-Once directory
+publish/
+
+# Publish Web Output
+*.[Pp]ublish.xml
+*.azurePubxml
+# Note: Comment the next line if you want to checkin your web deploy settings,
+# but database connection strings (with potential passwords) will be unencrypted
+*.pubxml
+*.publishproj
+
+# Microsoft Azure Web App publish settings. Comment the next line if you want to
+# checkin your Azure Web App publish settings, but sensitive information contained
+# in these scripts will be unencrypted
+PublishScripts/
+
+# NuGet Packages
+*.nupkg
+# The packages folder can be ignored because of Package Restore
+**/packages/*
+# except build/, which is used as an MSBuild target.
+!**/packages/build/
+# Uncomment if necessary however generally it will be regenerated when needed
+#!**/packages/repositories.config
+# NuGet v3's project.json files produces more ignorable files
+*.nuget.props
+*.nuget.targets
+
+# Microsoft Azure Build Output
+csx/
+*.build.csdef
+
+# Microsoft Azure Emulator
+ecf/
+rcf/
+
+# Windows Store app package directories and files
+AppPackages/
+BundleArtifacts/
+Package.StoreAssociation.xml
+_pkginfo.txt
+*.appx
+
+# Visual Studio cache files
+# files ending in .cache can be ignored
+*.[Cc]ache
+# but keep track of directories ending in .cache
+!*.[Cc]ache/
+
+# Others
+ClientBin/
+~$*
+*~
+*.dbmdl
+*.dbproj.schemaview
+*.jfm
+*.pfx
+*.publishsettings
+orleans.codegen.cs
+
+# Since there are multiple workflows, uncomment next line to ignore bower_components
+# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
+#bower_components/
+
+# RIA/Silverlight projects
+Generated_Code/
+
+# Backup & report files from converting an old project file
+# to a newer Visual Studio version. Backup files are not needed,
+# because we have git ;-)
+_UpgradeReport_Files/
+Backup*/
+UpgradeLog*.XML
+UpgradeLog*.htm
+
+# SQL Server files
+*.mdf
+*.ldf
+*.ndf
+
+# Business Intelligence projects
+*.rdl.data
+*.bim.layout
+*.bim_*.settings
+
+# Microsoft Fakes
+FakesAssemblies/
+
+# GhostDoc plugin setting file
+*.GhostDoc.xml
+
+# Node.js Tools for Visual Studio
+.ntvs_analysis.dat
+node_modules/
+
+# Typescript v1 declaration files
+typings/
+
+# Visual Studio 6 build log
+*.plg
+
+# Visual Studio 6 workspace options file
+*.opt
+
+# Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
+*.vbw
+
+# Visual Studio LightSwitch build output
+**/*.HTMLClient/GeneratedArtifacts
+**/*.DesktopClient/GeneratedArtifacts
+**/*.DesktopClient/ModelManifest.xml
+**/*.Server/GeneratedArtifacts
+**/*.Server/ModelManifest.xml
+_Pvt_Extensions
+
+# Paket dependency manager
+.paket/paket.exe
+paket-files/
+
+# FAKE - F# Make
+.fake/
+
+# JetBrains Rider
+.idea/
+*.sln.iml
+
+# CodeRush
+.cr/
+
+# Python Tools for Visual Studio (PTVS)
+__pycache__/
+*.pyc
+
+# Cake - Uncomment if you are using it
+# tools/**
+# !tools/packages.config
+
+# Tabs Studio
+*.tss
+
+# Telerik's JustMock configuration file
+*.jmconfig
+
+# BizTalk build output
+*.btp.cs
+*.btm.cs
+*.odx.cs
+*.xsd.cs
+
+# OpenCover UI analysis results
+OpenCover/
+
+# Added by me
+Output/
+*.sgui
+*.iss
\ No newline at end of file
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..85a3f68
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,21 @@
+The MIT License (MIT)
+
+Copyright (c) 2017 Mariusz Kacki
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
\ No newline at end of file
diff --git a/PMS Tool.sln b/PMS Tool.sln
new file mode 100644
index 0000000..befbb5e
--- /dev/null
+++ b/PMS Tool.sln
@@ -0,0 +1,22 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 14
+VisualStudioVersion = 14.0.25420.1
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PMS Tool", "WindowsFormsApplication1\PMS Tool.csproj", "{8F792076-7393-4053-9D72-09ADF21006CD}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|x86 = Debug|x86
+ Release|x86 = Release|x86
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {8F792076-7393-4053-9D72-09ADF21006CD}.Debug|x86.ActiveCfg = Debug|x86
+ {8F792076-7393-4053-9D72-09ADF21006CD}.Debug|x86.Build.0 = Debug|x86
+ {8F792076-7393-4053-9D72-09ADF21006CD}.Release|x86.ActiveCfg = Release|x86
+ {8F792076-7393-4053-9D72-09ADF21006CD}.Release|x86.Build.0 = Release|x86
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..231103f
--- /dev/null
+++ b/README.md
@@ -0,0 +1,16 @@
+# PMS Tool
+
+C# Windows Forms Application for Plantower PMS sensors.
+Supports PMS x003 sensors (1003, 3003, 5003, 6003, 7003).
+
+## Motivation
+
+I have not found another tool for Windows to test Plantower PMS dust sensors, so I created and share this program.
+
+## Screenshots
+![Connecting](Screenshots/1.PNG)
+![Console](Screenshots/2.PNG)
+
+## Arduino library
+Finally, I made a library for the Arduino:
+https://github.com/fu-hsi/PMS
\ No newline at end of file
diff --git a/Screenshots/1.PNG b/Screenshots/1.PNG
new file mode 100644
index 0000000..6b2c69d
Binary files /dev/null and b/Screenshots/1.PNG differ
diff --git a/Screenshots/2.PNG b/Screenshots/2.PNG
new file mode 100644
index 0000000..f43dac0
Binary files /dev/null and b/Screenshots/2.PNG differ
diff --git a/WindowsFormsApplication1/Form1.Designer.cs b/WindowsFormsApplication1/Form1.Designer.cs
new file mode 100644
index 0000000..bf5b427
--- /dev/null
+++ b/WindowsFormsApplication1/Form1.Designer.cs
@@ -0,0 +1,185 @@
+namespace WindowsFormsApplication1
+{
+ partial class Form1
+ {
+ ///
+ /// Required designer variable.
+ ///
+ private System.ComponentModel.IContainer components = null;
+
+ ///
+ /// Clean up any resources being used.
+ ///
+ /// true if managed resources should be disposed; otherwise, false.
+ protected override void Dispose(bool disposing)
+ {
+ if (disposing && (components != null))
+ {
+ components.Dispose();
+ }
+ base.Dispose(disposing);
+ }
+
+ #region Windows Form Designer generated code
+
+ ///
+ /// Required method for Designer support - do not modify
+ /// the contents of this method with the code editor.
+ ///
+ private void InitializeComponent()
+ {
+ this.components = new System.ComponentModel.Container();
+ this.toolStrip1 = new System.Windows.Forms.ToolStrip();
+ this.settingsToolStripButton = new System.Windows.Forms.ToolStripButton();
+ this.logToolStripButton = new System.Windows.Forms.ToolStripButton();
+ this.aboutToolStripButton = new System.Windows.Forms.ToolStripButton();
+ this.toolStripButton3 = new System.Windows.Forms.ToolStripButton();
+ this.label1 = new System.Windows.Forms.Label();
+ this.panelContainer = new System.Windows.Forms.Panel();
+ this.serialPort1 = new System.IO.Ports.SerialPort(this.components);
+ this.openFileDialog1 = new System.Windows.Forms.OpenFileDialog();
+ this.saveFileDialog1 = new System.Windows.Forms.SaveFileDialog();
+ this.toolStrip1.SuspendLayout();
+ this.SuspendLayout();
+ //
+ // toolStrip1
+ //
+ this.toolStrip1.BackColor = System.Drawing.Color.White;
+ this.toolStrip1.GripStyle = System.Windows.Forms.ToolStripGripStyle.Hidden;
+ this.toolStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
+ this.settingsToolStripButton,
+ this.logToolStripButton,
+ this.aboutToolStripButton,
+ this.toolStripButton3});
+ this.toolStrip1.Location = new System.Drawing.Point(0, 0);
+ this.toolStrip1.Name = "toolStrip1";
+ this.toolStrip1.Padding = new System.Windows.Forms.Padding(3, 0, 3, 0);
+ this.toolStrip1.RenderMode = System.Windows.Forms.ToolStripRenderMode.System;
+ this.toolStrip1.Size = new System.Drawing.Size(624, 56);
+ this.toolStrip1.TabIndex = 0;
+ this.toolStrip1.ItemClicked += new System.Windows.Forms.ToolStripItemClickedEventHandler(this.toolStrip1_ItemClicked);
+ //
+ // settingsToolStripButton
+ //
+ this.settingsToolStripButton.AutoSize = false;
+ this.settingsToolStripButton.Image = global::WindowsFormsApplication1.Properties.Resources.Network_connection;
+ this.settingsToolStripButton.ImageScaling = System.Windows.Forms.ToolStripItemImageScaling.None;
+ this.settingsToolStripButton.ImageTransparentColor = System.Drawing.Color.Magenta;
+ this.settingsToolStripButton.Margin = new System.Windows.Forms.Padding(0, 1, 3, 2);
+ this.settingsToolStripButton.Name = "settingsToolStripButton";
+ this.settingsToolStripButton.Padding = new System.Windows.Forms.Padding(5);
+ this.settingsToolStripButton.Size = new System.Drawing.Size(100, 53);
+ this.settingsToolStripButton.Tag = "1";
+ this.settingsToolStripButton.Text = "Connecting";
+ this.settingsToolStripButton.TextAlign = System.Drawing.ContentAlignment.BottomCenter;
+ this.settingsToolStripButton.TextImageRelation = System.Windows.Forms.TextImageRelation.ImageAboveText;
+ //
+ // logToolStripButton
+ //
+ this.logToolStripButton.AutoSize = false;
+ this.logToolStripButton.Image = global::WindowsFormsApplication1.Properties.Resources.Stock_graph;
+ this.logToolStripButton.ImageScaling = System.Windows.Forms.ToolStripItemImageScaling.None;
+ this.logToolStripButton.ImageTransparentColor = System.Drawing.Color.Magenta;
+ this.logToolStripButton.Margin = new System.Windows.Forms.Padding(0, 1, 3, 2);
+ this.logToolStripButton.Name = "logToolStripButton";
+ this.logToolStripButton.Padding = new System.Windows.Forms.Padding(5);
+ this.logToolStripButton.Size = new System.Drawing.Size(100, 53);
+ this.logToolStripButton.Tag = "2";
+ this.logToolStripButton.Text = "Console";
+ this.logToolStripButton.TextAlign = System.Drawing.ContentAlignment.BottomCenter;
+ this.logToolStripButton.TextImageRelation = System.Windows.Forms.TextImageRelation.ImageAboveText;
+ //
+ // aboutToolStripButton
+ //
+ this.aboutToolStripButton.AutoSize = false;
+ this.aboutToolStripButton.Image = global::WindowsFormsApplication1.Properties.Resources.About;
+ this.aboutToolStripButton.ImageScaling = System.Windows.Forms.ToolStripItemImageScaling.None;
+ this.aboutToolStripButton.ImageTransparentColor = System.Drawing.Color.Magenta;
+ this.aboutToolStripButton.Margin = new System.Windows.Forms.Padding(0, 1, 3, 2);
+ this.aboutToolStripButton.Name = "aboutToolStripButton";
+ this.aboutToolStripButton.Padding = new System.Windows.Forms.Padding(5);
+ this.aboutToolStripButton.Size = new System.Drawing.Size(100, 53);
+ this.aboutToolStripButton.Tag = "4";
+ this.aboutToolStripButton.Text = "About";
+ this.aboutToolStripButton.TextAlign = System.Drawing.ContentAlignment.BottomCenter;
+ this.aboutToolStripButton.TextImageRelation = System.Windows.Forms.TextImageRelation.ImageAboveText;
+ //
+ // toolStripButton3
+ //
+ this.toolStripButton3.Alignment = System.Windows.Forms.ToolStripItemAlignment.Right;
+ this.toolStripButton3.AutoSize = false;
+ this.toolStripButton3.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Center;
+ this.toolStripButton3.Image = global::WindowsFormsApplication1.Properties.Resources.Exit;
+ this.toolStripButton3.ImageScaling = System.Windows.Forms.ToolStripItemImageScaling.None;
+ this.toolStripButton3.ImageTransparentColor = System.Drawing.Color.Magenta;
+ this.toolStripButton3.Name = "toolStripButton3";
+ this.toolStripButton3.Size = new System.Drawing.Size(100, 53);
+ this.toolStripButton3.Tag = "6";
+ this.toolStripButton3.Text = "Exit";
+ this.toolStripButton3.TextAlign = System.Drawing.ContentAlignment.BottomCenter;
+ this.toolStripButton3.TextImageRelation = System.Windows.Forms.TextImageRelation.ImageAboveText;
+ //
+ // label1
+ //
+ this.label1.BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D;
+ this.label1.Dock = System.Windows.Forms.DockStyle.Top;
+ this.label1.Location = new System.Drawing.Point(0, 56);
+ this.label1.Name = "label1";
+ this.label1.Size = new System.Drawing.Size(624, 2);
+ this.label1.TabIndex = 1;
+ //
+ // panelContainer
+ //
+ this.panelContainer.BackColor = System.Drawing.SystemColors.Control;
+ this.panelContainer.Dock = System.Windows.Forms.DockStyle.Fill;
+ this.panelContainer.Location = new System.Drawing.Point(0, 58);
+ this.panelContainer.Name = "panelContainer";
+ this.panelContainer.Padding = new System.Windows.Forms.Padding(10);
+ this.panelContainer.Size = new System.Drawing.Size(624, 383);
+ this.panelContainer.TabIndex = 2;
+ this.panelContainer.ControlAdded += new System.Windows.Forms.ControlEventHandler(this.panelContainer_ControlAdded);
+ //
+ // openFileDialog1
+ //
+ this.openFileDialog1.DefaultExt = "osd";
+ this.openFileDialog1.Filter = "OSD Settings|*.osd";
+ //
+ // saveFileDialog1
+ //
+ this.saveFileDialog1.DefaultExt = "osd";
+ this.saveFileDialog1.Filter = "OSD Settings|*.osd";
+ //
+ // Form1
+ //
+ this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+ this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+ this.ClientSize = new System.Drawing.Size(624, 441);
+ this.Controls.Add(this.panelContainer);
+ this.Controls.Add(this.label1);
+ this.Controls.Add(this.toolStrip1);
+ this.MinimumSize = new System.Drawing.Size(640, 480);
+ this.Name = "Form1";
+ this.Text = "PMS Tool (1003/3003/5003/6003/7003)";
+ this.FormClosed += new System.Windows.Forms.FormClosedEventHandler(this.Form1_FormClosed);
+ this.toolStrip1.ResumeLayout(false);
+ this.toolStrip1.PerformLayout();
+ this.ResumeLayout(false);
+ this.PerformLayout();
+
+ }
+
+ #endregion
+
+ private System.Windows.Forms.ToolStrip toolStrip1;
+ private System.Windows.Forms.ToolStripButton logToolStripButton;
+ private System.Windows.Forms.ToolStripButton settingsToolStripButton;
+ private System.Windows.Forms.ToolStripButton aboutToolStripButton;
+ private System.Windows.Forms.Label label1;
+ private System.Windows.Forms.Panel panelContainer;
+ private System.IO.Ports.SerialPort serialPort1;
+ private System.Windows.Forms.OpenFileDialog openFileDialog1;
+ private System.Windows.Forms.SaveFileDialog saveFileDialog1;
+ private System.Windows.Forms.ToolStripButton toolStripButton3;
+ }
+}
+
diff --git a/WindowsFormsApplication1/Form1.cs b/WindowsFormsApplication1/Form1.cs
new file mode 100644
index 0000000..f592d60
--- /dev/null
+++ b/WindowsFormsApplication1/Form1.cs
@@ -0,0 +1,137 @@
+using System;
+using System.Linq;
+using System.Windows.Forms;
+
+namespace WindowsFormsApplication1
+{
+ public partial class Form1 : Form
+ {
+ UserControlSettings _panelSettings;
+ UserControlLog _panelLog;
+ UserControlAbout _panelAbout;
+
+ public Form1()
+ {
+ InitializeComponent();
+
+ _panelLog = new UserControlLog(serialPort1);
+ panelContainer.Controls.Add(_panelLog);
+
+ _panelSettings = new UserControlSettings();
+ panelContainer.Controls.Add(_panelSettings);
+ _panelSettings.ConnectButton.Click += new EventHandler(ConnectButton_Click);
+
+ _panelAbout = new UserControlAbout();
+ panelContainer.Controls.Add(_panelAbout);
+
+ toolStrip1_ItemClicked(this, new ToolStripItemClickedEventArgs(settingsToolStripButton));
+
+ if (string.IsNullOrEmpty(this.Text))
+ {
+ this.Text = Application.ProductName + " v" + Application.ProductVersion.Substring(0, Application.ProductVersion.Length - 2);
+ }
+ else
+ {
+ this.Text += " v" + Application.ProductVersion.Substring(0, Application.ProductVersion.Length - 2);
+ }
+ }
+
+ void ConnectButton_Click(object sender, EventArgs e)
+ {
+ if (serialPort1.IsOpen == false)
+ {
+ try
+ {
+ serialPort1.PortName = _panelSettings.comboBoxPorts.SelectedItem.ToString();
+ serialPort1.Open();
+ toolStrip1_ItemClicked(this, new ToolStripItemClickedEventArgs(logToolStripButton));
+ }
+ catch (Exception ex)
+ {
+ MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
+ }
+ }
+ else
+ {
+ serialPort1.Close();
+ }
+
+ _panelSettings.ConnectButton.Text = serialPort1.IsOpen ? "Close" : "Open";
+ _panelSettings.comboBoxPorts.Enabled = !serialPort1.IsOpen;
+ }
+
+ void toolStrip1_ItemClicked(object sender, ToolStripItemClickedEventArgs e)
+ {
+ if (e.ClickedItem is ToolStripButton)
+ {
+ ToolStripButton b = e.ClickedItem as ToolStripButton;
+
+ foreach (ToolStripButton i in toolStrip1.Items.OfType())
+ {
+ if (e.ClickedItem != i)
+ {
+ i.Checked = false;
+ }
+ }
+
+ b.Checked = true;
+
+ int menuIndex = Convert.ToInt32(b.Tag);
+
+ switch (menuIndex)
+ {
+ case 1:
+ ActivatePanel(_panelSettings);
+ break;
+ case 2:
+ ActivatePanel(_panelLog);
+ break;
+ case 4:
+ ActivatePanel(_panelAbout);
+ break;
+ case 6:
+ Application.Exit();
+ break;
+ default:
+ ActivatePanel(_panelSettings);
+ break;
+ }
+ }
+ }
+
+ private void ActivatePanel(Control panel)
+ {
+ foreach (Control c in panelContainer.Controls)
+ {
+ c.Visible = false;
+ }
+
+ panel.Visible = true;
+ }
+
+ private void Form1_FormClosed(object sender, FormClosedEventArgs e)
+ {
+ if (serialPort1.IsOpen)
+ {
+ serialPort1.Close();
+ }
+
+ if (_panelSettings.comboBoxPorts.SelectedIndex > -1)
+ {
+ Properties.Settings.Default.COM = _panelSettings.comboBoxPorts.SelectedItem.ToString();
+ Properties.Settings.Default.Save();
+ }
+ }
+
+ private void logToolStripButton_Click(object sender, EventArgs e)
+ {
+ ActivatePanel(_panelLog);
+ }
+
+ private void panelContainer_ControlAdded(object sender, ControlEventArgs e)
+ {
+ e.Control.Dock = DockStyle.Fill;
+ e.Control.Visible = false;
+ }
+ }
+}
diff --git a/WindowsFormsApplication1/Form1.resx b/WindowsFormsApplication1/Form1.resx
new file mode 100644
index 0000000..2d8b980
--- /dev/null
+++ b/WindowsFormsApplication1/Form1.resx
@@ -0,0 +1,132 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ 17, 17
+
+
+ 122, 17
+
+
+ 231, 17
+
+
+ 371, 17
+
+
\ No newline at end of file
diff --git a/WindowsFormsApplication1/PMS Tool.csproj b/WindowsFormsApplication1/PMS Tool.csproj
new file mode 100644
index 0000000..7f981b6
--- /dev/null
+++ b/WindowsFormsApplication1/PMS Tool.csproj
@@ -0,0 +1,160 @@
+
+
+
+ Debug
+ x86
+ 8.0.30703
+ 2.0
+ {8F792076-7393-4053-9D72-09ADF21006CD}
+ WinExe
+ Properties
+ WindowsFormsApplication1
+ PMS
+ v4.0
+ Client
+ 512
+ publish\
+ true
+ Disk
+ false
+ Foreground
+ 7
+ Days
+ false
+ false
+ true
+ 0
+ 1.0.0.%2a
+ false
+ false
+ true
+
+
+ x86
+ true
+ full
+ false
+ bin\Debug\
+ DEBUG;TRACE
+ prompt
+ 4
+
+
+ x86
+ pdbonly
+ true
+ bin\Release\
+ TRACE
+ prompt
+ 4
+
+
+ true
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Form
+
+
+ Form1.cs
+
+
+
+
+
+ UserControl
+
+
+ UserControlAbout.cs
+
+
+ UserControl
+
+
+ UserControlSettings.cs
+
+
+ UserControl
+
+
+ UserControlLog.cs
+
+
+ Form1.cs
+
+
+ ResXFileCodeGenerator
+ Resources.Designer.cs
+ Designer
+
+
+ True
+ Resources.resx
+ True
+
+
+ UserControlAbout.cs
+
+
+ UserControlLog.cs
+
+
+ UserControlSettings.cs
+
+
+
+ SettingsSingleFileGenerator
+ Settings.Designer.cs
+
+
+ True
+ Settings.settings
+ True
+
+
+
+
+
+
+
+
+
+
+
+ False
+ Microsoft .NET Framework 4 Client Profile %28x86 and x64%29
+ true
+
+
+ False
+ .NET Framework 3.5 SP1
+ false
+
+
+ False
+ Windows Installer 4.5
+ true
+
+
+
+
+
\ No newline at end of file
diff --git a/WindowsFormsApplication1/PMS.cs b/WindowsFormsApplication1/PMS.cs
new file mode 100644
index 0000000..b235a53
--- /dev/null
+++ b/WindowsFormsApplication1/PMS.cs
@@ -0,0 +1,174 @@
+using System;
+using System.Collections.Generic;
+using System.IO.Ports;
+using System.Linq;
+
+namespace WindowsFormsApplication1
+{
+ class PMS
+ {
+ private SerialPort _port;
+ private List _frame = new List(); // Only for visualization
+
+ public class DataEventArgs : EventArgs
+ {
+ private byte[] _payload;
+
+ public DataEventArgs(byte[] payload)
+ {
+ this._payload = payload;
+ }
+
+ public int PM_FE_UG_1_0 { get { return (ushort)((_payload[0] << 8) | _payload[1]); } }
+ public int PM_FE_UG_2_5 { get { return (ushort)((_payload[2] << 8) | _payload[3]); } }
+ public int PM_FE_UG_10_0 { get { return (ushort)((_payload[4] << 8) | _payload[5]); } }
+
+ public int PM_AE_UG_1_0 { get { return (ushort)((_payload[6] << 8) | _payload[7]); } }
+ public int PM_AE_UG_2_5 { get { return (ushort)((_payload[8] << 8) | _payload[9]); } }
+ public int PM_AE_UG_10_0 { get { return (ushort)((_payload[10] << 8) | _payload[11]); } }
+
+ public byte[] Payload { get { return _payload; } }
+ }
+
+ public class RawDataEventArgs : EventArgs
+ {
+ private string _text;
+
+ public RawDataEventArgs(string text)
+ {
+ this._text = text;
+ }
+
+ public string Data { get { return _text; } }
+ }
+
+ public delegate void DataEventHandler(object sender, DataEventArgs e);
+ public delegate void FeedbackEventHandler(object sender, RawDataEventArgs e);
+
+ public event DataEventHandler DataEvent;
+ public event FeedbackEventHandler FeedbackEvent;
+
+ private byte[] _payload = new byte[12];
+ private ushort _index, _frameLen, _checksum, _calculatedChecksum;
+
+ public PMS(SerialPort port)
+ {
+ this._port = port;
+ this._port.DataReceived += Port_DataReceived;
+ }
+
+ private void Port_DataReceived(object sender, SerialDataReceivedEventArgs e)
+ {
+ while (this._port.BytesToRead > 0)
+ {
+ loop();
+ }
+ }
+
+ private void SendData(byte[] data)
+ {
+ if (this._port.IsOpen)
+ {
+ this._port.Write(data, 0, data.Length);
+ this.FeedbackEvent?.Invoke(this, new RawDataEventArgs("> " + string.Join(" ", data.Select(c => ((byte)c).ToString("X2")))));
+ }
+ }
+
+ public void Sleep()
+ {
+ SendData(new byte[] { 0x42, 0x4D, 0xE4, 0x00, 0x00, 0x01, 0x73 });
+ }
+
+ public void WakeUp()
+ {
+ SendData(new byte[] { 0x42, 0x4D, 0xE4, 0x00, 0x01, 0x01, 0x74 });
+ }
+
+ public void PassiveMode()
+ {
+ SendData(new byte[] { 0x42, 0x4D, 0xE1, 0x00, 0x00, 0x01, 0x70 });
+ }
+
+ public void ActiveMode()
+ {
+ SendData(new byte[] { 0x42, 0x4D, 0xE1, 0x00, 0x01, 0x01, 0x71 });
+ }
+
+ public void Read()
+ {
+ SendData(new byte[] { 0x42, 0x4D, 0xE2, 0x00, 0x00, 0x01, 0x71 });
+ }
+
+ private void loop()
+ {
+ byte ch = (byte)this._port.ReadByte();
+ if (_index == 0) _frame.Clear(); else _frame.Add(ch);
+
+ switch (_index)
+ {
+ case 0:
+ if (ch != 0x42)
+ {
+ return;
+ }
+ _calculatedChecksum = ch;
+ break;
+
+ case 1:
+ if (ch != 0x4D)
+ {
+ _index = 0;
+ return;
+ }
+ _calculatedChecksum += ch;
+ break;
+
+ case 2:
+ _calculatedChecksum += ch;
+ _frameLen = (ushort)(ch << 8);
+ break;
+
+ case 3:
+ _frameLen |= ch;
+ if (_frameLen != 2 * 9 + 2 && _frameLen != 2 * 13 + 2)
+ {
+ _index = 0;
+ return;
+ }
+ _calculatedChecksum += ch;
+ break;
+
+ default:
+ if (_index == _frameLen + 2)
+ {
+ _checksum = (ushort)(ch << 8);
+ }
+ else if (_index == _frameLen + 2 + 1)
+ {
+ _checksum |= ch;
+
+ if (_calculatedChecksum == _checksum)
+ {
+ FeedbackEvent?.Invoke(this, new RawDataEventArgs("< " + string.Join(" ", _frame.Select(c => ((byte)c).ToString("X2")))));
+ DataEvent?.Invoke(this, new DataEventArgs(_payload));
+ }
+
+ _index = 0;
+ return;
+ }
+ else
+ {
+ _calculatedChecksum += ch;
+ byte payloadIndex = (byte)(_index - 4);
+
+ if (payloadIndex < _payload.Length)
+ {
+ _payload[payloadIndex] = ch;
+ }
+ }
+ break;
+ }
+ _index++;
+ }
+ }
+}
diff --git a/WindowsFormsApplication1/Program.cs b/WindowsFormsApplication1/Program.cs
new file mode 100644
index 0000000..73f70d2
--- /dev/null
+++ b/WindowsFormsApplication1/Program.cs
@@ -0,0 +1,19 @@
+using System;
+using System.Windows.Forms;
+
+namespace WindowsFormsApplication1
+{
+ static class Program
+ {
+ ///
+ /// The main entry point for the application.
+ ///
+ [STAThread]
+ static void Main()
+ {
+ Application.EnableVisualStyles();
+ Application.SetCompatibleTextRenderingDefault(false);
+ Application.Run(new Form1());
+ }
+ }
+}
diff --git a/WindowsFormsApplication1/Properties/AssemblyInfo.cs b/WindowsFormsApplication1/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..963b566
--- /dev/null
+++ b/WindowsFormsApplication1/Properties/AssemblyInfo.cs
@@ -0,0 +1,38 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Resources;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("PMS Tool")]
+[assembly: AssemblyDescription("Supports Plantower PMSx003 series sensors (1003, 3003, 5003, 6003, 7003).")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("Mariusz Kacki")]
+[assembly: AssemblyProduct("PMS Tool")]
+[assembly: AssemblyCopyright("Copyright © 2017 Mariusz Kacki")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("A983CFDA-56F5-4362-AC8D-DA3F74B6FBBE")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
+[assembly: NeutralResourcesLanguageAttribute("pl")]
diff --git a/WindowsFormsApplication1/Properties/Resources.Designer.cs b/WindowsFormsApplication1/Properties/Resources.Designer.cs
new file mode 100644
index 0000000..5b4932d
--- /dev/null
+++ b/WindowsFormsApplication1/Properties/Resources.Designer.cs
@@ -0,0 +1,112 @@
+//------------------------------------------------------------------------------
+//
+// This code was generated by a tool.
+// Runtime Version:4.0.30319.42000
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+//
+//------------------------------------------------------------------------------
+
+namespace WindowsFormsApplication1.Properties {
+ using System;
+
+
+ ///
+ /// A strongly-typed resource class, for looking up localized strings, etc.
+ ///
+ // This class was auto-generated by the StronglyTypedResourceBuilder
+ // class via a tool like ResGen or Visual Studio.
+ // To add or remove a member, edit your .ResX file then rerun ResGen
+ // with the /str option, or rebuild your VS project.
+ [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
+ internal class Resources {
+
+ private static global::System.Resources.ResourceManager resourceMan;
+
+ private static global::System.Globalization.CultureInfo resourceCulture;
+
+ [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
+ internal Resources() {
+ }
+
+ ///
+ /// Returns the cached ResourceManager instance used by this class.
+ ///
+ [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+ internal static global::System.Resources.ResourceManager ResourceManager {
+ get {
+ if (object.ReferenceEquals(resourceMan, null)) {
+ global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("WindowsFormsApplication1.Properties.Resources", typeof(Resources).Assembly);
+ resourceMan = temp;
+ }
+ return resourceMan;
+ }
+ }
+
+ ///
+ /// Overrides the current thread's CurrentUICulture property for all
+ /// resource lookups using this strongly typed resource class.
+ ///
+ [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+ internal static global::System.Globalization.CultureInfo Culture {
+ get {
+ return resourceCulture;
+ }
+ set {
+ resourceCulture = value;
+ }
+ }
+
+ ///
+ /// Looks up a localized resource of type System.Drawing.Bitmap.
+ ///
+ internal static System.Drawing.Bitmap About {
+ get {
+ object obj = ResourceManager.GetObject("About", resourceCulture);
+ return ((System.Drawing.Bitmap)(obj));
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to PMS.
+ ///
+ internal static string APP_DATA_FOLDER {
+ get {
+ return ResourceManager.GetString("APP_DATA_FOLDER", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized resource of type System.Drawing.Bitmap.
+ ///
+ internal static System.Drawing.Bitmap Exit {
+ get {
+ object obj = ResourceManager.GetObject("Exit", resourceCulture);
+ return ((System.Drawing.Bitmap)(obj));
+ }
+ }
+
+ ///
+ /// Looks up a localized resource of type System.Drawing.Bitmap.
+ ///
+ internal static System.Drawing.Bitmap Network_connection {
+ get {
+ object obj = ResourceManager.GetObject("Network_connection", resourceCulture);
+ return ((System.Drawing.Bitmap)(obj));
+ }
+ }
+
+ ///
+ /// Looks up a localized resource of type System.Drawing.Bitmap.
+ ///
+ internal static System.Drawing.Bitmap Stock_graph {
+ get {
+ object obj = ResourceManager.GetObject("Stock_graph", resourceCulture);
+ return ((System.Drawing.Bitmap)(obj));
+ }
+ }
+ }
+}
diff --git a/WindowsFormsApplication1/Properties/Resources.resx b/WindowsFormsApplication1/Properties/Resources.resx
new file mode 100644
index 0000000..8c65450
--- /dev/null
+++ b/WindowsFormsApplication1/Properties/Resources.resx
@@ -0,0 +1,136 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ PMS
+
+
+
+ ..\Resources\Exit.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
+
+
+ ..\Resources\About.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
+
+
+ ..\Resources\Network connection.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
+
+
+ ..\Resources\Stock graph.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
+
+
\ No newline at end of file
diff --git a/WindowsFormsApplication1/Properties/Settings.Designer.cs b/WindowsFormsApplication1/Properties/Settings.Designer.cs
new file mode 100644
index 0000000..59d582f
--- /dev/null
+++ b/WindowsFormsApplication1/Properties/Settings.Designer.cs
@@ -0,0 +1,38 @@
+//------------------------------------------------------------------------------
+//
+// This code was generated by a tool.
+// Runtime Version:4.0.30319.42000
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+//
+//------------------------------------------------------------------------------
+
+namespace WindowsFormsApplication1.Properties {
+
+
+ [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
+ [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "14.0.0.0")]
+ internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
+
+ private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
+
+ public static Settings Default {
+ get {
+ return defaultInstance;
+ }
+ }
+
+ [global::System.Configuration.UserScopedSettingAttribute()]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.Configuration.DefaultSettingValueAttribute("")]
+ public string COM {
+ get {
+ return ((string)(this["COM"]));
+ }
+ set {
+ this["COM"] = value;
+ }
+ }
+ }
+}
diff --git a/WindowsFormsApplication1/Properties/Settings.settings b/WindowsFormsApplication1/Properties/Settings.settings
new file mode 100644
index 0000000..5fd0070
--- /dev/null
+++ b/WindowsFormsApplication1/Properties/Settings.settings
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/WindowsFormsApplication1/Resources/About.png b/WindowsFormsApplication1/Resources/About.png
new file mode 100644
index 0000000..fabc1fc
Binary files /dev/null and b/WindowsFormsApplication1/Resources/About.png differ
diff --git a/WindowsFormsApplication1/Resources/Exit.png b/WindowsFormsApplication1/Resources/Exit.png
new file mode 100644
index 0000000..02ab845
Binary files /dev/null and b/WindowsFormsApplication1/Resources/Exit.png differ
diff --git a/WindowsFormsApplication1/Resources/Network connection.png b/WindowsFormsApplication1/Resources/Network connection.png
new file mode 100644
index 0000000..6ee7547
Binary files /dev/null and b/WindowsFormsApplication1/Resources/Network connection.png differ
diff --git a/WindowsFormsApplication1/Resources/Stock graph.png b/WindowsFormsApplication1/Resources/Stock graph.png
new file mode 100644
index 0000000..77f88be
Binary files /dev/null and b/WindowsFormsApplication1/Resources/Stock graph.png differ
diff --git a/WindowsFormsApplication1/Resources/Tune.png b/WindowsFormsApplication1/Resources/Tune.png
new file mode 100644
index 0000000..fa8c19f
Binary files /dev/null and b/WindowsFormsApplication1/Resources/Tune.png differ
diff --git a/WindowsFormsApplication1/UserControlAbout.Designer.cs b/WindowsFormsApplication1/UserControlAbout.Designer.cs
new file mode 100644
index 0000000..1b3b43b
--- /dev/null
+++ b/WindowsFormsApplication1/UserControlAbout.Designer.cs
@@ -0,0 +1,62 @@
+namespace WindowsFormsApplication1
+{
+ partial class UserControlAbout
+ {
+ ///
+ /// Required designer variable.
+ ///
+ private System.ComponentModel.IContainer components = null;
+
+ ///
+ /// Clean up any resources being used.
+ ///
+ /// true if managed resources should be disposed; otherwise, false.
+ protected override void Dispose(bool disposing)
+ {
+ if (disposing && (components != null))
+ {
+ components.Dispose();
+ }
+ base.Dispose(disposing);
+ }
+
+ #region Component Designer generated code
+
+ ///
+ /// Required method for Designer support - do not modify
+ /// the contents of this method with the code editor.
+ ///
+ private void InitializeComponent()
+ {
+ System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(UserControlAbout));
+ this.textBox1 = new System.Windows.Forms.TextBox();
+ this.SuspendLayout();
+ //
+ // textBox1
+ //
+ this.textBox1.Dock = System.Windows.Forms.DockStyle.Fill;
+ this.textBox1.Location = new System.Drawing.Point(0, 0);
+ this.textBox1.Multiline = true;
+ this.textBox1.Name = "textBox1";
+ this.textBox1.ReadOnly = true;
+ this.textBox1.Size = new System.Drawing.Size(642, 412);
+ this.textBox1.TabIndex = 0;
+ this.textBox1.Text = resources.GetString("textBox1.Text");
+ //
+ // UserControlAbout
+ //
+ this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+ this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+ this.Controls.Add(this.textBox1);
+ this.Name = "UserControlAbout";
+ this.Size = new System.Drawing.Size(642, 412);
+ this.ResumeLayout(false);
+ this.PerformLayout();
+
+ }
+
+ #endregion
+
+ private System.Windows.Forms.TextBox textBox1;
+ }
+}
diff --git a/WindowsFormsApplication1/UserControlAbout.cs b/WindowsFormsApplication1/UserControlAbout.cs
new file mode 100644
index 0000000..054365d
--- /dev/null
+++ b/WindowsFormsApplication1/UserControlAbout.cs
@@ -0,0 +1,12 @@
+using System.Windows.Forms;
+
+namespace WindowsFormsApplication1
+{
+ public partial class UserControlAbout : UserControl
+ {
+ public UserControlAbout()
+ {
+ InitializeComponent();
+ }
+ }
+}
diff --git a/WindowsFormsApplication1/UserControlAbout.resx b/WindowsFormsApplication1/UserControlAbout.resx
new file mode 100644
index 0000000..1608a78
--- /dev/null
+++ b/WindowsFormsApplication1/UserControlAbout.resx
@@ -0,0 +1,130 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ Application supports Plantower PMS x003 series sensors (1003, 3003, 5003, 6003, 7003).
+Tested with PMS 7003, but protocol is the same or similar for all these sensors (let me known if you have any problems).
+
+Need Arduino library?
+https://github.com/fu-hsi/PMS
+
+Credits:
+24x24 Free Application Icons, www.aha-soft.com, CC-BY 3.0.
+
+
\ No newline at end of file
diff --git a/WindowsFormsApplication1/UserControlLog.Designer.cs b/WindowsFormsApplication1/UserControlLog.Designer.cs
new file mode 100644
index 0000000..4a71282
--- /dev/null
+++ b/WindowsFormsApplication1/UserControlLog.Designer.cs
@@ -0,0 +1,321 @@
+namespace WindowsFormsApplication1
+{
+ partial class UserControlLog
+ {
+ ///
+ /// Required designer variable.
+ ///
+ private System.ComponentModel.IContainer components = null;
+
+ ///
+ /// Clean up any resources being used.
+ ///
+ /// true if managed resources should be disposed; otherwise, false.
+ protected override void Dispose(bool disposing)
+ {
+ if (disposing && (components != null))
+ {
+ components.Dispose();
+ }
+ base.Dispose(disposing);
+ }
+
+ #region Component Designer generated code
+
+ ///
+ /// Required method for Designer support - do not modify
+ /// the contents of this method with the code editor.
+ ///
+ private void InitializeComponent()
+ {
+ this.components = new System.ComponentModel.Container();
+ System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(UserControlLog));
+ this.imageList1 = new System.Windows.Forms.ImageList(this.components);
+ this.textBoxLog = new System.Windows.Forms.TextBox();
+ this.buttonRead = new System.Windows.Forms.Button();
+ this.checkBoxActiveMode = new System.Windows.Forms.CheckBox();
+ this.groupBox1 = new System.Windows.Forms.GroupBox();
+ this.label7 = new System.Windows.Forms.Label();
+ this.textBox10_0 = new System.Windows.Forms.TextBox();
+ this.label4 = new System.Windows.Forms.Label();
+ this.textBox2_5 = new System.Windows.Forms.TextBox();
+ this.label5 = new System.Windows.Forms.Label();
+ this.textBox1_0 = new System.Windows.Forms.TextBox();
+ this.label6 = new System.Windows.Forms.Label();
+ this.textBoxCF_10_0 = new System.Windows.Forms.TextBox();
+ this.label3 = new System.Windows.Forms.Label();
+ this.textBoxCF_2_5 = new System.Windows.Forms.TextBox();
+ this.label2 = new System.Windows.Forms.Label();
+ this.textBoxCF_1_0 = new System.Windows.Forms.TextBox();
+ this.label1 = new System.Windows.Forms.Label();
+ this.checkBoxSleepMode = new System.Windows.Forms.CheckBox();
+ this.groupBox2 = new System.Windows.Forms.GroupBox();
+ this.label8 = new System.Windows.Forms.Label();
+ this.groupBox1.SuspendLayout();
+ this.groupBox2.SuspendLayout();
+ this.SuspendLayout();
+ //
+ // imageList1
+ //
+ this.imageList1.ImageStream = ((System.Windows.Forms.ImageListStreamer)(resources.GetObject("imageList1.ImageStream")));
+ this.imageList1.TransparentColor = System.Drawing.Color.Transparent;
+ this.imageList1.Images.SetKeyName(0, "0.png");
+ this.imageList1.Images.SetKeyName(1, "1.png");
+ this.imageList1.Images.SetKeyName(2, "2.png");
+ this.imageList1.Images.SetKeyName(3, "3.png");
+ this.imageList1.Images.SetKeyName(4, "4.png");
+ this.imageList1.Images.SetKeyName(5, "5.png");
+ this.imageList1.Images.SetKeyName(6, "6.png");
+ this.imageList1.Images.SetKeyName(7, "7.png");
+ this.imageList1.Images.SetKeyName(8, "8.png");
+ this.imageList1.Images.SetKeyName(9, "9.png");
+ //
+ // textBoxLog
+ //
+ this.textBoxLog.Dock = System.Windows.Forms.DockStyle.Fill;
+ this.textBoxLog.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(238)));
+ this.textBoxLog.Location = new System.Drawing.Point(0, 0);
+ this.textBoxLog.Multiline = true;
+ this.textBoxLog.Name = "textBoxLog";
+ this.textBoxLog.ReadOnly = true;
+ this.textBoxLog.ScrollBars = System.Windows.Forms.ScrollBars.Both;
+ this.textBoxLog.Size = new System.Drawing.Size(544, 196);
+ this.textBoxLog.TabIndex = 0;
+ //
+ // buttonRead
+ //
+ this.buttonRead.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
+ this.buttonRead.Enabled = false;
+ this.buttonRead.Location = new System.Drawing.Point(463, 23);
+ this.buttonRead.Name = "buttonRead";
+ this.buttonRead.Size = new System.Drawing.Size(75, 23);
+ this.buttonRead.TabIndex = 0;
+ this.buttonRead.Text = "Read";
+ this.buttonRead.UseVisualStyleBackColor = true;
+ this.buttonRead.Click += new System.EventHandler(this.buttonRead_Click);
+ //
+ // checkBoxActiveMode
+ //
+ this.checkBoxActiveMode.AutoSize = true;
+ this.checkBoxActiveMode.Checked = true;
+ this.checkBoxActiveMode.CheckState = System.Windows.Forms.CheckState.Checked;
+ this.checkBoxActiveMode.Location = new System.Drawing.Point(13, 27);
+ this.checkBoxActiveMode.Name = "checkBoxActiveMode";
+ this.checkBoxActiveMode.Size = new System.Drawing.Size(205, 17);
+ this.checkBoxActiveMode.TabIndex = 1;
+ this.checkBoxActiveMode.Text = "Active Mode (Default when power up)";
+ this.checkBoxActiveMode.UseVisualStyleBackColor = true;
+ this.checkBoxActiveMode.CheckedChanged += new System.EventHandler(this.checkBoxActiveMode_CheckedChanged);
+ //
+ // groupBox1
+ //
+ this.groupBox1.AutoSize = true;
+ this.groupBox1.Controls.Add(this.label7);
+ this.groupBox1.Controls.Add(this.textBox10_0);
+ this.groupBox1.Controls.Add(this.label4);
+ this.groupBox1.Controls.Add(this.textBox2_5);
+ this.groupBox1.Controls.Add(this.label5);
+ this.groupBox1.Controls.Add(this.textBox1_0);
+ this.groupBox1.Controls.Add(this.label6);
+ this.groupBox1.Controls.Add(this.textBoxCF_10_0);
+ this.groupBox1.Controls.Add(this.label3);
+ this.groupBox1.Controls.Add(this.textBoxCF_2_5);
+ this.groupBox1.Controls.Add(this.label2);
+ this.groupBox1.Controls.Add(this.textBoxCF_1_0);
+ this.groupBox1.Controls.Add(this.label1);
+ this.groupBox1.Dock = System.Windows.Forms.DockStyle.Bottom;
+ this.groupBox1.Location = new System.Drawing.Point(0, 196);
+ this.groupBox1.Name = "groupBox1";
+ this.groupBox1.Size = new System.Drawing.Size(544, 185);
+ this.groupBox1.TabIndex = 2;
+ this.groupBox1.TabStop = false;
+ this.groupBox1.Text = "Data";
+ //
+ // label7
+ //
+ this.label7.AutoSize = true;
+ this.label7.Location = new System.Drawing.Point(10, 156);
+ this.label7.Name = "label7";
+ this.label7.Size = new System.Drawing.Size(264, 13);
+ this.label7.TabIndex = 12;
+ this.label7.Text = "Note: CF=1 should be used in the factory environment.";
+ //
+ // textBox10_0
+ //
+ this.textBox10_0.Location = new System.Drawing.Point(228, 119);
+ this.textBox10_0.Name = "textBox10_0";
+ this.textBox10_0.ReadOnly = true;
+ this.textBox10_0.Size = new System.Drawing.Size(100, 20);
+ this.textBox10_0.TabIndex = 11;
+ //
+ // label4
+ //
+ this.label4.AutoSize = true;
+ this.label4.Location = new System.Drawing.Point(225, 103);
+ this.label4.Name = "label4";
+ this.label4.Size = new System.Drawing.Size(69, 13);
+ this.label4.TabIndex = 10;
+ this.label4.Text = "PM 10 μg/m³";
+ //
+ // textBox2_5
+ //
+ this.textBox2_5.Location = new System.Drawing.Point(228, 80);
+ this.textBox2_5.Name = "textBox2_5";
+ this.textBox2_5.ReadOnly = true;
+ this.textBox2_5.Size = new System.Drawing.Size(100, 20);
+ this.textBox2_5.TabIndex = 9;
+ //
+ // label5
+ //
+ this.label5.AutoSize = true;
+ this.label5.Location = new System.Drawing.Point(225, 64);
+ this.label5.Name = "label5";
+ this.label5.Size = new System.Drawing.Size(72, 13);
+ this.label5.TabIndex = 8;
+ this.label5.Text = "PM 2.5 μg/m³";
+ //
+ // textBox1_0
+ //
+ this.textBox1_0.Location = new System.Drawing.Point(228, 41);
+ this.textBox1_0.Name = "textBox1_0";
+ this.textBox1_0.ReadOnly = true;
+ this.textBox1_0.Size = new System.Drawing.Size(100, 20);
+ this.textBox1_0.TabIndex = 7;
+ //
+ // label6
+ //
+ this.label6.AutoSize = true;
+ this.label6.Location = new System.Drawing.Point(225, 25);
+ this.label6.Name = "label6";
+ this.label6.Size = new System.Drawing.Size(72, 13);
+ this.label6.TabIndex = 6;
+ this.label6.Text = "PM 1.0 μg/m³";
+ //
+ // textBoxCF_10_0
+ //
+ this.textBoxCF_10_0.Location = new System.Drawing.Point(13, 119);
+ this.textBoxCF_10_0.Name = "textBoxCF_10_0";
+ this.textBoxCF_10_0.ReadOnly = true;
+ this.textBoxCF_10_0.Size = new System.Drawing.Size(100, 20);
+ this.textBoxCF_10_0.TabIndex = 5;
+ //
+ // label3
+ //
+ this.label3.AutoSize = true;
+ this.label3.Location = new System.Drawing.Point(10, 103);
+ this.label3.Name = "label3";
+ this.label3.Size = new System.Drawing.Size(103, 13);
+ this.label3.TabIndex = 4;
+ this.label3.Text = "PM 10 μg/m³ (CF=1)";
+ //
+ // textBoxCF_2_5
+ //
+ this.textBoxCF_2_5.Location = new System.Drawing.Point(13, 80);
+ this.textBoxCF_2_5.Name = "textBoxCF_2_5";
+ this.textBoxCF_2_5.ReadOnly = true;
+ this.textBoxCF_2_5.Size = new System.Drawing.Size(100, 20);
+ this.textBoxCF_2_5.TabIndex = 3;
+ //
+ // label2
+ //
+ this.label2.AutoSize = true;
+ this.label2.Location = new System.Drawing.Point(10, 64);
+ this.label2.Name = "label2";
+ this.label2.Size = new System.Drawing.Size(106, 13);
+ this.label2.TabIndex = 2;
+ this.label2.Text = "PM 2.5 μg/m³ (CF=1)";
+ //
+ // textBoxCF_1_0
+ //
+ this.textBoxCF_1_0.Location = new System.Drawing.Point(13, 41);
+ this.textBoxCF_1_0.Name = "textBoxCF_1_0";
+ this.textBoxCF_1_0.ReadOnly = true;
+ this.textBoxCF_1_0.Size = new System.Drawing.Size(100, 20);
+ this.textBoxCF_1_0.TabIndex = 1;
+ //
+ // label1
+ //
+ this.label1.AutoSize = true;
+ this.label1.Location = new System.Drawing.Point(10, 25);
+ this.label1.Name = "label1";
+ this.label1.Size = new System.Drawing.Size(106, 13);
+ this.label1.TabIndex = 0;
+ this.label1.Text = "PM 1.0 μg/m³ (CF=1)";
+ //
+ // checkBoxSleepMode
+ //
+ this.checkBoxSleepMode.AutoSize = true;
+ this.checkBoxSleepMode.Location = new System.Drawing.Point(13, 50);
+ this.checkBoxSleepMode.Name = "checkBoxSleepMode";
+ this.checkBoxSleepMode.Size = new System.Drawing.Size(83, 17);
+ this.checkBoxSleepMode.TabIndex = 2;
+ this.checkBoxSleepMode.Text = "Sleep Mode";
+ this.checkBoxSleepMode.UseVisualStyleBackColor = true;
+ this.checkBoxSleepMode.CheckedChanged += new System.EventHandler(this.checkBoxSleepMode_CheckedChanged);
+ //
+ // groupBox2
+ //
+ this.groupBox2.AutoSize = true;
+ this.groupBox2.Controls.Add(this.label8);
+ this.groupBox2.Controls.Add(this.checkBoxSleepMode);
+ this.groupBox2.Controls.Add(this.buttonRead);
+ this.groupBox2.Controls.Add(this.checkBoxActiveMode);
+ this.groupBox2.Dock = System.Windows.Forms.DockStyle.Bottom;
+ this.groupBox2.Location = new System.Drawing.Point(0, 381);
+ this.groupBox2.Name = "groupBox2";
+ this.groupBox2.Size = new System.Drawing.Size(544, 108);
+ this.groupBox2.TabIndex = 3;
+ this.groupBox2.TabStop = false;
+ this.groupBox2.Text = "Modes";
+ //
+ // label8
+ //
+ this.label8.AutoSize = true;
+ this.label8.Location = new System.Drawing.Point(10, 79);
+ this.label8.Name = "label8";
+ this.label8.Size = new System.Drawing.Size(230, 13);
+ this.label8.TabIndex = 13;
+ this.label8.Text = "Not all sensors can support the above features.";
+ //
+ // UserControlLog
+ //
+ this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+ this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+ this.Controls.Add(this.textBoxLog);
+ this.Controls.Add(this.groupBox1);
+ this.Controls.Add(this.groupBox2);
+ this.Name = "UserControlLog";
+ this.Size = new System.Drawing.Size(544, 489);
+ this.groupBox1.ResumeLayout(false);
+ this.groupBox1.PerformLayout();
+ this.groupBox2.ResumeLayout(false);
+ this.groupBox2.PerformLayout();
+ this.ResumeLayout(false);
+ this.PerformLayout();
+
+ }
+
+ #endregion
+ private System.Windows.Forms.ImageList imageList1;
+ private System.Windows.Forms.TextBox textBoxLog;
+ private System.Windows.Forms.Button buttonRead;
+ private System.Windows.Forms.CheckBox checkBoxActiveMode;
+ private System.Windows.Forms.GroupBox groupBox1;
+ private System.Windows.Forms.TextBox textBox10_0;
+ private System.Windows.Forms.Label label4;
+ private System.Windows.Forms.TextBox textBox2_5;
+ private System.Windows.Forms.Label label5;
+ private System.Windows.Forms.TextBox textBox1_0;
+ private System.Windows.Forms.Label label6;
+ private System.Windows.Forms.TextBox textBoxCF_10_0;
+ private System.Windows.Forms.Label label3;
+ private System.Windows.Forms.TextBox textBoxCF_2_5;
+ private System.Windows.Forms.Label label2;
+ private System.Windows.Forms.TextBox textBoxCF_1_0;
+ private System.Windows.Forms.Label label1;
+ private System.Windows.Forms.Label label7;
+ private System.Windows.Forms.CheckBox checkBoxSleepMode;
+ private System.Windows.Forms.GroupBox groupBox2;
+ private System.Windows.Forms.Label label8;
+ }
+}
diff --git a/WindowsFormsApplication1/UserControlLog.cs b/WindowsFormsApplication1/UserControlLog.cs
new file mode 100644
index 0000000..da55cd6
--- /dev/null
+++ b/WindowsFormsApplication1/UserControlLog.cs
@@ -0,0 +1,82 @@
+using System;
+using System.Drawing;
+using System.Windows.Forms;
+using System.IO.Ports;
+
+namespace WindowsFormsApplication1
+{
+ public partial class UserControlLog : UserControl
+ {
+ private SerialPort port;
+ private PMS pms;
+
+ public UserControlLog(SerialPort port)
+ {
+ InitializeComponent();
+ this.port = port;
+ this.pms = new PMS(this.port);
+ this.pms.DataEvent += Pms_DataEvent;
+ this.pms.FeedbackEvent += Pms_RawDataEvent;
+
+ try
+ {
+ Font font = new Font(FontFamily.GenericMonospace, 7.5f);
+ textBoxLog.Font = font;
+ }
+ catch { }
+ }
+
+ private void Pms_RawDataEvent(object sender, PMS.RawDataEventArgs e)
+ {
+ this.Invoke((MethodInvoker)(() =>
+ {
+ textBoxLog.AppendText(e.Data + Environment.NewLine);
+ }));
+ }
+
+ private void Pms_DataEvent(object sender, PMS.DataEventArgs e)
+ {
+ this.Invoke((MethodInvoker)(() =>
+ {
+ textBoxCF_1_0.Text = e.PM_FE_UG_1_0.ToString();
+ textBoxCF_2_5.Text = e.PM_FE_UG_2_5.ToString();
+ textBoxCF_10_0.Text = e.PM_FE_UG_10_0.ToString();
+
+ textBox1_0.Text = e.PM_AE_UG_1_0.ToString();
+ textBox2_5.Text = e.PM_AE_UG_2_5.ToString();
+ textBox10_0.Text = e.PM_AE_UG_10_0.ToString();
+ }));
+ }
+
+ private void checkBoxActiveMode_CheckedChanged(object sender, EventArgs e)
+ {
+ if ((sender as CheckBox).Checked)
+ {
+ pms.ActiveMode();
+ buttonRead.Enabled = false;
+ }
+ else
+ {
+ pms.PassiveMode();
+ buttonRead.Enabled = true;
+ }
+ }
+
+ private void buttonRead_Click(object sender, EventArgs e)
+ {
+ pms.Read();
+ }
+
+ private void checkBoxSleepMode_CheckedChanged(object sender, EventArgs e)
+ {
+ if ((sender as CheckBox).Checked)
+ {
+ pms.Sleep();
+ }
+ else
+ {
+ pms.WakeUp();
+ }
+ }
+ }
+}
diff --git a/WindowsFormsApplication1/UserControlLog.resx b/WindowsFormsApplication1/UserControlLog.resx
new file mode 100644
index 0000000..d4ee2bc
--- /dev/null
+++ b/WindowsFormsApplication1/UserControlLog.resx
@@ -0,0 +1,193 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ 17, 17
+
+
+
+ AAEAAAD/////AQAAAAAAAAAMAgAAAFdTeXN0ZW0uV2luZG93cy5Gb3JtcywgVmVyc2lvbj00LjAuMC4w
+ LCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODkFAQAAACZTeXN0
+ ZW0uV2luZG93cy5Gb3Jtcy5JbWFnZUxpc3RTdHJlYW1lcgEAAAAERGF0YQcCAgAAAAkDAAAADwMAAACo
+ DgAAAk1TRnQBSQFMAgEBCgEAAWABAAFgAQABEAEAARgBAAT/AQkBAAj/AUIBTQE2AQQGAAE2AQQCAAEo
+ AwABQAMAAUgDAAEBAQABCAYAARIYAAGAAgABgAMAAoABAAGAAwABgAEAAYABAAKAAgADwAEAAcAB3AHA
+ AQAB8AHKAaYBAAEzBQABMwEAATMBAAEzAQACMwIAAxYBAAMcAQADIgEAAykBAANVAQADTQEAA0IBAAM5
+ AQABgAF8Af8BAAJQAf8BAAGTAQAB1gEAAf8B7AHMAQABxgHWAe8BAAHWAucBAAGQAakBrQIAAf8BMwMA
+ AWYDAAGZAwABzAIAATMDAAIzAgABMwFmAgABMwGZAgABMwHMAgABMwH/AgABZgMAAWYBMwIAAmYCAAFm
+ AZkCAAFmAcwCAAFmAf8CAAGZAwABmQEzAgABmQFmAgACmQIAAZkBzAIAAZkB/wIAAcwDAAHMATMCAAHM
+ AWYCAAHMAZkCAALMAgABzAH/AgAB/wFmAgAB/wGZAgAB/wHMAQABMwH/AgAB/wEAATMBAAEzAQABZgEA
+ ATMBAAGZAQABMwEAAcwBAAEzAQAB/wEAAf8BMwIAAzMBAAIzAWYBAAIzAZkBAAIzAcwBAAIzAf8BAAEz
+ AWYCAAEzAWYBMwEAATMCZgEAATMBZgGZAQABMwFmAcwBAAEzAWYB/wEAATMBmQIAATMBmQEzAQABMwGZ
+ AWYBAAEzApkBAAEzAZkBzAEAATMBmQH/AQABMwHMAgABMwHMATMBAAEzAcwBZgEAATMBzAGZAQABMwLM
+ AQABMwHMAf8BAAEzAf8BMwEAATMB/wFmAQABMwH/AZkBAAEzAf8BzAEAATMC/wEAAWYDAAFmAQABMwEA
+ AWYBAAFmAQABZgEAAZkBAAFmAQABzAEAAWYBAAH/AQABZgEzAgABZgIzAQABZgEzAWYBAAFmATMBmQEA
+ AWYBMwHMAQABZgEzAf8BAAJmAgACZgEzAQADZgEAAmYBmQEAAmYBzAEAAWYBmQIAAWYBmQEzAQABZgGZ
+ AWYBAAFmApkBAAFmAZkBzAEAAWYBmQH/AQABZgHMAgABZgHMATMBAAFmAcwBmQEAAWYCzAEAAWYBzAH/
+ AQABZgH/AgABZgH/ATMBAAFmAf8BmQEAAWYB/wHMAQABzAEAAf8BAAH/AQABzAEAApkCAAGZATMBmQEA
+ AZkBAAGZAQABmQEAAcwBAAGZAwABmQIzAQABmQEAAWYBAAGZATMBzAEAAZkBAAH/AQABmQFmAgABmQFm
+ ATMBAAGZATMBZgEAAZkBZgGZAQABmQFmAcwBAAGZATMB/wEAApkBMwEAApkBZgEAA5kBAAKZAcwBAAKZ
+ Af8BAAGZAcwCAAGZAcwBMwEAAWYBzAFmAQABmQHMAZkBAAGZAswBAAGZAcwB/wEAAZkB/wIAAZkB/wEz
+ AQABmQHMAWYBAAGZAf8BmQEAAZkB/wHMAQABmQL/AQABzAMAAZkBAAEzAQABzAEAAWYBAAHMAQABmQEA
+ AcwBAAHMAQABmQEzAgABzAIzAQABzAEzAWYBAAHMATMBmQEAAcwBMwHMAQABzAEzAf8BAAHMAWYCAAHM
+ AWYBMwEAAZkCZgEAAcwBZgGZAQABzAFmAcwBAAGZAWYB/wEAAcwBmQIAAcwBmQEzAQABzAGZAWYBAAHM
+ ApkBAAHMAZkBzAEAAcwBmQH/AQACzAIAAswBMwEAAswBZgEAAswBmQEAA8wBAALMAf8BAAHMAf8CAAHM
+ Af8BMwEAAZkB/wFmAQABzAH/AZkBAAHMAf8BzAEAAcwC/wEAAcwBAAEzAQAB/wEAAWYBAAH/AQABmQEA
+ AcwBMwIAAf8CMwEAAf8BMwFmAQAB/wEzAZkBAAH/ATMBzAEAAf8BMwH/AQAB/wFmAgAB/wFmATMBAAHM
+ AmYBAAH/AWYBmQEAAf8BZgHMAQABzAFmAf8BAAH/AZkCAAH/AZkBMwEAAf8BmQFmAQAB/wKZAQAB/wGZ
+ AcwBAAH/AZkB/wEAAf8BzAIAAf8BzAEzAQAB/wHMAWYBAAH/AcwBmQEAAf8CzAEAAf8BzAH/AQAC/wEz
+ AQABzAH/AWYBAAL/AZkBAAL/AcwBAAJmAf8BAAFmAf8BZgEAAWYC/wEAAf8CZgEAAf8BZgH/AQAC/wFm
+ AQABIQEAAaUBAANfAQADdwEAA4YBAAOWAQADywEAA7IBAAPXAQAD3QEAA+MBAAPqAQAD8QEAA/gBAAHw
+ AfsB/wEAAaQCoAEAA4ADAAH/AgAB/wMAAv8BAAH/AwAB/wEAAf8BAAL/AgAD/4IAASoJOAExASIEAAEi
+ CTgBMQEiJAABMQEqBzgCMQEqBQABIgc4AjEBKiQAATEBOAEqBikBKgE4ATEGAAEiBikBKgE4ATEkAAEp
+ AjgGAAEpAjgNAAEpAjgkAAEpAjgGAAEpAjgNAAEpAjgkAAEiAjgBIgUAASICOAEiDAABIgI4ASIjAAEi
+ AjgBIgUAASICOAEiDAABIgI4ASIkAAI4ASkGAAI4ASkNAAI4ASkkAAExATgHKQEqATgBKgYAASIGKQEq
+ ATgBKiQAASkBKgg4ASoBKQUAASIIOAEqASkkAAEpAjEHOAIqBAABKQIxBzgCKiQAASkBOAExBykCOAQA
+ ASkBOAExBykCOCQAASMCOAEOBQABKQI4AQ4DAAEjAjgBDgUAASkCOAEOIwABIgI4ASIFAAEiAjgBIgMA
+ ASICOAEiBQABIgI4ASIjAAEOAjgBIwUAAQ4COAEjAwABDgI4ASMFAAEOAjgBIyQAAjgBKQYAAjgBKQQA
+ AjgBKQYAAjgBKSQAATEBOAEqBgABMQE4ASoEAAExATgBKgYAATEBOAEqJAABMQE4ASoGKQEqATgBMQQA
+ ATEBOAEqBikBKgE4ATEkAAEqAjEHOAEqATEEAAEqAjEHOAEqATEkAAEiATEJOAEqBAABIgExCTgBKv8A
+ LgABIgQAASIJOAExASIEAAEqCTgBMQEiDwABIg4AAioFAAEiBzgCMQEqBAABMQEqBzgCMQEqDgACKg0A
+ ASoBOAExBgABIgYpASoBOAExBAABMQE4ASoGKQEqATgBMQ0AASoBOAExDQABKQI4DQABKQI4BAABKQI4
+ BgABKQI4DQABKQI4DQABKQI4DQABKQI4BAABKQI4BgABKQI4DQABKQI4DQABIgI4ASIMAAEiAjgBIgMA
+ ASICOAEiBQABIgI4ASIMAAEiAjgBIgwAASICOAEiDAABIgI4ASIDAAEiAjgBIgUAASICOAEiDAABIgI4
+ ASINAAI4ASkNAAI4ASkEAAI4ASkGAAI4ASkNAAI4ASkGAAEiBikBKgE4ASoGAAEiBikBKgE4ASoEAAEx
+ ATgHKQEqATgBKg0AASMBOAEqBQABIgg4ASoBKQUAASIIOAEqASkEAAEpASoIOAEqASkOAAEjASkEAAEp
+ AjEHOAIqBAABKQIxBzgBIwUAASkCMQc4ASMPAAEiASoEAAEpATgBMQcpAjgEAAEpATgBMQYpASIGAAEp
+ ATgBMQYpASIPAAEiAjgEAAEjAjgBDgUAASkCOAEOAwABIwI4AQ4MAAEjAjgBDhUAASMCOAEOAwABIgI4
+ ASIFAAEiAjgBIgMAASICOAEiDAABIgI4ASIVAAEiAjgBIgMAAQ4COAEjBQABDgI4ASMDAAEOAjgBIwwA
+ AQ4COAEjFQABDgI4ASMEAAI4ASkGAAI4ASkEAAI4ASkNAAI4ASkWAAI4ASkEAAExATgBKgYAATEBOAEq
+ BAABMQE4ASoNAAExATgBKhYAATEBOAEqBAABMQE4ASoGAAEjATgBMQQAATEBOAEqBikBIgYAATEBOAEq
+ BikBIgkABikBKgE4ATEEAAIqCAABIwExBAABKgIxBzgBIgUAASoCMQc4ASIHAAExBzgBKgExBAABIgoA
+ ASMEAAEiATEJOAEiBAABIgExCTgBIgUAATEJOAEq/wADAAEqCTgBMQEiDwABIgQAASoJOAExBQABIgk4
+ ATEBIgQAATEBKgc4AjEBKg4AAioEAAExASoHOAExBwABIgc4AjEBKgQAATEBOAEqBikBKgE4ATENAAEq
+ ATgBMQQAATEBOAEqBikJAAEiBikBKgE4ATEEAAEpAjgGAAEpAjgNAAEpAjgEAAEpAjgWAAEpAjgEAAEp
+ AjgGAAEpAjgNAAEpAjgEAAEpAjgWAAEpAjgEAAEiAjgBIgUAASICOAEiDAABIgI4ASIDAAEiAjgBIhUA
+ ASICOAEiAwABIgI4ASIFAAEiAjgBIgwAASICOAEiAwABIgI4ASIVAAEiAjgBIgQAAjgBKQYAAjgBKQ0A
+ AjgBKQQAAjgBKRYAAjgBKQQAATEBOAEiBgABIwE4ASoNAAEjATgBKgQAATEBOAcpASIIAAEiBikBKgE4
+ ASoEAAEpASMIAAEjASkOAAEjASkEAAEpASoIOAEiBgABIgg4ASoBKQQAASkBKggAASIBKg4AASIBKgYA
+ ATEHOAIqBgABMQc4AioEAAEpATgBKgYAASICOA0AASICOAcABykCOAcABykCOAQAASMCOAEOBQABKQI4
+ AQ4MAAEjAjgBDgwAASkCOAEODAABKQI4AQ4DAAEiAjgBIgUAASICOAEiDAABIgI4ASIMAAEiAjgBIgwA
+ ASICOAEiAwABDgI4ASMFAAEOAjgBIwwAAQ4COAEjDAABDgI4ASMMAAEOAjgBIwQAAjgBKQYAAjgBKQ0A
+ AjgBKQ0AAjgBKQ0AAjgBKQQAATEBOAEqBgABMQE4ASoNAAExATgBKg0AATEBOAEqDQABMQE4ASoEAAEx
+ ATgBKgYpASoBOAExDQABIwE4ATEHAAYpASoBOAExBwAGKQEqATgBMQQAASoCMQc4ASoBMQ4AASMBMQYA
+ ATEHOAEqATEGAAExBzgBKgExBAABIgExCTgBKg8AASMFAAExCTgBKgUAATEJOAEqgQABQgFNAT4HAAE+
+ AwABKAMAAUADAAFIAwABAQEAAQEFAAFAAQIWAAP//wD/AEMACw==
+
+
+
\ No newline at end of file
diff --git a/WindowsFormsApplication1/UserControlSettings.Designer.cs b/WindowsFormsApplication1/UserControlSettings.Designer.cs
new file mode 100644
index 0000000..9758984
--- /dev/null
+++ b/WindowsFormsApplication1/UserControlSettings.Designer.cs
@@ -0,0 +1,131 @@
+namespace WindowsFormsApplication1
+{
+ partial class UserControlSettings
+ {
+ ///
+ /// Required designer variable.
+ ///
+ private System.ComponentModel.IContainer components = null;
+
+ ///
+ /// Clean up any resources being used.
+ ///
+ /// true if managed resources should be disposed; otherwise, false.
+ protected override void Dispose(bool disposing)
+ {
+ if (disposing && (components != null))
+ {
+ components.Dispose();
+ }
+ base.Dispose(disposing);
+ }
+
+ #region Component Designer generated code
+
+ ///
+ /// Required method for Designer support - do not modify
+ /// the contents of this method with the code editor.
+ ///
+ private void InitializeComponent()
+ {
+ this.groupBox2 = new System.Windows.Forms.GroupBox();
+ this.buttonRefresh = new System.Windows.Forms.Button();
+ this.ConnectButton = new System.Windows.Forms.Button();
+ this.button1 = new System.Windows.Forms.Button();
+ this.label1 = new System.Windows.Forms.Label();
+ this.comboBoxPorts = new System.Windows.Forms.ComboBox();
+ this.groupBox2.SuspendLayout();
+ this.SuspendLayout();
+ //
+ // groupBox2
+ //
+ this.groupBox2.AutoSize = true;
+ this.groupBox2.Controls.Add(this.buttonRefresh);
+ this.groupBox2.Controls.Add(this.ConnectButton);
+ this.groupBox2.Controls.Add(this.button1);
+ this.groupBox2.Controls.Add(this.label1);
+ this.groupBox2.Controls.Add(this.comboBoxPorts);
+ this.groupBox2.Dock = System.Windows.Forms.DockStyle.Top;
+ this.groupBox2.Location = new System.Drawing.Point(0, 0);
+ this.groupBox2.Name = "groupBox2";
+ this.groupBox2.Padding = new System.Windows.Forms.Padding(10);
+ this.groupBox2.Size = new System.Drawing.Size(728, 99);
+ this.groupBox2.TabIndex = 1;
+ this.groupBox2.TabStop = false;
+ this.groupBox2.Text = "Serial port";
+ //
+ // buttonRefresh
+ //
+ this.buttonRefresh.Location = new System.Drawing.Point(140, 24);
+ this.buttonRefresh.Name = "buttonRefresh";
+ this.buttonRefresh.Size = new System.Drawing.Size(75, 23);
+ this.buttonRefresh.TabIndex = 7;
+ this.buttonRefresh.Text = "Refresh";
+ this.buttonRefresh.UseVisualStyleBackColor = true;
+ this.buttonRefresh.Click += new System.EventHandler(this.buttonRefresh_Click);
+ //
+ // ConnectButton
+ //
+ this.ConnectButton.Enabled = false;
+ this.ConnectButton.Location = new System.Drawing.Point(221, 24);
+ this.ConnectButton.Name = "ConnectButton";
+ this.ConnectButton.Size = new System.Drawing.Size(75, 23);
+ this.ConnectButton.TabIndex = 5;
+ this.ConnectButton.Text = "Open";
+ this.ConnectButton.UseVisualStyleBackColor = true;
+ //
+ // button1
+ //
+ this.button1.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
+ this.button1.AutoSize = true;
+ this.button1.Location = new System.Drawing.Point(605, 24);
+ this.button1.Name = "button1";
+ this.button1.Size = new System.Drawing.Size(110, 23);
+ this.button1.TabIndex = 4;
+ this.button1.Text = "Device Manager";
+ this.button1.UseVisualStyleBackColor = true;
+ this.button1.Click += new System.EventHandler(this.button1_Click);
+ //
+ // label1
+ //
+ this.label1.AutoSize = true;
+ this.label1.Location = new System.Drawing.Point(10, 63);
+ this.label1.Name = "label1";
+ this.label1.Size = new System.Drawing.Size(401, 13);
+ this.label1.TabIndex = 3;
+ this.label1.Text = "BaudRate = 9600, Parity = None, DataBits = 8, StopBits = One, Handshake = None";
+ //
+ // comboBoxPorts
+ //
+ this.comboBoxPorts.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
+ this.comboBoxPorts.FormattingEnabled = true;
+ this.comboBoxPorts.Location = new System.Drawing.Point(13, 26);
+ this.comboBoxPorts.Name = "comboBoxPorts";
+ this.comboBoxPorts.Size = new System.Drawing.Size(121, 21);
+ this.comboBoxPorts.TabIndex = 2;
+ this.comboBoxPorts.SelectedIndexChanged += new System.EventHandler(this.comboBoxPorts_SelectedIndexChanged);
+ //
+ // UserControlSettings
+ //
+ this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+ this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+ this.Controls.Add(this.groupBox2);
+ this.Name = "UserControlSettings";
+ this.Size = new System.Drawing.Size(728, 360);
+ this.Load += new System.EventHandler(this.UserControlSettings_Load);
+ this.groupBox2.ResumeLayout(false);
+ this.groupBox2.PerformLayout();
+ this.ResumeLayout(false);
+ this.PerformLayout();
+
+ }
+
+ #endregion
+ private System.Windows.Forms.GroupBox groupBox2;
+ private System.Windows.Forms.Label label1;
+ private System.Windows.Forms.Button button1;
+ public System.Windows.Forms.ComboBox comboBoxPorts;
+ public System.Windows.Forms.Button ConnectButton;
+ private System.Windows.Forms.Button buttonRefresh;
+ }
+}
diff --git a/WindowsFormsApplication1/UserControlSettings.cs b/WindowsFormsApplication1/UserControlSettings.cs
new file mode 100644
index 0000000..945b209
--- /dev/null
+++ b/WindowsFormsApplication1/UserControlSettings.cs
@@ -0,0 +1,51 @@
+using System;
+using System.Windows.Forms;
+using System.IO.Ports;
+
+namespace WindowsFormsApplication1
+{
+ public partial class UserControlSettings : UserControl
+ {
+ public UserControlSettings()
+ {
+ InitializeComponent();
+ }
+
+ private void UserControlSettings_Load(object sender, EventArgs e)
+ {
+ buttonRefresh_Click(this, EventArgs.Empty);
+ }
+
+ private void linkLabel1_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
+ {
+ System.Diagnostics.Process.Start((sender as LinkLabel).Text);
+ }
+
+ private void button1_Click(object sender, EventArgs e)
+ {
+ System.Diagnostics.Process.Start("devmgmt.msc");
+ }
+
+ private void comboBoxPorts_SelectedIndexChanged(object sender, EventArgs e)
+ {
+ ConnectButton.Enabled = comboBoxPorts.SelectedIndex > -1;
+ }
+
+ private void buttonRefresh_Click(object sender, EventArgs e)
+ {
+ comboBoxPorts.Items.Clear();
+
+ foreach (string s in SerialPort.GetPortNames())
+ {
+ comboBoxPorts.Items.Add(s);
+ }
+
+ string storedCom = Properties.Settings.Default.COM;
+
+ if (storedCom != String.Empty && comboBoxPorts.Items.Count > 0)
+ {
+ comboBoxPorts.SelectedItem = storedCom;
+ }
+ }
+ }
+}
diff --git a/WindowsFormsApplication1/UserControlSettings.resx b/WindowsFormsApplication1/UserControlSettings.resx
new file mode 100644
index 0000000..1af7de1
--- /dev/null
+++ b/WindowsFormsApplication1/UserControlSettings.resx
@@ -0,0 +1,120 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
\ No newline at end of file
diff --git a/WindowsFormsApplication1/app.config b/WindowsFormsApplication1/app.config
new file mode 100644
index 0000000..34b37ed
--- /dev/null
+++ b/WindowsFormsApplication1/app.config
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file