把資料通過串列埠或USB以1秒間隔實時發給另外一臺計算機,在另外一臺計算機上以同樣方式顯示條形圖或趨勢曲線。
阿新 • • 發佈:2018-12-10
前面兩篇文章已經講過了隨機資料產生,繪製直方圖,趨勢圖,資料儲存,串列埠傳送。接下來則是串列埠接收部分的程式。 注意:如果在一臺電腦上進行除錯,需要用虛擬串列埠軟體把串列埠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: 在此新增控制元件通知處理程式程式碼
}
程式元件連結