项目背景:
在本次“新冠疫情”的冲击下,小区需要监控人员体温,现新进了一批可以采集人体体温的智能体温计,但是小区有三个门:正门,侧门,后门,每个门都会有人员流动,物业希望能够在监控室查看相关人员的体温,可以做匹配记录。
项目需求:
(1)每个智能体温计都能采集体温数据并自动上传该数据到监控平台。
(2)监控平台可以实时查看各门,各人员的体温。
(3)对于出现异常体温(超过37.3°C)监控平台会发出报警。
项目开发环境:
(1)QT 5.14.2。
(2)SSokit网络调试助手。
技术支持:
(1)C语言。
(2)C++。
(3)QT界面开发。
(4)TCP协议。
:具体的项目流程与实现,我用脑图的方式展示给大家。
TCP客户端核心代码:
/*******************************************************
*
* Function name :makeTemp
* Description :产生一个16位的数据:高8位整数+低8位小数
* Parameter :NULL
* Return :NULL
*
**********************************************************/
short makeTemp()
{
// 配置随机种子:根据系统的节拍取
srand(clock());
short temp = 0;
char high = 0;
char low = 0;
while(1)
{
// 以100ms的时间间隔
usleep(100 * 1000);
// 正常体温范围:34-43
// 体温整数部分随机数产生
high = 34 + rand() % 9;
// 体温小数部分随机数产生
low = rand() % 100;
// 将产生的数值传递给temp中:位运算处理
temp = high;
temp = temp << 8;
// 最终产生的模拟体温数值
temp += low;
gTemp = temp;
}
}
// 全局变量:存储产生的体温数据
short gTemp;
int main(int argc, char *argv[])
{
// 开启多线程:将数据的产生,放在线程中
QThread::create([](){
makeTemp();
})->start();
// 连接到TCP服务器端
QTcpSocket *client = new QTcpSocket;
QHostAddress address("127.0.0.1");
client->connectToHost(address,8888);
if(client->waitForConnected())
{
// 打印对方地址和端口
qDebug() << client->peerAddress();
qDebug() << client->peerPort();
// 打印自己的地址和端口
qDebug() << client->localAddress();
qDebug() << client->localPort();
// 数据循环发送TCP服务器端
while(1)
{
// 模拟人的流动 随机延时
sleep(1 + rand()% 9);
// write的用法 char *的地址 数据长度(字节)
client->write((char *)&gTemp,2);
client->flush();
}
}
return 0;
}
TCP客户端数据发送验证:
TCP服务器核心代码:
/*******************************************************
*
* Function name :createChart
* Description :配置主显示界面
* Parameter :NULL
* Return :NULL
*
**********************************************************/
void MainWidget::createChart()
{
// 配置基础的图表数据
mainChart = new QChart();
dotSeries = new QScatterSeries;
alertLineSeries = new QLineSeries;
connectLineSeries = new QLineSeries;
// X Y 座标系
QValueAxis *axisX = new QValueAxis;
QValueAxis *axisY = new QValueAxis;
// 数值范围
axisX->setRange(0,60);
axisX->setLabelFormat("%.2f");
// 是否显示表格分割虚线
axisX->setGridLineVisible(true);
// 分割的格子数
axisX->setTickCount(7);
// 最小分割
axisX->setMinorTickCount(1);
// 座标代表的含义标题
axisX->setTitleText("时间");
axisY->setRange(34,43);
axisY->setLabelFormat("%.2f");
axisY->setGridLineVisible(true);
axisY->setGridLineColor(Qt::gray);
axisY->setTickCount(10);
axisY->setTitleText("体温");
// 座标轴的位置
mainChart->addAxis(axisX,Qt::AlignBottom);
mainChart->addAxis(axisY,Qt::AlignLeft);
// 数据点,警戒线,连接线的层级关系
mainChart->addSeries(alertLineSeries);
mainChart->addSeries(connectLineSeries);
mainChart->addSeries(dotSeries);
// 隐藏图例
mainChart->legend()->hide();
// 需要将座标系和数值范围绑定在一起,否则显示的数据不正确
// 必须是在将图类型添加到图表上之后
dotSeries->attachAxis(axisX);
dotSeries->attachAxis(axisY);
alertLineSeries->attachAxis(axisX);
alertLineSeries->attachAxis(axisY);
connectLineSeries->attachAxis(axisX);
connectLineSeries->attachAxis(axisY);
// 设置警戒线:颜色,粗细,位置
//alertLineSeries->setColor(QColor("red"));
alertLineSeries->setPen(QPen(Qt::red,3,Qt::DashLine,Qt::RoundCap,Qt::RoundJoin));
alertLineSeries->append(0,37.3);
alertLineSeries->append(60,37.3);
// 设置连接线:颜色,粗细,位置
connectLineSeries->setPen(QPen(Qt::blue,1.5,Qt::SolidLine,Qt::RoundCap,Qt::RoundJoin));
}
// 创建server,监听端口和地址
bool MainWidget::startServer()
{
server = new QTcpServer();
return server->listen(QHostAddress("127.0.0.1"),8888);
}
void MainWidget::newConnectionAccept()
{
// 定义一个刷新图表的时间
qreal passMinute = QTime::currentTime().minute();
qDebug() << "新连接已接入";
// 获取当前的传输套接字 可以进行数据的发送和接收
dataSocket = server->nextPendingConnection();
dataSocket->write("HELLO");
// 客服端是否有新的数据发送?
// 有-> 触发readyRead信号
// 可以对发送的数据进行处理
connect(dataSocket,&QTcpSocket::readyRead,[=]()mutable{
// 按照高8位和低8位数据转换成真正的温度数据
short temp = 0;
dataSocket->read((char *)&temp,2);
short t = temp >> 8;
float realTemp = t + (temp & 0x00ff) / 100.00;
qDebug() << realTemp;
// 每隔一分钟刷新一次图表
if( passMinute != QTime::currentTime().minute() )
{
dotSeries->clear();
connectLineSeries->clear();
passMinute = QTime::currentTime().minute();
}
dotSeries->append(QTime::currentTime().second(),realTemp);
connectLineSeries->append(QTime::currentTime().second(),realTemp);
QString tt("当前温度为:");
tt += QString("%1").arg(realTemp);
currentTempLabel->setText(tt);
numberDisplay->display(realTemp);
// 当体温数值超过 37.3 就报警
if(realTemp > 37.3)
{
alertPlayer->play();
}
});
}