Метеостанція + побудова графіку + C#

This entry was posted by Опубліковано: 08.06.2015

Автор: Alex-human, переклад.arduino126-1
Джерело:http://cxem.net

Хоча я новачок в роботі з arduino, і все ще не знаю добре про можливості даного апарату, я вирішив поділитися своїм успішним досвідом, тому що знаю, як це – шукати те, що не можливо знайти, особливо коли його просто неіснує. В цій статті я докладно опишу мій проект, який є моєю практичною роботою в університеті. Мені його ніхто не нав’язував, просто друг захопився і показав мені. Мене ця штукенція звичайно ж зацікавила і я вирішив спробувати. До того ж програма не надто складна.

Отже, робота полягає в наступному: з відомого багатьом давача DHT11 (давач вологості і температури) приймаємо дані через COM порт, далі записуємо дані в текстовий файл і за цими даними будуємо графік змін.

Arduino Uno побудований на ATmega328. Платформа має 14 цифрових входів/виходів, 6 аналогових входів, кварцовий генератор 16 МГц, роз’єм USB, силовий роз’єм, роз’їм ICSP і кнопку перезавантаження. Для роботи необхідно підключити платформу до комп’ютера з допомогою кабеля USB, або подати живлення з допомогою адаптера AC/DC або батареї.

Характеристики:

Мікроконтролер           ATmega328

Рабоча напруга              5 В

Вхідна напруга (рекомендована)       7-12 В

Вхідна напруга (гранична)       6-20 В

Цифрові Входи/Виходи            14

Аналогові входи            6

Постійний струм через вхід/вихід      40 мА

Постійний струм для виводу 3.3 В       50 мА

Флеш – пам’ять              32 Кб (ATmega328) з яких 0.5 Кб використовується для завантажувача

ОЗП       2 Кб (ATmega328)

EEPROM              1 Кб (ATmega328)

Тактова частота              16 МГц

 

Датчик DHT11

arduino126-2

Відносна вологість:

Роздільна здатність = 16 Bit

повторюваність = ±1%

точність = якщо 25℃, то ±5%

взаємозамінність = повністю взаємозамінний

час відгуку = 1-2 сек

гістерезис = <±0,3% RH

стабільність = <±0,5% RH/год

 

Температура:

Роздільна здатність = 16 Bit

повторюваність = ±0,2℃

діапазон = якщо 25℃ ± 2℃

час відгуку = 1-2 сек

 

​Електричні характеристики:

живлення = 3,5 – 5,5 V

 

Фотографія давача в розрізі:

arduino126-3

DHT11 цифровий давач температури і вологості є складеним давачем, який містить калібрований цифровий вихідний сигнал з показами температури і вологості. Він має високу надійність та чудову довготривалу стабільність роботи. Давач включає в себе резистивний сенсор вологості і компоненти NTC (negative temperature coefficient) структури для вимірювання температури.

 

Підключення

arduino126-4

1 – VCC – живлення 3,5 – 5,5 V

2 – DATA – передача даних

3 – NC – не використовується

4 – GND – від’ємне живлення

 

Для підключення до arduino необхідно під’ єднати між 1 і 2 ніжкою резистор = 10кОм.

arduino126-5

Схема підєднання

arduino126-6

Схема:

arduino126-7

Програмний код (скетч для давача DHT11)

#include "DHT.h"
#define DHTPIN 2     // у меня подключен ко 2 пину, поэтому 2
#define DHTTYPE DHT11   // указываем какой датчик
DHT dht(DHTPIN, DHTTYPE);
void setup() {
Serial.begin(9600); //указываем скорость передачи в бодах
dht.begin();
}
void loop() {
int h = dht.readHumidity();//переменная для влажности
int t = dht.readTemperature();//переменная для температуры
if (isnan(t) || isnan(h)) {//проверка (что мы получаем на запрос из датчика - цифры?)
Serial.println("Failed to read from DHT");//сообщение об ошибке
}
else {
//Serial.print("Humidity: ");
<strong>   </strong>Serial.print(h);//вывожу построчно - влажность
Serial.print("\t\n");//сдвиг каретки и начало строки
// Serial.print("Temperature: ");
Serial.print(t);//температура
Serial.print("\n");
//Serial.println(" *C");
}
delay(60000);//задержка времени в милсек. = 1 мин.
//delay(3600000);//на каждый час
}

Завантажую даний скетч, і кожну хвилину отримую дані в моніторі COM порту

arduino126-8

34 – в % відносна вологість

25 – в ℃ температура

 

Далі я так би мовити прикрашав свою програму, надавав їй товарного вигляду. Все це я робив в середовищі програмування Microsoft Visual Studio 2012 .NET. Я зробив за стосунок, який через COM порт отримує дані і обробляє їх. Отримую і записую у файл. Також порядково. В першому рядку значення, а другому – дата і час моменту отримання даних. Це згодиться для побудови графіків. Хто не знайомий з C#, дуже рекомендую – зручна річ. Створюю форму з 2-ма текст боксами, перший буде виводити значення вологості, другий – значення температури. Із них створюється файл, якщо не був створений, а якщо вже існує то дописуємо в нього. 2 файли – 1- Графік температури, 2-Графік вологості. Назви можете придумувати свої. Елементи, що використовуються в програмі : : textbox і textbox1, openFileDialog – для роботи з вибором файлу для графіка, notifyIcon – для роботи з іконкою, для звертання в трей.

Ось запуск застосунку

arduino126-9

Для перегляду графіка, натискаємо на кнопку Демонстрація графіку і вибираємо файл, тобто те що ми хочемо побачити (вологість чи температуру)

arduino126-10

Далі натискаємо – Відкрити і побачимо графік

arduino126-11

Це графік відносної вологості. Графік має властивість – він масштабується по осі Х. Якщо інтервал великий – ми мишкою виділяємо зону, яка цікава для нас і вона наближується. Якщо загальний графік то на осі Х біля 0 натискаємо “-” і графік буде загальним.

Також я трохи вдосконалив програму – зробив так щоб вона зверталася в трей. Бо для того щоб працювати вона має бути запущена і хоча вікно можна звертати, але ймовірно воно буде заважати. А так дуже зручно.

arduino126-12

1-ий значок в треї – програма. Після натискання лівою кнопкою мишки – звертається або розвертається.

 

Наводжу сирець своєї програми:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO.Ports;
using System.IO;

namespace arduino
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
notifyIcon1.Visible = false;
this.notifyIcon1.MouseClick += new MouseEventHandler(notifyIcon1_MouseClick);
this.Resize += new System.EventHandler(this.Form1_Resize);

// Открываем порт, и задаем скорость в 9600 бод
serialPort1.PortName = "COM6";
serialPort1.BaudRate = 9600;
serialPort1.DtrEnable = true;
serialPort1.Open();
serialPort1.DataReceived += serialPort1_DataReceived;
serialPort1.DataReceived += serialPort1_DataReceived1;
}

//****** поток ком порта
private void serialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
{
string vlag = serialPort1.ReadLine();
this.BeginInvoke(new LineReceivedEvent(LineReceived), vlag);
}

private void serialPort1_DataReceived1(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
{
string temp = serialPort1.ReadLine();
this.BeginInvoke(new LineReceivedEvent1(LineReceived1), temp);
}

//запись влажности
private delegate void LineReceivedEvent(string vlag);

private void LineReceived(string vlag)
{
textBox1.Text = vlag;
string path = "График_влажности.txt";
string date = DateTime.Now.ToString();

// Создание файла и запись в него

using (StreamWriter sw = File.AppendText(path))
{
sw.WriteLine(vlag);
sw.WriteLine(date);
}
}

//запись температуры
private delegate void LineReceivedEvent1(string temp);
private void LineReceived1(string temp)
{
textBox2.Text = temp.ToString();
string path = "График_температуры.txt";
string date = DateTime.Now.ToString();

// Создание файла и запись в него
using (StreamWriter sw = File.AppendText(path))
{
sw.WriteLine(temp);
sw.WriteLine(date);
}
}

private void button1_Click(object sender, EventArgs e)
{
if (openFileDialog1.ShowDialog() == DialogResult.OK)
{
chart1.ChartAreas[0].AxisX.ScaleView.Zoom(0,30);
chart1.ChartAreas[0].CursorX.IsUserEnabled = true;
chart1.ChartAreas[0].CursorX.IsUserSelectionEnabled = true;
chart1.ChartAreas[0].AxisX.ScaleView.Zoomable = true;
chart1.ChartAreas[0].AxisX.ScrollBar.IsPositionedInside = true;

//chart1.ChartAreas[0].AxisY.ScaleView.Zoom(0, 30);
//chart1.ChartAreas[0].CursorY.IsUserEnabled = true;
//chart1.ChartAreas[0].CursorY.IsUserSelectionEnabled = true;
//chart1.ChartAreas[0].AxisY.ScaleView.Zoomable = true;
//chart1.ChartAreas[0].AxisY.ScrollBar.IsPositionedInside = true;

StreamReader streamReader = new StreamReader(openFileDialog1.FileName);
chart1.Series[0].Points.Clear();
while (!streamReader.EndOfStream)
{
string Y = streamReader.ReadLine();
string X = streamReader.ReadLine();
chart1.Series[0].Color = Color.Red;
chart1.Series[0].BorderWidth = 1;
chart1.Series[0].Points.AddXY(X, Y);
}
streamReader.Close();
}
}
private void Form1_Resize(object sender, EventArgs e)
{
if (this.WindowState == FormWindowState.Minimized)
{
this.Hide();
notifyIcon1.Visible = true;
}
}

private void notifyIcon1_MouseClick(object sender, MouseEventArgs e)
{
this.Show();
this.WindowState = FormWindowState.Normal;
notifyIcon1.Visible = false;
}
}
}

Прикріплені файли:

Сирець на C# для завантаження.

Скетч для Arduino.