Главная » Arduino
Призовой фонд
на май 2017 г.
1. Тестер компонентов MG328
Паяльник
2. Осциллограф DSO138
Паяльник
3. Регулируемый паяльник 60 Вт
Паяльник
4. 100 руб.
От пользователей

Метеостанция + построение графика + C#

Хоть я в работе с arduino новичок, и не все еще знаю о способностях данного аппарата, я решил поделиться своим успешным опытом, потому как знаю, каково это - искать то, что невозможно найти или этого просто нет. В данной статье я подробно опишу мой проект, который явился моей практикой в университете. Мне никто не навязывал, просто друг увлекся, показал мне. Меня конечно же эта штука заинтересовала и я решил попробовать. Моя программа не так сложна. 

Итак, работа заключается в следующем: с известного многим датчика DHT11 (датчик влажности и температуры) принимаем данные через COM порт, далее записываем данные в текстовый файл и по этим данным строим график изменений.

Arduino Uno

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

Относительная влажность:

  • разрешение = 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

Фотография датчика в разрезе:

DHT11 цифровой датчик температуры и влажности является составным датчиком, который содержит калиброванный цифровой выходной сигнал с показаниями температуры и влажности. Он имеет высокую надежность и превосходную долговременную стабильность работы. Датчик включает в себя резистивный сенсор влажности и компоненты NTC структуры для измерения температуры.

Подключение

1 - VCC - питание 3,5 - 5,5 V
2 - DATA - передача данных
3 - NC - не используется
4 - GND - отрицательное питание

Для подключения к arduino необходимо подключить между 1 и 2 ножкой резистор = 10кОм.

Схемы подключения

Схема:

Программный код (скетч для датчика 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: "); 
    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 порта

34 - в % относительная влажность
25 - в ℃ температура

Далее я так сказать украшал свою программу, придавал ей товарный вид. Все это я делал в среде программирования Microsoft Visual Studio 2012 .NET.  Я сделал приложение, которое через COM порт получает данные и обрабатывает их. Получаю, записываю в файл. Тоже построчно. В первой строке значение, вторая строка - дата и время в момент получения данных. Это пригодится для построения графиков. Кто не знаком с работой в C# очень рекомендую, удобная вещь. Создаю форму с 2-мя текстбоксами, 1- будет выводится значение влажности, 2 - значение температуры. Из них создается файл, если не был создан, если был создан до дописываем в него. 2 файла - 1-График_температуры, 2-График_влажности. Названия можете придумать свои. Элементы, используемые в программе: textbox и textbox1, openFileDialog - для работы с выбором файла для графика, notifyIcon - для работы с иконкой, для сворачивания в трей.

Вот запуск приложения

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

Далее нажимаем - Открыть, и увидим график

Это график относительной влажности. Есть свойство графика - он масштабируется по оси Х. Если большой интервал, мы мышкой выделяем зону, которая нам интересна и он приближает. Если общий график, то на оси Х около 0 нажмем "-" и график будет общим.

Также я немного усовершенствовал программу, я сделал так, чтобы она сворачивалась в трей. Потому что, чтобы работать, она должна быть открыта, или запущена, ее можно свернуть как окно, но вероятно что она будет мешать. А так очень удобно.

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;
        }
    }
}

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

Теги:

Опубликована: 0 0
Я собрал 0 1
x

Оценить статью

  • Техническая грамотность
  • Актуальность материала
  • Изложение материала
  • Полезность устройства
  • Повторяемость устройства
  • Орфография
0

Средний балл статьи: 5 Проголосовало: 1 чел.

Комментарии (8) | Я собрал (0) | Подписаться

+1
freearduino #
Интересная задумка!
Мне вот интересно как сделать вывод нескольких графиков одновременно?
Ответить
0

[Автор]
alex-human #
Можно создать еще один элемент - график, связать каждый текстовый файл с графиком и все. Например: верхний график - температурный, нижний - давления. Очень просто.
Ответить
0
DS #
Ответить
0
варп #
Резистор на фотографии в тексте статьи имеет номинал НЕ равный 10 кОм. (это так - уточнение)
Ответить
0
ConGo #
у меня почему то график строится в виде пилы от нуля до текущего считанного из файла значения температуры или влажности. какой параметр графика за это отвечает и что надо поправить?
Ответить
0
Александр #
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();
Вот в этом цикле мы считываем из файла значения и отображаем их на осях точками chart1.Series[0].Points.AddXY(X, Y);. Все зависит от ваших значений в файле. если там идут значения -10, -3, 10, 15, -25 то конечно график такой и будет.
Ответить
0
ConGo #
Значения из файла 24 24 25 24 24 и т.д., а линия строится не от точки к точки а как бы через ноль - в виде пилы ... вот и не пойму откуда берутся нулевые значения. Хотя они (нулевые значения ) находятся между датами, которые откладываются по оси Х, т.е. сами точки на графике строятся правильно - каждой дате соответствует значение температуры, а вот линия строится не от точки к точке, а падая в ноль и поднимаясь к следующей точке - может в свойствах графика где-то?
Ответить
0
1йНеизвестный #
Только я заметил, что схема подключения со схемой не стыкуется? И чему верить?
Ответить
Добавить комментарий
Имя:
E-mail:
не публикуется
Текст:
Защита от спама:
В чем измеряется электрическое сопротивление?
Файлы:
 
Для выбора нескольких файлов использйте CTRL

Модуль измерения тока на ACS712 (30А)
Модуль измерения тока на ACS712 (30А)
Мультиметр Mastech MS8268 Конструктор УНЧ 60 Вт на LM3886
вверх