【问题描述】
我们周围的环境对生活有很大的影响,设计一个Zigbee的智能农业大棚环境检测系统,自动检测农业生态信息,可以自动开启或关闭指定设备。并且设计一个显示界面,在PC机上实时显示相应的环境变量。
解决方案以各个传感器接收的数据为输入,最终PC机上的图形界面输出结果。程序编写包括传感器节点的C语言编程,在Visual Studio 2015平台构建已C++为基础的MFC控件编程。此外还涉及了MySQL数据库,重点功能如下。
设计的基本要求如下:
1实现对传感器数据的采集
2 拥有友善的可视化界面显示系统相关信息与数据
3 可连接数据库,向数据库中插入数据与数据库互动
4 模拟了组播传输的特点进行系统设计
设计的扩展要求如下:
模拟了农业大棚系统对环境进行调控的操作
#include "stdafx.h"
#include "SmartHome.h"
#include "AirControlDlg.h"
#include "equAdp.h"
#include "afxdialogex.h"
//因为数据库是通过网络连接的,必须包含网络相关头文件
#include "winsock.h"
//这个没什么好说的,mysql头文件自然要包含
#include "mysql.h"
#include
#include
// SH_AIR_CONTROL_DLG dialog
IMPLEMENT_DYNAMIC(SH_AIR_CONTROL_DLG, CDialogEx)
SH_AIR_CONTROL_DLG::SH_AIR_CONTROL_DLG(CWnd* pParent /*=NULL*/)
: CDialogEx(IDD_DIALOG_AIRCTL, pParent),
C_SERIAL_COM_ADP()
{
}
SH_AIR_CONTROL_DLG::~SH_AIR_CONTROL_DLG()
{
}
void SH_AIR_CONTROL_DLG::DoDataExchange(CDataExchange* pDX)
{
CDialogEx::DoDataExchange(pDX);
}
BEGIN_MESSAGE_MAP(SH_AIR_CONTROL_DLG, CDialogEx)
ON_BN_CLICKED(IDCANCEL, &SH_AIR_CONTROL_DLG::OnBnClickedCancel)
ON_WM_TIMER()
ON_BN_CLICKED(IDC_BUTTON_AC_OPEN, &SH_AIR_CONTROL_DLG::OnBnClickedButtonAcOpen)
ON_BN_CLICKED(IDC_BUTTON_AC_CLOSE, &SH_AIR_CONTROL_DLG::OnBnClickedButtonAcClose)
ON_WM_CTLCOLOR()
ON_BN_CLICKED(IDC_BUTTON11, &SH_AIR_CONTROL_DLG::OnBnClickedButton11)
END_MESSAGE_MAP()
// SH_AIR_CONTROL_DLG message handlers
void SH_AIR_CONTROL_DLG::OnBnClickedCancel()
{
// TODO: Add your control notification handler code here
closeComm();
CDialogEx::OnCancel();
}
BOOL SH_AIR_CONTROL_DLG::OnInitDialog()
{
CDialogEx::OnInitDialog();
// TODO: Add extra initialization here
bool bRet = openComm();
if (false == bRet)
{
MessageBox(_T("Open Serial port Failed"));
}
else
{
SetTimer(TIMER_AIR_CTL_REFRESH, 1000, NULL);
}
return TRUE; // return TRUE unless you set the focus to a control
// EXCEPTION: OCX Property Pages should return FALSE
}
void SH_AIR_CONTROL_DLG::OnTimer(UINT_PTR nIDEvent)
{
// TODO: Add your message handler code here and/or call default
__super::OnTimer(nIDEvent);
char buffer[128] = { 0 };
int iLoop = 10000;
while (0 < iLoop)
{
bool bRet = readFromComm(buffer, 127);
if ((true == bRet) && (0 < strlen(buffer)))
{
CString csBuffer(buffer);
int iTmpNmLen = 0, iHumNmLen = 0;
int iTempPos = csBuffer.Find(_T(MBR_TEMP), 0);
if (0 <= iTempPos)
{
iTmpNmLen = strlen(MBR_TEMP);
UpdateData(TRUE);
GetDlgItem(IDC_EDIT_MBR_TEM)->SetWindowText(csBuffer.Mid(iTempPos + iTmpNmLen, 2));
UpdateData(FALSE);
}
iTempPos = csBuffer.Find(_T(MBR_HUM), 0);
if (0 <= iTempPos)
{
iHumNmLen = strlen(MBR_HUM);
UpdateData(TRUE);
GetDlgItem(IDC_EDIT_MBR_HUM)->SetWindowText(csBuffer.Mid(iTempPos + iHumNmLen, 2));
UpdateData(FALSE);
}
iTempPos = csBuffer.Find(_T(SBR_TEMP), 0);
if (0 <= iTempPos)
{
iTmpNmLen = strlen(SBR_TEMP);
UpdateData(TRUE);
GetDlgItem(IDC_EDIT_MBR_TEM)->SetWindowText(csBuffer.Mid(iTempPos + iTmpNmLen, 2));
UpdateData(FALSE);
}
iTempPos = csBuffer.Find(_T(SBR_HUM), 0);
if (0 <= iTempPos)
{
iHumNmLen = strlen(SBR_HUM);
UpdateData(TRUE);
GetDlgItem(IDC_EDIT_MBR_HUM)->SetWindowText(csBuffer.Mid(iTempPos + iHumNmLen, 2));
UpdateData(FALSE);
}
iTempPos = csBuffer.Find(_T(LV_TEMP), 0);
if (0 <= iTempPos)
{
iTmpNmLen = strlen(LV_TEMP);
UpdateData(TRUE);
GetDlgItem(IDC_EDIT_SC_LR_TEM)->SetWindowText(csBuffer.Mid(iTempPos + iTmpNmLen, 2));
UpdateData(FALSE);
}
iTempPos = csBuffer.Find(_T(LV_HUM), 0);
if (0 <= iTempPos)
{
iHumNmLen = strlen(LV_HUM);
UpdateData(TRUE);
GetDlgItem(IDC_EDIT2_LR_HUM)->SetWindowText(csBuffer.Mid(iTempPos + iHumNmLen, 2));
UpdateData(FALSE);
}
memset(buffer, 0, 128);
}
iLoop--;
}
}
void SH_AIR_CONTROL_DLG::OnBnClickedButtonAcOpen()
{
// TODO: Add your control notification handler code here
unsigned char buffer[128] = { 0 };
if (((CButton*)GetDlgItem(IDC_CHECK_AC_BED_ROOM_MAIN))->GetCheck()
|| ((CButton*)GetDlgItem(IDC_CHECK_WND_BED_ROOM_M))->GetCheck())
{
memcpy(buffer, MBR_MOTOR_CTL, strlen(MBR_MOTOR_CTL));
memcpy(buffer + strlen(MBR_MOTOR_CTL), CURTAIN_OPEN, strlen(CURTAIN_OPEN));
bool bRet = writeToComm(buffer, 8);
if (false == bRet)
{
MessageBox(_T("Open failed."));
}
memset(buffer, 0, 128);
}
Sleep(1000);
if (((CButton*)GetDlgItem(IDC_CHECK_BED_AC_ROOM_S))->GetCheck()
|| ((CButton*)GetDlgItem(IDC_CHECK_WND_BED_ROOM_S))->GetCheck())
{
memcpy(buffer, SBR_MOTOR_CTL, strlen(SBR_MOTOR_CTL));
memcpy(buffer + strlen(SBR_MOTOR_CTL), CURTAIN_OPEN, strlen(CURTAIN_OPEN));
bool bRet = writeToComm(buffer, 8);
if (false == bRet)
{
MessageBox(_T("Open failed."));
}
memset(buffer, 0, 128);
}
Sleep(1000);
if (((CButton*)GetDlgItem(IDC_CHECK_AC_LIVING_ROOM))->GetCheck()
|| ((CButton*)GetDlgItem(IDC_CHECK_WND_LIVING_ROOM))->GetCheck())
{
memcpy(buffer, LV_MOTOR_CTL, strlen(LV_MOTOR_CTL));
memcpy(buffer + strlen(LV_MOTOR_CTL), CURTAIN_OPEN, strlen(CURTAIN_OPEN));
bool bRet = writeToComm(buffer, 8);
if (false == bRet)
{
MessageBox(_T("Open failed."));
}
memset(buffer, 0, 128);
}
}
void SH_AIR_CONTROL_DLG::OnBnClickedButtonAcClose()
{
// TODO: Add your control notification handler code here
unsigned char buffer[128] = { 0 };
if (((CButton*)GetDlgItem(IDC_CHECK_AC_BED_ROOM_MAIN))->GetCheck()
|| ((CButton*)GetDlgItem(IDC_CHECK_WND_BED_ROOM_M))->GetCheck())
{
memcpy(buffer, MBR_MOTOR_CTL, strlen(MBR_MOTOR_CTL));
memcpy(buffer + strlen(MBR_MOTOR_CTL), CURTAIN_OPEN, strlen(CURTAIN_CLOSE));
bool bRet = writeToComm(buffer, 8);
if (false == bRet)
{
MessageBox(_T("Open failed."));
}
memset(buffer, 0, 128);
}
Sleep(1000);
if (((CButton*)GetDlgItem(IDC_CHECK_BED_AC_ROOM_S))->GetCheck()
|| ((CButton*)GetDlgItem(IDC_CHECK_WND_BED_ROOM_S))->GetCheck())
{
memcpy(buffer, SBR_MOTOR_CTL, strlen(SBR_MOTOR_CTL));
memcpy(buffer + strlen(SBR_MOTOR_CTL), CURTAIN_OPEN, strlen(CURTAIN_CLOSE));
bool bRet = writeToComm(buffer, 8);
if (false == bRet)
{
MessageBox(_T("Open failed."));
}
memset(buffer, 0, 128);
}
Sleep(1000);
if (((CButton*)GetDlgItem(IDC_CHECK_AC_LIVING_ROOM))->GetCheck()
|| ((CButton*)GetDlgItem(IDC_CHECK_WND_LIVING_ROOM))->GetCheck())
{
memcpy(buffer, LV_MOTOR_CTL, strlen(LV_MOTOR_CTL));
memcpy(buffer + strlen(LV_MOTOR_CTL), CURTAIN_OPEN, strlen(CURTAIN_CLOSE));
bool bRet = writeToComm(buffer, 8);
if (false == bRet)
{
MessageBox(_T("Open failed."));
}
memset(buffer, 0, 128);
}
}
光敏传感器相关程序
void SH_LIGHTING_DLG::OnTimer(UINT_PTR nIDEvent)
{
CDialogEx::OnTimer(nIDEvent);
char buffer[128] = { 0 };
int iLoop = 1000;
while (0 < iLoop)
{
bool bRet = readFromComm(buffer, 127);
if ((true == bRet) && (0 < strlen(buffer)))
{
CString csBuffer(buffer);
int iLightPos = 0;
int iLightNmLen = 0;
if (((CButton*)GetDlgItem(IDC_RADIO_BED_ROOM))->GetCheck())
{
iLightPos = csBuffer.Find(CString(MBR_LIGHT_CTL));
if (0 > iLightPos)
{
iLoop--;
continue;
}
iLightNmLen = strlen(MBR_LIGHT_CTL);
}
else if (((CButton*)GetDlgItem(IDC_RADIO_LIVING_ROOM))->GetCheck())
{
iLightPos = csBuffer.Find(CString(LV_LIGHT_CTL));
if (0 > iLightPos)
{
iLoop--;
continue;
}
iLightNmLen = strlen(LV_LIGHT_CTL);
}
else
{
csBuffer = "";
}
UpdateData(TRUE);
GetDlgItem(IDC_EDIT_LC_VAL)->SetWindowText(csBuffer.Mid(iLightPos + iLightNmLen, 3));
UpdateData(FALSE);
memset(buffer, 0, 128);
}
iLoop--;
}
return;
}
电机控制
void SH_LIGHTING_DLG::OnBnClickedButtonLightingOpen()
{
// TODO: Add your control notification handler code here
unsigned char buffer[128] = { 0 };
if (((CButton*)GetDlgItem(IDC_RADIO_BED_ROOM))->GetCheck())
{
memcpy(buffer, MBR_MOTOR_CTL, strlen(MBR_MOTOR_CTL));
memcpy(buffer + strlen(MBR_MOTOR_CTL), CURTAIN_OPEN, strlen(CURTAIN_OPEN));
}
else if (((CButton*)GetDlgItem(IDC_RADIO_LIVING_ROOM))->GetCheck())
{
memcpy(buffer, LV_MOTOR_CTL, strlen(LV_MOTOR_CTL));
memcpy(buffer + strlen(LV_MOTOR_CTL), CURTAIN_OPEN, strlen(CURTAIN_OPEN));
}
else
{
}
bool bRet = writeToComm(buffer, 8);
if (false == bRet)
{
MessageBox(_T("Open failed."));
}
}
void SH_LIGHTING_DLG::OnBnClickedButtonLightingClose()
{
// TODO: Add your control notification handler code here
unsigned char buffer[128] = { 0 };
if (((CButton*)GetDlgItem(IDC_RADIO_BED_ROOM))->GetCheck())
{
memcpy(buffer, MBR_MOTOR_CTL, strlen(MBR_MOTOR_CTL));
memcpy(buffer + strlen(MBR_MOTOR_CTL), CURTAIN_CLOSE, strlen(CURTAIN_CLOSE));
}
else if (((CButton*)GetDlgItem(IDC_RADIO_LIVING_ROOM))->GetCheck())
{
memcpy(buffer, LV_MOTOR_CTL, strlen(LV_MOTOR_CTL));
memcpy(buffer + strlen(LV_MOTOR_CTL), CURTAIN_CLOSE, strlen(CURTAIN_CLOSE));
}
else
{
}
bool bRet = writeToComm(buffer, 8);
if (false == bRet)
{
MessageBox(_T("Close failed."));
}
}
连接数据库操作
使用VS2015连接MySQL数据库
在项目属性中修改包含关系和依赖
控制数据库核心代码
#include "winsock.h"
//这个没什么好说的,mysql头文件自然要包含
#include "mysql.h"
#include
#include
void SH_LIGHTING_DLG::OnBnClickedButton1()
{
int num1;
num1 =GetDlgItemInt(IDC_EDIT_LC_VAL);
// TODO: 在此添加控件通知处理程序代码
MYSQL m_sqlCon;
//初始化数据库对象
mysql_init(&m_sqlCon);
//localhost:服务器地址,可以直接填入IP;root:账号;
//123:密码;test:数据库名;3306:网络端口
if (!mysql_real_connect(&m_sqlCon, "localhost", "root",
"123456", "mydb", 3306, NULL, 0))
{
AfxMessageBox(_T("数据库连接失败!"));
return;
}
else//连接成功则继续访问数据库,之后的相关操作代码基本是放在这里面的
{
AfxMessageBox(_T("数据库连接成功!"));
UpdateData(true);
//设置数据库字符格式,解决中文乱码问题
mysql_query(&m_sqlCon, "set names 'gb2312'");
//char* num = (char*)m_num.GetBuffer();
char insert[1000];
sprintf_s(insert, "insert into light(light) values (\'%d\')",num1);
// 执行 sql 语句。
// mysql_query() 的返回值份很多情形, 进行判断使要注意。
if (mysql_query(&m_sqlCon, insert) == 0)
{
AfxMessageBox(_T("插入数据成功!"));
}
else {
AfxMessageBox(_T("插入数据失败!"));
}
}
UpdateData(false);
mysql_close(&m_sqlCon);//关闭Mysql连接
}
运行功能展示
改进和体会
在界面的设计部分,采取了默认的背景,仅仅修改了主界面的背景,时间充分的还可以做到更加完善。在数据发送与采集的过程中有一定的延迟,应该是程序接口设计的不完善,也可以继续完善。
如果使用邻接表存储网络信息,应该可以适应更复杂的网络,也能实现精确的布局描绘