1. 程式人生 > >利用arduino採集溫溼度,客戶端程式顯示實時曲線圖

利用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微控制器程式 網上找別人的

以下是客戶端介面和程式碼



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<byte> buffer = new List<byte>(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
    {
        /// <summary>
        /// 啟動控制檯
        /// </summary>
        [DllImport("kernel32.dll")]
        public static extern bool AllocConsole();

        /// <summary>
        /// 釋放控制檯
        /// </summary>
        [DllImport("kernel32.dll")]
        public static extern bool FreeConsole();
    }

}