0%

硬件开发项目实践

test1

嵌入式面试宝典

单片机总结

单片机结构与系统

1.单片机分类

单片机家族

2.单片机系统

单片机基础知识

C51单片机中断系统

C51定时器计数器

C51单片机时钟系统

STM32库函数开发

STM32库开发实战指南

3.单片机体系与结构

ARM体系与结构

FreeRTOS 内核实现与应用开发实战

常用通信协议介绍

硬件通信协议简介

硬件常用通信协议详解

C/C++基础

单片机C/C++常见面试题

C/C++面试题宝典

C++ STL进阶版

C++ Boost库

数据结构与算法

数据结构与算法

常用外设模块与原理

STM32模块例程介绍

1.项目涉及模块

RC55读写卡(非接触考勤)

ESP8266模块(WIFI通信)

SX1280收发模块 (TOF测距)

DOF Sensor传感器(惯性导航)

L298N(电机驱动)

2.其他常用模块

光敏模块

DHT11温湿度传感器

HC05蓝牙模块

OLED模块

数码管模块

施工工地智能安全帽设计

整体设计思路

智能安全帽将安全性提升到了更高层次,借助人工智能和物联网技术,智能安全帽考虑到了工地上的各种情况,实现检测了相应的检测,获取的数据也可分析数据工人的各种情况,所得结果使对工地的各种设施的改善具有针对性。

安全帽最主要的一个创新点就是它将能将所收集到的信息全都传输到客户端,使所有数据能够直观地呈现出来,对于制定更好的工地制度和管理工人有更加科学的参考作用。相比起传统安全帽,我们能提取到更多的信息,从而获得更大的工作效益。

test1

image-20221017114248506


image-20221017114329781

image-20221017114347288

登记考勤

1.功能概述

当工人穿戴进入到与工地宝特定距离,工地宝与安全帽进行信息交流,利用非接触式IC卡技术,例如“Mifare”,基于ISO14443A&B通信协议,由电磁波进行数据交换,安全帽向工地宝提交请求,工地宝将收集到的信息通过WiFi模块,“UART-WiFi透传模块”发送到数据中心,完成对工人的考勤。然后数据中心返回请求,通过安全帽的语音播报功能提示工人已经考勤完成。

2.相关元器件

RC55读写卡(非接触考勤)

ESP8266模块(WIFI通信)

3.非接触式考勤实现

STM32 Mifare考勤

4.WIFI通信实现

单片机间 WIFI通信

区域定位

1.功能概述

其次,利用UWB技术实现人员位置定位功能,当工人穿戴安全帽在工作区域时,安全帽将坐标信息提交给数据中心,数据中心通过相关形成工人的时间/工作轨迹。在工人进入数据中心定义的危险坐标时,数据中心使安全帽通过语音播报模块发出警报。由此可以保证在事故时能准确地知道员工的位置方便救援,也有助于工人的管理。通过有效分析工人经常停留的区域,关联施工工序做出更加准确的工效分析

2.相关元器件

SX1280收发模块 (TOF测距)

DOF Sensor传感器(惯性导航

3.TOF测距实现

ToF技术全解读

STM32 TOF实现

4.UWP定位实现

UWB定位技术原理

image-20221017093753576

5.惯性导航实现

UWB_INS联合室内定位方法研究

image-20221023202347586

环境检测

1.功能概述

利用MQ-7传感器对空气中的一氧化碳含量进行检查,利用ME4-NH3传感器对空气中的氨气含量进行检测等等。可有效分析工人的工作环境。当检测到危险气体超标时,安全帽利用内置的“UART-WiFi透传模块”向“工地宝”提交信息,最终将数据呈现给数据中心,数据中心再通过安全帽的语音播模块警示工人

后台中心

1.功能概述

后台控制中心对各个过程提交的数据进行汇总,并利用后台软件进行数据分析,例如对考勤信息进行处理,可以活动安全帽对应工人的综合素质信息、对作业人员的轨迹分析,可以得知工人是否严格按照计划作业,可在施工过程中提高作业效率等等。安全帽还有对工人身体状况的检查功能。实现智能语音播报功能。当施工人员进入施工现场,通过考勤点设置的“工地宝”,主动感应安全帽芯片发出的信号,区分队伍和个人,进行预警信息播报;若是安全帽通过以上数据检测到工人周遭环境较为危险时也会发出预警信号来警示工人,预警信息预置可通过使用手机端自助录入。并且设置应急按钮,预防安全帽检测不到的危险情况,影响到工人的人身安全,安全帽检测到的相关信息也会在PC端看到,在PC端我们还能实时观察到每个工人的位置,身体情况和周遭环境,在方便管理的同时也降低了发生事故的可能性

数字PID闭环电机调速系统

整体设计思路

设计制作数字PID闭环电机调速系统,要求达到以下技术指标:

1)编写程序实现数字PID控制;

2)能够跟踪显示电机实际运行速度,实现PID参数显示和修改;

3)PID控制超调量小于40%,调节时间尽量短,具备一定的抗干扰性。

PID算法与PWM调速

1.相关元器件

L298N(电机驱动)

直流电机

image-20221017153930568

2.PID解析

当电机转速的设定值突然改变,或电机的转速发生突变时,会引起偏差的阶跃,使error增大,PID的输出out将急剧增加或减小,以至于超过控制量的上下限,电机的转速SPEEDR虽然不断上升,但由于控制量受到限制,其增长的速度减慢,偏差error将比正常情况下持续更长的时间保持在较大的偏差值,该程序主要是把设定的转速现当前测量得到的转速来计算偏差,从而用PWM输出方式来确定输出脉冲的宽度,流程图如下:

微信图片_20220621223507

3.PID实现

51单片机PID算法程序:算法详解及控制算法实例

51单片机PID算法程序:算法详解及控制算法实例(有图)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
int PID_Controller(int Target, int Feedback)
{
float out;
// 计算误差值
Error = Target - Feedback;
// 覆盖误差积分
Integral_Error = Integral_Error + Error;
// 计算微分误差
Differential_Error = Error - Error_last;
// 记录误差值
Error_last = Error;

// 计算PID控制数值
Proportion_OUT = KP * Error;
Integral_OUT = KI * Integral_Error;
Differential_OUT = KD * Differential_Error;

out = Proportion_OUT + Integral_OUT + Differential_OUT;

if(out<=1) out = 1;
else if (out>=CYCLE) PID_OUT = CYCLE;

PID_OUT = (int)out;

return PID_OUT;
}

4.PWM调速
  • PWM意为脉冲宽度调制,可用于调整输出直流平均电压,对于矩形波而言,输出平均压等于峰值电压×占空比,占空比是一个脉冲周期内高电平时间与周期的比值,例如,峰值电压等于5V,占空比等于50%的方波信号平均电压等于2.5V

  • 电机循环转动

    这里要注意循环一定是要放在main函数中的(否则如果是放在中断中,会卡死主流程),这里使用的方法是,中断触发电机开关,而main函数不断检测这个开关从而达到电机的循环转动

  • 代码

    这里使用定时器 + 计数的方法来实现占空比(如果用延时方法,会造成阻塞)

光电测速

1.相关元器件

MOC70T4 光电开关

image-20221017154412399

2.测速实现

飞轮上有两个缺口凹槽,所以两次脉冲触发的时间里飞轮刚好转过半圈,这时可以通过周期来计算转速

基于C51单片机直流电机测速仪设计

image-20221017154717264

上下位机串口通讯

1.下位机串口操作

C51/C52单片机的串口原理及参考代码_

串口初始化

1
2
3
4
5
6
7
8
9
10
11
12
13
void UART_Init()
{
PCON &= 0x7F; //波特率不倍速
SCON = 0x50; //8位数据,可变波特率
TMOD &= 0x0F; //清除定时器1模式位
TMOD |= 0x20; //设定定时器1为8位自动重装方式
TL1 = 0xFA; //设定定时初值
TH1 = 0xFA; //设定定时器重装值
ET1 = 0; //允许定时器1中断
TR1 = 1; //启动定时器1
EA=1;
ES=1;
}

串口通讯接收

1
2
3
4
5
6
7
8
9
10
11
12
13
/*------------------------------------------------
串口通讯子程序
------------------------------------------------*/

void UART_Routine() interrupt 4
{

if(RI==1) //如果接收标志位为1,接收到了数据
{
switch(SBUF)
{
// 此处添加接收到的16进制数跳转程序
}
2.上位机串口操作

Qt的QString字符串操作

Qt 串口助手开发笔记

C++正则表达式的使用

串口搜索

1
2
3
4
5
6
7
8
9
10
11
12
void Widget::on_serialSearchButton_clicked()
{
// 创建一个串口对象
serialPort = new QSerialPort(this);

// 搜索所有可用串口
ui->serialBox->clear();
foreach(const QSerialPortInfo &info, QSerialPortInfo::availablePorts()){
ui->serialBox->addItem(info.portName());

}
}

串口连接

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
/* 串口设置 */
// 端口设置
serialPort->setPortName(ui->serialBox->currentText());
// 波特率设置
serialPort->setBaudRate(ui->baudrateBox->currentText().toInt());
// 默认数据位为8
serialPort->setDataBits(QSerialPort::Data8);
// 默认停止位为one
serialPort->setStopBits(QSerialPort::OneStop);
// 默认无校验位
serialPort->setParity(QSerialPort::NoParity);

// 串口开启
if(true == serialPort->open(QIODevice::ReadWrite)){
serialSwitch = 1;
// 连接串口并让serialPort_Read()异步读取串口数据
connect(serialPort, SIGNAL(readyRead()), this, SLOT(serialPort_Read()));
}
else{
QMessageBox::critical(this, "提示", "串口打开失败");
return;
}

读取串口数据

1
2
3
4
5
6
7
void Widget::serialPort_Read(){
QString data = serialPort->readAll();

if(data.isEmpty()){
return;
}
}

串口发送16进制指令

1
2
3
serialPort->write(QByteArray::fromHex("0"));
serialPort->write(QByteArray::fromHex("1"));
serialPort->write(QByteArray::fromHex("2"));
3.上位机曲线绘制

Qt Charts使用指南

动态曲线案例

Charts画布设置

Qt Creator的UI设计中并没有Charts相关的组件,这里主要通过提升graphicsView组件来添加Charts画布

image-20220618110940947

添加点到曲线

为了实现动态曲线,下面提供了scroll扩展X轴和重设X轴范围两种方案

1
2
3
4
5
series->append(QPointF(numX, speed));
// X轴范围增加式
if(numX > 500){
axisX->setRange(0, numX + 5);
}
1
2
3
4
5
 // X轴拓展滚动式
qreal x = chart->plotArea().width() / 100;
if(numX > 500){
chart->scroll(x,0);
}

图表初始化

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
    // 坐标轴实例化
axisX = new QValueAxis();
axisY = new QValueAxis();
// 划分个数
axisX->setTickCount(11);
axisY->setTickCount(31);

// 设定坐标轴范围
axisX->setRange(0,500);
axisY->setRange(0,3000);

// 坐标轴描述
axisX->setTitleText("采集次数");
axisY->setTitleText("转速");

// 创建曲线绘制对象
series = new QSplineSeries();
// 设置数据点可见
// series->setPointsVisible(true);
// 图例名称
series->setName("speed");


// 实例化图表
chart = new QChart();
chart->setTitle("转速波形图");
// 坐标轴添加到图表指定位置
chart->addAxis(axisX, Qt::AlignBottom);
chart->addAxis(axisY, Qt::AlignLeft);
// 曲线对象添加到图表上
chart->addSeries(series);
// 动画使曲线绘制显示更加平滑
chart->setAnimationOptions(QChart::SeriesAnimations);

// 曲线关联XY轴
series->attachAxis(axisX);
series->attachAxis(axisY);

ui->dataChart->setChart(chart);
// 设置抗锯齿,让曲线更顺滑
ui->dataChart->setRenderHint(QPainter::Antialiasing);

);