1. 程式人生 > >把資料通過串列埠或USB以1秒間隔實時發給另外一臺計算機,在另外一臺計算機上以同樣方式顯示條形圖或趨勢曲線。

把資料通過串列埠或USB以1秒間隔實時發給另外一臺計算機,在另外一臺計算機上以同樣方式顯示條形圖或趨勢曲線。

前面兩篇文章已經講過了隨機資料產生,繪製直方圖,趨勢圖,資料儲存,串列埠傳送。接下來則是串列埠接收部分的程式。 注意:如果在一臺電腦上進行除錯,需要用虛擬串列埠軟體把串列埠1,2連結起來。


// 作業Dlg.cpp : 實現檔案
//

#include "stdafx.h"
#include "作業.h"
#include "作業Dlg.h"
#include "afxdialogex.h"
#include <iostream>
#include <fstream>
#include <stdlib.h>
#include "CMarks.h"
using
namespace std; #ifdef _DEBUG #define new DEBUG_NEW #endif int linei=0; const UINT nlinelength = 999; int lineData1[nlinelength] = { 0 }; int lineData2[nlinelength] = { 0 }; int lineData3[nlinelength] = { 0 }; int lineData4[nlinelength] = { 0 }; int lineData5[nlinelength] = { 0 }; int
lineData6[nlinelength] = { 0 }; int lineData7[nlinelength] = { 0 }; int lineData8[nlinelength] = { 0 }; int lineData9[nlinelength] = { 0 }; int lineData10[nlinelength] = { 0 }; int WaitData[10]; // 用於應用程式“關於”選單項的 CAboutDlg 對話方塊 class CAboutDlg : public CDialogEx { public: CAboutDlg(); // 對話方塊資料
enum { IDD = IDD_ABOUTBOX }; protected: virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支援 // 實現 protected: DECLARE_MESSAGE_MAP() public: // afx_msg void OnTimer(UINT_PTR nIDEvent); }; CAboutDlg::CAboutDlg() : CDialogEx(CAboutDlg::IDD) { } void CAboutDlg::DoDataExchange(CDataExchange* pDX) { CDialogEx::DoDataExchange(pDX); } BEGIN_MESSAGE_MAP(CAboutDlg, CDialogEx) // ON_WM_TIMER() END_MESSAGE_MAP() // C作業Dlg 對話方塊 C作業Dlg::C作業Dlg(CWnd* pParent /*=NULL*/) : CDialogEx(C作業Dlg::IDD, pParent) //, m_Chart(0) //, m_Chart2(0) , m_EditSend(_T("")) , m_EditReceive(_T("")) { m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME); } void C作業Dlg::DoDataExchange(CDataExchange* pDX) { CDialogEx::DoDataExchange(pDX); DDX_Control(pDX, IDC_TCHART1, m_Chart); DDX_Control(pDX, IDC_TCHART2, m_Chart2); DDX_Control(pDX, IDC_MSCOMM1, m_mscomm); DDX_Text(pDX, IDC_EDIT1, m_EditSend); DDX_Text(pDX, IDC_EDIT2, m_EditReceive); } BEGIN_MESSAGE_MAP(C作業Dlg, CDialogEx) ON_WM_SYSCOMMAND() ON_WM_PAINT() ON_WM_QUERYDRAGICON() ON_WM_TIMER() ON_BN_CLICKED(IDC_BUTTONOpen, &C作業Dlg::OnBnClickedButtonopen) ON_BN_CLICKED(IDC_BUTTONClose, &C作業Dlg::OnBnClickedButtonclose) //ON_BN_CLICKED(IDC_BUTTONSend, &C作業Dlg::OnBnClickedButtonsend) ON_BN_CLICKED(IDC_CHECK_Marks, &C作業Dlg::OnBnClickedCheckMarks) ON_BN_CLICKED(IDC_CHECK_Line1, &C作業Dlg::OnBnClickedCheckLine1) ON_BN_CLICKED(IDC_CHECK_Line2, &C作業Dlg::OnBnClickedCheckLine2) ON_BN_CLICKED(IDC_CHECK_Line3, &C作業Dlg::OnBnClickedCheckLine3) ON_BN_CLICKED(IDC_CHECK_Line4, &C作業Dlg::OnBnClickedCheckLine4) ON_BN_CLICKED(IDC_CHECK_Line5, &C作業Dlg::OnBnClickedCheckLine5) ON_BN_CLICKED(IDC_CHECK_Line6, &C作業Dlg::OnBnClickedCheckLine6) ON_BN_CLICKED(IDC_CHECK_Line7, &C作業Dlg::OnBnClickedCheckLine7) ON_BN_CLICKED(IDC_CHECK_Line8, &C作業Dlg::OnBnClickedCheckLine8) ON_BN_CLICKED(IDC_CHECK_Line9, &C作業Dlg::OnBnClickedCheckLine9) ON_BN_CLICKED(IDC_CHECK_Line10, &C作業Dlg::OnBnClickedCheckLine10) END_MESSAGE_MAP() // C作業Dlg 訊息處理程式 BOOL C作業Dlg::OnInitDialog() { CDialogEx::OnInitDialog(); // 將“關於...”選單項新增到系統選單中。 // IDM_ABOUTBOX 必須在系統命令範圍內。 ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX); ASSERT(IDM_ABOUTBOX < 0xF000); CMenu* pSysMenu = GetSystemMenu(FALSE); if (pSysMenu != NULL) { BOOL bNameValid; CString strAboutMenu; bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX); ASSERT(bNameValid); if (!strAboutMenu.IsEmpty()) { pSysMenu->AppendMenu(MF_SEPARATOR); pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu); } } // 設定此對話方塊的圖示。當應用程式主視窗不是對話方塊時,框架將自動 // 執行此操作 SetIcon(m_hIcon, TRUE); // 設定大圖示 SetIcon(m_hIcon, FALSE); // 設定小圖示 ShowWindow(SW_MAXIMIZE); // TODO: 在此新增額外的初始化程式碼 remove("data.txt"); ((CButton*)GetDlgItem(IDC_CHECK_Marks))->SetCheck(TRUE); return TRUE; // 除非將焦點設定到控制元件,否則返回 TRUE } void C作業Dlg::OnSysCommand(UINT nID, LPARAM lParam) { if ((nID & 0xFFF0) == IDM_ABOUTBOX) { CAboutDlg dlgAbout; dlgAbout.DoModal(); } else { CDialogEx::OnSysCommand(nID, lParam); } } // 如果向對話方塊新增最小化按鈕,則需要下面的程式碼 // 來繪製該圖示。對於使用文件/檢視模型的 MFC 應用程式, // 這將由框架自動完成。 void C作業Dlg::OnPaint() { if (IsIconic()) { CPaintDC dc(this); // 用於繪製的裝置上下文 SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0); // 使圖示在工作區矩形中居中 int cxIcon = GetSystemMetrics(SM_CXICON); int cyIcon = GetSystemMetrics(SM_CYICON); CRect rect; GetClientRect(&rect); int x = (rect.Width() - cxIcon + 1) / 2; int y = (rect.Height() - cyIcon + 1) / 2; // 繪製圖標 dc.DrawIcon(x, y, m_hIcon); } else { CDialogEx::OnPaint(); } } //當用戶拖動最小化視窗時系統呼叫此函式取得游標 //顯示。 HCURSOR C作業Dlg::OnQueryDragIcon() { return static_cast<HCURSOR>(m_hIcon); } void C作業Dlg::OnTimer(UINT_PTR nIDEvent) { // TODO: 在此新增訊息處理程式程式碼和/或呼叫預設值 CSeries lineSeries1 = (CSeries)m_Chart2.Series(1); CSeries lineSeries2 = (CSeries)m_Chart2.Series(2); CSeries lineSeries3 = (CSeries)m_Chart2.Series(3); CSeries lineSeries4 = (CSeries)m_Chart2.Series(4); CSeries lineSeries5 = (CSeries)m_Chart2.Series(5); CSeries lineSeries6 = (CSeries)m_Chart2.Series(6); CSeries lineSeries7 = (CSeries)m_Chart2.Series(7); CSeries lineSeries8 = (CSeries)m_Chart2.Series(8); CSeries lineSeries9 = (CSeries)m_Chart2.Series(9); CSeries lineSeries10 = (CSeries)m_Chart2.Series(0); if(1 == nIDEvent) { //存入資料檔案 fstream fso("data.txt", ios::app); for (int i = 0; i < 10; i++) { fso << WaitData[i] << ' '; }; fso << endl; fso.close(); //畫條形圖 CSeries barSeries = (CSeries)m_Chart.Series(0); barSeries.Clear(); CString str; for (int i = 0; i<10; i++) { str.Format("%d", WaitData[i]); barSeries.AddXY((double)i + 1, WaitData[i], str, RGB(20 * i, 40 * i, 80 * i)); }; lineData1[linei + 300] = WaitData[0]; lineData2[linei + 300] = WaitData[1]; lineData3[linei + 300] = WaitData[2]; lineData4[linei + 300] = WaitData[3]; lineData5[linei + 300] = WaitData[4]; lineData6[linei + 300] = WaitData[5]; lineData7[linei + 300] = WaitData[6]; lineData8[linei + 300] = WaitData[7]; lineData9[linei + 300] = WaitData[8]; lineData10[linei + 300] = WaitData[9]; //畫趨勢圖 if (BST_CHECKED == ((CButton*)GetDlgItem(IDC_CHECK_Line1))->GetCheck()) //判斷是否選中線1 { lineSeries1.Clear(); for (int i = linei - 300; i <= linei; i++) { lineSeries1.AddXY((double)i+ 1, lineData1[i + 300], NULL, RGB(0,0,0)); } } else { lineSeries1.Clear(); } if (BST_CHECKED == ((CButton*)GetDlgItem(IDC_CHECK_Line2))->GetCheck()) //判斷是否選中線2 { lineSeries2.Clear(); for (int i = linei - 300; i <= linei; i++) { lineSeries2.AddXY((double)i + 1, lineData2[i + 300], NULL, RGB(20, 40, 80)); } } else { lineSeries2.Clear(); } if (BST_CHECKED == ((CButton*)GetDlgItem(IDC_CHECK_Line3))->GetCheck()) //判斷是否選中線3 { lineSeries3.Clear(); for (int i = linei - 300; i <= linei; i++) { lineSeries3.AddXY((double)i + 1, lineData3[i + 300], NULL, RGB(40,80,160)); } } else { lineSeries3.Clear(); } if (BST_CHECKED == ((CButton*)GetDlgItem(IDC_CHECK_Line4))->GetCheck()) //判斷是否選中線4 { lineSeries4.Clear(); for (int i = linei - 300; i <= linei; i++) { lineSeries4.AddXY((double)i+ 1, lineData4[i + 300], NULL, RGB(60,120,240)); } } else { lineSeries4.Clear(); } if (BST_CHECKED == ((CButton*)GetDlgItem(IDC_CHECK_Line5))->GetCheck()) //判斷是否選中線5 { lineSeries5.Clear(); for (int i = linei - 300; i <= linei; i++) { lineSeries5.AddXY((double)i + 1, lineData5[i + 300], NULL, RGB(80,160,320)); } } else { lineSeries5.Clear(); } if (BST_CHECKED == ((CButton*)GetDlgItem(IDC_CHECK_Line6))->GetCheck()) //判斷是否選中線6 { lineSeries6.Clear(); for (int i = linei - 300; i <= linei; i++) { lineSeries6.AddXY((double)i+ 1, lineData6[i + 300], NULL, RGB(100,200,400)); } } else { lineSeries6.Clear(); } if (BST_CHECKED == ((CButton*)GetDlgItem(IDC_CHECK_Line7))->GetCheck()) //判斷是否選中線7 { lineSeries7.Clear(); for (int i = linei - 300; i <= linei; i++) { lineSeries7.AddXY((double)i+ 1, lineData7[i + 300], NULL, RGB(120,240,480)); } } else { lineSeries7.Clear(); } if (BST_CHECKED == ((CButton*)GetDlgItem(IDC_CHECK_Line8))->GetCheck()) //判斷是否選中線8 { lineSeries8.Clear(); for (int i = linei - 300; i <= linei; i++) { lineSeries8.AddXY((double)i+ 1, lineData8[i + 300], NULL, RGB(140,280,560)); } } else { lineSeries8.Clear(); } if (BST_CHECKED == ((CButton*)GetDlgItem(IDC_CHECK_Line9))->GetCheck()) //判斷是否選中線9 { lineSeries9.Clear(); for (int i = linei - 300; i <= linei; i++) { lineSeries9.AddXY((double)i+ 1, lineData9[i + 300], NULL, RGB(160,320,640)); } } else { lineSeries9.Clear(); } if (BST_CHECKED == ((CButton*)GetDlgItem(IDC_CHECK_Line10))->GetCheck()) //判斷是否選中線10 { lineSeries10.Clear(); for (int i = linei - 300; i <= linei; i++) { lineSeries10.AddXY((double)i+ 1, lineData10[i + 300], NULL, RGB(160,320,640)); } } else { lineSeries10.Clear(); } linei++; memset(WaitData, 0, sizeof(WaitData)); } CDialogEx::OnTimer(nIDEvent); } BEGIN_EVENTSINK_MAP(C作業Dlg, CDialogEx) ON_EVENT(C作業Dlg, IDC_MSCOMM1, 1, C作業Dlg::OnCommMscomm1, VTS_NONE) END_EVENTSINK_MAP() void C作業Dlg::OnCommMscomm1() { // TODO: 在此處新增訊息處理程式程式碼 static unsigned int cnt = 0; VARIANT variant_inp; COleSafeArray safearray_inp; long len, k; unsigned int data[1024] = { 0 }; byte rxdata[1024]; //設定 BYTE 陣列 CString strtemp; if (m_mscomm.get_CommEvent() == 2) //值為 2 表示接收緩衝區內有字元 { cnt++; variant_inp = m_mscomm.get_Input(); //讀緩衝區訊息 safearray_inp = variant_inp; ///變數轉換 len = safearray_inp.GetOneDimSize(); //得到有效的資料長度 for (k = 0; k<len; k++) { safearray_inp.GetElement(&k, rxdata + k); } for (k = 0; k<len; k++) //將陣列轉換為 CString 型變數 { strtemp.Format(_T("%c"), *(rxdata + k)); m_EditReceive += strtemp; //CString temp = _T("\r\n"); //換行 //m_EditReceive += temp; } CString receive1[10]; for (int i = 0; i < 10; i++) { AfxExtractSubString(receive1[i], m_EditReceive, i, ' '); WaitData[i] = atoi(receive1[i]); } m_EditReceive.Empty(); //接收後清空接收框 } UpdateData(FALSE); //更新編輯框內容 } void C作業Dlg::OnBnClickedButtonopen() { // TODO: 在此新增控制元件通知處理程式程式碼 if (m_mscomm.get_PortOpen()) //如果串列埠是開啟的,則行關閉串列埠 { m_mscomm.put_PortOpen(FALSE); } m_mscomm.put_CommPort(2); //選擇COM2 m_mscomm.put_InBufferSize(1024); //接收緩衝區 m_mscomm.put_OutBufferSize(1024);//傳送緩衝區 m_mscomm.put_InputLen(0);//設定當前接收區資料長度為0,表示全部讀取 m_mscomm.put_InputMode(1);//以二進位制方式讀寫資料 m_mscomm.put_RThreshold(1);//接收緩衝區有1個及1個以上字元時,將引發接收資料的OnComm事件 m_mscomm.put_Settings(_T("9600,n,8,1"));//波特率9600無檢驗位,8個數據位,1個停止位 if (!m_mscomm.get_PortOpen())//如果串列埠沒有開啟則開啟 { m_mscomm.put_PortOpen(TRUE);//開啟串列埠 AfxMessageBox(_T("串列埠1開啟成功")); } else { m_mscomm.put_OutBufferCount(0); AfxMessageBox(_T("串列埠1開啟失敗")); } SetTimer(1, 1000, NULL);//此處設定,對應於OnTimer() } void C作業Dlg::OnBnClickedButtonclose() { // TODO: 在此新增控制元件通知處理程式程式碼 //僅執行關閉串列埠 m_mscomm.put_PortOpen(FALSE);//關閉串列埠 AfxMessageBox(_T("串列埠1已關閉")); } void C作業Dlg::OnBnClickedCheckMarks() { // TODO: 在此新增控制元件通知處理程式程式碼 CSeries barSeries = (CSeries)m_Chart.Series(0); CMarks SeriesMarks = (CMarks)barSeries.get_Marks(); if (BST_CHECKED == ((CButton*)GetDlgItem(IDC_CHECK_Marks))->GetCheck()) { SeriesMarks.put_Visible(TRUE); } else { SeriesMarks.put_Visible(FALSE); } } void C作業Dlg::OnBnClickedCheckLine1() { // TODO: 在此新增控制元件通知處理程式程式碼 } void C作業Dlg::OnBnClickedCheckLine2() { // TODO: 在此新增控制元件通知處理程式程式碼 } void C作業Dlg::OnBnClickedCheckLine3() { // TODO: 在此新增控制元件通知處理程式程式碼 } void C作業Dlg::OnBnClickedCheckLine4() { // TODO: 在此新增控制元件通知處理程式程式碼 } void C作業Dlg::OnBnClickedCheckLine5() { // TODO: 在此新增控制元件通知處理程式程式碼 } void C作業Dlg::OnBnClickedCheckLine6() { // TODO: 在此新增控制元件通知處理程式程式碼 } void C作業Dlg::OnBnClickedCheckLine7() { // TODO: 在此新增控制元件通知處理程式程式碼 } void C作業Dlg::OnBnClickedCheckLine8() { // TODO: 在此新增控制元件通知處理程式程式碼 } void C作業Dlg::OnBnClickedCheckLine9() { // TODO: 在此新增控制元件通知處理程式程式碼 } void C作業Dlg::OnBnClickedCheckLine10() { // TODO: 在此新增控制元件通知處理程式程式碼 }

程式元件連結