利用arduino采集温湿度,客户端程序显示实时曲线图


// Example testing sketch for various DHT humidity/temperature sensors
// Written by ladyada, public domain

#include "DHT.h"

#define DHTPIN 2     // what digital pin we're connected to

// Uncomment whatever type you're using!
#define DHTTYPE DHT11   // DHT 11
//#define DHTTYPE DHT22   // DHT 22  (AM2302), AM2321
//#define DHTTYPE DHT21   // DHT 21 (AM2301)

// Connect pin 1 (on the left) of the sensor to +5V
// NOTE: If using a board with 3.3V logic like an Arduino Due connect pin 1
// to 3.3V instead of 5V!
// Connect pin 2 of the sensor to whatever your DHTPIN is
// Connect pin 4 (on the right) of the sensor to GROUND
// Connect a 10K resistor from pin 2 (data) to pin 1 (power) of the sensor

// Initialize DHT sensor.
// Note that older versions of this library took an optional third parameter to
// tweak the timings for faster processors.  This parameter is no longer needed
// as the current DHT reading algorithm adjusts itself to work on faster procs.
DHT dht(DHTPIN, DHTTYPE);

void setup() {
  Serial.begin(9600);
  Serial.println("DHTxx test!");

  dht.begin();
}

void loop() {
  // Wait a few seconds between measurements.
  delay(2000);

  // Reading temperature or humidity takes about 250 milliseconds!
  // Sensor readings may also be up to 2 seconds 'old' (its a very slow sensor)
  float h = dht.readHumidity();
  // Read temperature as Celsius (the default)
  float t = dht.readTemperature();
  // Read temperature as Fahrenheit (isFahrenheit = true)
  float f = dht.readTemperature(true);

  // Check if any reads failed and exit early (to try again).
  if (isnan(h) || isnan(t) || isnan(f)) {
    Serial.println("Failed to read from DHT sensor!");
    return;
  }

  // Compute heat index in Fahrenheit (the default)
  float hif = dht.computeHeatIndex(f, h);
  // Compute heat index in Celsius (isFahreheit = false)
  float hic = dht.computeHeatIndex(t, h, false);

 // Serial.print("Humidity: ");
  Serial.print("ST");
  Serial.print(h);
 // Serial.print(" %\t");
 // Serial.print("Temperature: ");
    Serial.print(t);
//  Serial.print(" *C ");
    Serial.print(f);
//  Serial.print(" *F\t");
//  Serial.print("Heat index: ");
//  Serial.print(hic);
//  Serial.print(" *C ");
//  Serial.print(hif);
//  Serial.println(" *F");
}

以上是arduino单片机程序 网上找别人的


以下是客户端界面和代码

利用arduino采集温湿度,客户端程序显示实时曲线图_第1张图片

利用arduino采集温湿度,客户端程序显示实时曲线图_第2张图片

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.Windows.Forms.DataVisualization.Charting;
using System.Data.SqlClient;
using System.Runtime.InteropServices;

namespace 温湿度采集
{
   

    
    public partial class Form1 : Form
    {
        private SerialPort comm = new SerialPort();
        private StringBuilder builder = new StringBuilder();//避免在事件处理方法中反复的创建,定义到外面。
        private long received_count = 0;//接收计数
        private long send_count = 0;//发送计数
        private bool Listening = false;//是否没有执行完invoke相关操作
        private bool Closing = false;//是否正在关闭串口,执行Application.DoEvents,并阻止再次invoke
        private List buffer = new List(8192);//默认分配1页内存,并始终限制不允许超过
        private byte[] binary_data_1 = new byte[31];//53 54 32 30 2E 30 30 32 31 2E 30 30 36 39 2E 38 30 

        double wend;
        double shid;
        public Form1()
        {
            InitializeComponent();
            InitChart();
            InitChart2();
            ConsoleEx.AllocConsole(); 
        }
        System.Windows.Forms.Timer chartTimer = new System.Windows.Forms.Timer();

        
        private void InitChart()
        {
            DateTime time = DateTime.Now;
            chartTimer.Interval = 1000;
           
            wendu.DoubleClick += wendu_DoubleClick;

            Series series = wendu.Series[0];
            series.ChartType = SeriesChartType.Spline;

            wendu.ChartAreas[0].AxisX.LabelStyle.Format = "HH:mm:ss";
            wendu.ChartAreas[0].AxisX.ScaleView.Size = 5;
            wendu.ChartAreas[0].AxisX.ScrollBar.IsPositionedInside = true;
            wendu.ChartAreas[0].AxisX.ScrollBar.Enabled = true;

            chartTimer.Start();

        }
        private void InitChart2()
        {
            DateTime time1 = DateTime.Now;
            chartTimer.Interval = 1000;

           // wendu.DoubleClick += wendu_DoubleClick;

            Series series = shidu.Series[0];
            series.ChartType = SeriesChartType.Spline;

            shidu.ChartAreas[0].AxisX.LabelStyle.Format = "HH:mm:ss";
            shidu.ChartAreas[0].AxisX.ScaleView.Size = 5;
            shidu.ChartAreas[0].AxisX.ScrollBar.IsPositionedInside = true;
            shidu.ChartAreas[0].AxisX.ScrollBar.Enabled = true;

            chartTimer.Start();

        }

        void wendu_DoubleClick(object sender, EventArgs e)
        {
            wendu.ChartAreas[0].AxisX.ScaleView.Size = 5;
            wendu.ChartAreas[0].AxisX.ScrollBar.IsPositionedInside = true;
            wendu.ChartAreas[0].AxisX.ScrollBar.Enabled = true;
            //throw new NotImplementedException();
        }

       


        private void Form1_Load(object sender, EventArgs e)
        {
            comm.PortName = "COM3";
            comm.BaudRate = 9600;
            comm.DataBits = 7;
            comm.Open();
            comm.NewLine = "\r\n";
            comm.RtsEnable = true;//根据实际情况吧。

            //添加事件注册
            comm.DataReceived += comm_DataReceived;
        }

        private void comm_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            if (Closing) return;//如果正在关闭,忽略操作,直接返回,尽快的完成串口监听线程的一次循环
            try
            {
                Listening = true;//设置标记,说明我已经开始处理数据,一会儿要使用系统UI的。
                int n = comm.BytesToRead;//先记录下来,避免某种原因,人为的原因,操作几次之间时间长,缓存不一致
                byte[] buf = new byte[n];//声明一个临时数组存储当前来的串口数据
                received_count += n;//增加接收计数
                comm.Read(buf, 0, n);//读取缓冲数据

                /////////////////////////////////////////////////////////////////////////////////////////////////////////////
                //<协议解析>
                int data_1_catched = 0;//缓存记录数据是否捕获到
                //1.缓存数据
                buffer.AddRange(buf);
                //2.完整性判断
                while (buffer.Count >= 17)//至少要包含头(2字节)+长度(1字节)+校验(1字节)
                {
                    //请不要担心使用>=,因为>=已经和>,<,=一样,是独立操作符,并不是解析成>和=2个符号
                    //2.1 查找数据头
                    if (buffer[0] == 0x53)
                    {
                        //2.2 探测缓存数据是否有一条数据的字节,如果不够,就不用费劲的做其他验证了
                        //前面已经限定了剩余长度>=4,那我们这里一定能访问到buffer[2]这个长度
                        int len = 17;//数据长度
                        //数据完整判断第一步,长度是否足够
                        //len是数据段长度,4个字节是while行注释的3部分长度
                        if (buffer.Count < len) break;//数据不够的时候什么都不做
                                                          //这里确保数据长度足够,数据头标志找到,我们开始计算校验
                                                          //2.3 校验数据,确认数据正确
                                                          //异或校验,逐个字节异或得到校验码
                        #region 校验和
                        //byte checksum = 0;
                        //for (int i = 0; i < len + 3; i++)//len+3表示校验之前的位置
                        //{
                        //    checksum ^= buffer[i];
                        //}
                        //if (checksum != buffer[len + 3]) //如果数据校验失败,丢弃这一包数据
                        //{
                        //    buffer.RemoveRange(0, len + 4);//从缓存中删除错误数据
                        //    continue;//继续下一次循环
                        //}
                        //至此,已经被找到了一条完整数据。我们将数据直接分析,或是缓存起来一起分析
                        //我们这里采用的办法是缓存一次,好处就是如果你某种原因,数据堆积在缓存buffer中
                        //已经很多了,那你需要循环的找到最后一组,只分析最新数据,过往数据你已经处理不及时
                        //了,就不要浪费更多时间了,这也是考虑到系统负载能够降低。
                        #endregion

                        buffer.CopyTo(0, binary_data_1, 0, 17);//复制一条完整数据到具体的数据缓存
                        data_1_catched = 1;
                        buffer.RemoveRange(0, 17);//正确分析一条数据,从缓存中移除数据。
                    }
                    else
                    {
                        //这里是很重要的,如果数据开始不是头,则删除数据
                        buffer.RemoveAt(0);
                    }
                }
                //分析数据
                if (data_1_catched == 1)
                {
                    foreach (byte str in binary_data_1)
                         Console.Write("{0} ", Convert.ToChar(str));
                    int h1 = binary_data_1[2]-48;
                    Console.WriteLine( h1);
                    int h2 = binary_data_1[3] - 48;
                    int h3 = binary_data_1[5] - 48;
                    int h4 = binary_data_1[6] - 48;
                    double h = h1 * 10 + h2 + h3 * 0.1 + h4 * 0.01;
                    int w1 = binary_data_1[7] - 48;
               
                    int w2 = binary_data_1[8] - 48;
                    int w3 = binary_data_1[10] - 48;
                    int w4 = binary_data_1[11] - 48;
                    double w = w1 * 10 + w2 + w3 * 0.1 + w4 * 0.01;
                    //Console.WriteLine("{0}   {1}  {2}  {3} {4}" ,h1,h2,h3,h4,h);
                    shid = h;
                    wend = w;
                    this.Invoke((EventHandler)(delegate {
                        Series series = shidu.Series[0];
                        series.Points.AddXY(DateTime.Now, shid);
                        shidu.ChartAreas[0].AxisX.ScaleView.Position = series.Points.Count - 5;
                        Series series1 = wendu.Series[0];
                        series1.Points.AddXY(DateTime.Now, wend);
                        wendu.ChartAreas[0].AxisX.ScaleView.Position = series.Points.Count - 5;
                    }));
                    

                    //int to1 = (Convert.ToInt32(binary_data_1[22]) - 48);
                    //int to2 = (Convert.ToInt32(binary_data_1[23]) - 48);
                    //int t = t1 * 10 + t2;
                    //int h = h1 * 10 + h2;
                    //int to = to1 * 10 + to2;
                    //DateTime d = DateTime.Now;
                    //Console.Write(d);
                    #region 连接数据库
                    //string constr = "Data source=(local);Initial Catalog=ww;Integrated Security=true";
                    //using (SqlConnection con = new SqlConnection(constr))
                    //{
                    //    //con.Open();
                    //    string sql = string.Format("insert into hj values('{0}','{1}','{2}',getdate())", t, h, to);
                    //    using (SqlCommand cmd = new SqlCommand(sql, con))
                    //    {
                    //        con.Open();
                    //        int r = cmd.ExecuteNonQuery();
                    //        if (r > 0)
                    //        {
                    //            Console.Write("charuchengg");
                    //        }
                    //        else
                    //        {
                    //            Console.Write("shibai");
                    //        }
                    //    }
                    //}
                    #endregion

                    //int val = Convert.ToInt16((b1 << 8) + b2);//两个字节合并
                    //int b3 = Convert.ToInt16(binary_data_1[6]);
                    //int b4 = Convert.ToInt16(binary_data_1[7]);
                    //int b5 = Convert.ToInt16(binary_data_1[8]);
                    //int b6 = Convert.ToInt16(binary_data_1[9]);
                    //int b7 = Convert.ToInt16(binary_data_1[10]);
                    //int czbh1 = Convert.ToInt16(binary_data_1[11]);
                    //int czbh2 = Convert.ToInt16(binary_data_1[12]);
                    //int sd = Convert.ToInt32((czbh1 << 8) + czbh2);
                    //int jsd = Convert.ToInt32(binary_data_1[13]);
                    //Console.WriteLine("{0}年{1}月{2}日{3}时{4}分{5}秒,编号时{6},是否超限{7}", Convert.ToString(val),
                    //    Convert.ToString(b3), Convert.ToString(b4), Convert.ToString(b5), Convert.ToString(b6),
                    //    Convert.ToString(b7), Convert.ToString(sd), Convert.ToString(jsd ));
                    //Console.WriteLine("H的值{0} }",  h);
                    //Console.WriteLine(b2);
                    //foreach (byte str in binary_data_1)
                    //    Console.Write("{0} ", Convert.ToChar(str));






                }
               
                //如果需要别的协议,只要扩展这个data_n_catched就可以了。往往我们协议多的情况下,还会包含数据编号,给来的数据进行
                //编号,协议优化后就是: 头+编号+长度+数据+校验
                //
                /////////////////////////////////////////////////////////////////////////////////////////////////////////////

                builder.Clear();//清除字符串构造器的内容

                #region MyRegion
                //因为要访问ui资源,所以需要使用invoke方式同步ui。
                //this.Invoke((EventHandler)(delegate
                //{
                //    //判断是否是显示为16禁止
                //    if (checkBoxHexView.Checked)
                //    {
                //        //依次的拼接出16进制字符串
                //        foreach (byte b in buf)
                //        {
                //            builder.Append(b.ToString("X2") + " ");
                //        }
                //    }
                //    else
                //    {
                //        //直接按ASCII规则转换成字符串
                //        builder.Append(Encoding.ASCII.GetString(buf));
                //    }
                //    //追加的形式添加到文本框末端,并滚动到最后。
                //    this.txGet.AppendText(builder.ToString());
                //    //修改接收计数
                //    labelGetCount.Text = "Get:" + received_count.ToString();
                //}));

                #endregion

            }
            finally
            {
                Listening = false;//我用完了,ui可以关闭串口了。
            }
            
            
            //throw new NotImplementedException();
        }
    }
    public class ConsoleEx
    {
        /// 
        /// 启动控制台
        /// 
        [DllImport("kernel32.dll")]
        public static extern bool AllocConsole();

        /// 
        /// 释放控制台
        /// 
        [DllImport("kernel32.dll")]
        public static extern bool FreeConsole();
    }

}



你可能感兴趣的:(利用arduino采集温湿度,客户端程序显示实时曲线图)