2025贸泽电子M-Design创意设计竞赛
- 基于CH32的远程输出控制平台
一、项目介绍
本项目依托于2025贸泽电子M-Design创意设计竞赛,基于CH32和其他器件,使用受控端-上位机的运行模式,设计了一套基于TCP/IP协议的远程输出控制平台。用户可以通过全平台上位机远程遥控继电器通断、DA输出、IO电平等等。
项目内容:
1、设计了一套主控核心板。
2、设计了一套全平台上位机。
3、设计了一套受控端装置。
4、驱动受控端联网并完成与上位机通信。
5、添加光纤通信。
应用场景:
本项目为一基于TCP/IP的远程控制平台。项目基于网络通信,对于受控端,联网方式为以太网,作为有线通信,其抗干扰能力强,设计适当外壳后,可以适应各种恶劣环境。同时,基于有线的以太网,可以通过添加光纤来低成本大幅增加其通信距离。由于其具有的抗干扰能力强、通信距离成本低且可无限拓展等优点,其适宜用于帮助科研、操作人员远程控制位于深井、深海内的各类设备。如控制煤矿井下电阻率层析成像监测系统的激发电源控制系统。
二、项目整体设计
2.1 项目整体架构
本系统采用局域网作为该项目的通信介质。局域网可以通过光纤、电缆、无线电波等多种形式扩大通信距离,同时任一设备间都能精确的建立通信,可以轻易的满足本系统的通信需求。本项目整体架构如下图2.1.1。
图2.1.1 系统总体架构图
2.2 控制端总体方案
常见控制端形态主要为智能手机、笔记本电脑、台式电脑以及平板电脑,操作系统主要为Android、Windows、Linux、IOS(iPadOS),如下图2.2.1。
图2.2.1 2019-2022全球设备使用量
但是,考虑到目标场景,将使用Windows 7及以上版本的台式电脑和笔记本电脑作为第一预想控制设备。同时,将使用Android系统和Linux系统的三防笔记本电脑和平板电脑作为第二预想控制设备。综合第一预想控制设备和第二预想控制设备,假定控制设备硬件配置如下表2.2.1:
CPU核心 | CPU频率 | 内存 | 硬盘 |
双核及以上 | 2GHz及以上 | 4G | 64G |
表2.2.1 预想控制设备硬件配置
在Windows系统上,常用的几种桌面软件架构有LabVIEW、MATLAB AppDeigner、QT、Electron,它们各自的优劣如下表2.2.2。
其中,使用LabVIEW和MATLAB编写的桌面应用需要各自的运行引擎-LabVIEW Runtime和MATLAB Runtime。该引擎往往需要占用数百兆内存,如此巨大的内存占用,对于假想的控制设备来说,是不可忍受的。并且该引擎只支持Windows。这意味着,基于LabVIEW和MATLAB的应用完全没有任何原生跨平台的能力,只能在第一假想设备上运行。
Electron是一种基于Chromium浏览器内核的GUI语言。虽然,其内部完整的浏览器内核给了其非常良好的兼容性,使其可以同时在第一和第二假想设备上运行。但是,也使其需要占用大量内存和硬盘空间,对于假想设备来说也是不可忍受的。
QT是一门历史悠久的、基于C++的GUI编程语言,具有原生的跨平台能力,且运行速度快,占用空间小,可以高效的同时在第一和第二假想设备上运行,因此选用QT作为控制端架构。
名称 | 体积 | 运行速度 | 内存占用 | 全平台 | 函数功能 |
LabVIEW | 空项目体积约400m | 慢 | 中 | 否 | 弱 |
MATLAB | 空项目体积约800m | 慢 | 高 | 否 | 中 |
QT | 空项目体积(Windows)约20m | 快 | 低 | 是 | 强 |
electron | 空项目体积约800m | 慢 | 高 | 是 | 强 |
表2.2.2 常见桌面软件架构对比
2.3 通信方案
常见局域网通信介质有WIFI、以太网和光纤,其中WIFI主要用于30米内移动设备通信;以太网主要应用于100米内固定设备的通信;光纤主要应用于KM级超远距离通信。本项目中,多数情况下控制端和受控端之间的距离远超1KM,需要采用光纤传输,但是第一和第二假想设备均不具备光纤通信能力;此外,考虑到少数极端情况下,控制端和受控端无法连通到同一局域网,需要通过公网转发。因此本项目采用多种介质混合组网,物理结构如下图2.3.1。
图2.3.1 通信方案示意图
其中,多级路由器间使用任意介质连接,用于建立局域网,为各设备分配ip地址以及转发和接收公网的信息,部分路由器还具有WIFI功能,可以用于连接具有WIFI通信功能的控制端。光纤交换机为成对使用,中间可以连接长度不大于20KM的光纤,用于连接控制端和受控端局域网,通过以太网与其他设备连接。本网络的网络拓扑图如下图2.3.2。需要注意的是,多个控制端表示,可以在任意一级局域网中或者在公网中,控制受控端。
图2.3.2 网络结构拓扑图
2.4 受控端总体方案
受控端主要功能为接收来自局域网的控制信号,输出相应的数字和模拟电压,并控制多路继电器的开合。主控采用南京沁恒微电子的CH32V307VCT6芯片,相较于其他通用型MCU(如STM32F411CEU6),其主要有以下几点优点:
1、内部集成两路12位DAC,可建立4095个电平,远大于最终输出0-300V,0.1V步进所需要的3000个电平,不需要外接SPI通信的16位高精度DAC。
2、内部集成1G MAC和10M PHY,原生支持以太网,提供成熟的以太网编程库函数,大大降低编程难度和设计PCB时的布线难度。
3、内部集成USB PHY,原生支持USB虚拟串口,方便调试,无需外挂串口芯片。
三、受控端的设计方案
3.1 主控PCB设计
主控部分的PCB设计主要包含网络通信部分、USB通信部分、IO部分、调试部分和系统部分。根据系统需求,要求该PCB在尽量减小系统复杂度的情况下,实现以下需求:
1、可以进行双向高速以太网通信。
2、可以在不需要烧录夹等工具的情况下,对系统进行烧录。
3、可以通过多路继电器控制多路负载的通断
4、板载LED等,方便调试。
对于需求1,CH32原生支持以太网通信,仅需将IEC 60603-7连接器母座相应的引脚连接至主控即可。对于需求二,常见解决方案有:DAP-link、WCH-link、串口、USB-DFU。各个方案互有优劣,参见下表3.1.1。
| 下载速率 | 需要芯片 | 串口 |
串口 | 115200 | 是 | 是 |
DAP-LINK | 921600 | 是 | 是 |
WCH-LIHNK | 230400 | 是 | 是 |
USB-DFU | 460800 | 否 | 否 |
表3.1.1 各下载方式对比
其中串口下载速度慢,且容易受干扰导致下载失败;DAP-link和WCH-Link都是通用型高速下载器,集成高速串口,但是都需要板载相应的芯片以完成下载;USB-DFU不集成串口解决方案,但是该模式下载速度快,且无需外挂芯片。最终选定USB-DFU作为解决方案。
对于需求三,选择引出多组共72个GPIO控制继电器通断,远大于所需的八个IO,互为冗余,即使损失数个管脚也可以快速恢复运行。对于需求四,板载1个用户KEY和两个LED。同时,引出IEC 60603-7连接器母座的两个指示用LED的引脚,这两个指示用LED也可以用于调试。
PCB成品如下图3.1.1所示
图3.1.1a 主控板成品图
图3.1.1b 主控板PCB图
3.1.1 网络通信部分
网络通信部分电路如下图3.1.2所示。HR9011105A为一集成网络变压器的IEC 60603-7连接器母座,该插座的6脚、3脚、2脚、1脚分别为ERXP、ERXN和ETXP、ETXN,这是两组差分信号线,分别连接主控的PC6、PC7、PC8、PC9管脚。由于主控通过电压而非电流驱动网口,因此插座的4脚和5脚接入高电平,同时交流接地,滤除交流信号。
图3.1.2 网络通信原理图
3.1.2 USB通信部分
USB通信部分电路如下图3.1.3所示。此处采用两个支持USB3.2 GEN1通信协议的16P USB Type-C母座。但是,由于该主控硬件仅支持双线通信的USB 2.0协议,因此将DP1和DN1、DP2和DN2两组中心对称的差分线短接成一组USB差分线,其中DP连接主控的PA11管脚,DN连接主控的PA12管脚。SBU在USB3.2 GEN1协议中作为高速通信的多协议复用引脚,此处作悬空处理。CC1和CC2在USB 3.2 GEN1通信协议中用于识别连接方向,即,用于识别主从设备,此处接地表示作为从设备连接。
图3.1.3 USB通信原理图
3.1.3 供电部分
供电设计分为两部分,第一部分是外部输入转换至各供电电压,如下图3.1.4。
图3.1.4 电压转换原理图
本设计中,所有5V供电均先经由开关和自恢复保险丝。开关断开或者保险丝熔断,电源就会与PCB上的供电部分完全断开。这种设计可以有效提高安全性。5V供电随后经由线性稳压器,输出3.3V,同时在线性稳压器的输入和输出位置添加电容,交流接地以减小纹波。此处,线性稳压器选择SOP-223封装的AMS1117-3.3,其主要特性如下表3.1.2所示。
输入电压/V | 输出电压/V | 负载调整率 | |||
最小 | 额定 | 最大 | 额定 | 最大 | |
4.8-10.3 | 3.234 | 3.3 | 3.366 | 0.20% | 0.70% |
表3.1.2 AMS1117-3.3主要特性
第二部分是数字供电和模拟供电的隔离问题。本文将所有模拟正极和模拟负极连接到一点,然后采用0欧电阻的形式将两部分隔离开,如下图3.1.5。
图3.1.5 供电隔离原理图
3.1.4 调试与其他部分
本文中,BOOT0、BOOT1和NRST三个引脚通过下拉电阻的按键形式给出,如下图3.1.6。常态下BOOT0和BOOT1为低电平,NRST为高电平;按下后BOOT0和BOOT1为高电平,NRST为低电平。相较使用跳帽连接VCC或者GND,本设计可以显著降低改变这三个引脚电平的操作复杂度,大大方便USB-DFU下载。此外还板载两个共阳极3.3V LED,一个上拉电阻的按键用于调试。
图3.1.6 按键原理图
3.2 主控的软件设计
3.2.1 程序架构
主控的程序调度主要分为两部分,第一部分是main函数和主循环部分,其流程图如下图3.4.1所示:
图3.2.1 主函数流程图
系统开始后首先进行时钟、中断等较为底层的初始化,随后初始化网络,使主控在网络上作为服务器运行,该部分程序包括预分配内存空间和创建各类网络中断的响应机制等,优先保证网络通信的流畅性。之后初始化DAC,将对应引脚输出置为零,保证安全性,不会在初始化中误伤人员。最后初始化GPIO,控制继电器全部断开。初始化结束后,进入主循环,循环接收缓冲区的信息,串口发送调试用的信息,控制网口指示灯的闪烁,如果发生故障,方便检修。
另一部分是各类网络中断的响应机制,包括客户端连接中断、信息接收中断和连接失活中断。首先是客户端连接中断,其流程如下图3.4.2所示。当主控收到控制端根据TCP协发送的请求连接的报文时,首先检查控制端连接数量是否超出规定数量。如果超出规定数量,则不会响应该请求连接的报文。如果未超过,继续执行TCP协议的三次握手流程。三次握手流程成功后,主控会为该控制端分配Socket ID。
图3.2.2
然后是信息接收中断,当主控的任一TCP连接接收到信息时,且该信息符合TCP连接的信息规范时,会触发该中断,该中断流程如下图3.4.3。主控首先判断缓冲区内接收到的数据的长度是否溢出,溢出则修改接收到的数据的长度。之后,根据数据长度,提取数据至内存,根据通信协议确定数据是否有效,并同时通过串口1和接收到该信息的TCP连接返回结果。如果有效,根据通信协议转译该数据,并根据接收数据转译出的控制数据控制DAC或者GPIO状态,并同时通过串口1和接受到该信息的TCP连接返回执行的操作。
图3.2.3 信息接收中断
3.2.2 通信协议设置
本设计中,单次通信协议一共4位十进制数,划定0-4095作为DAC输出的数值范围,将该数值直接作为DAC的输出值。5000-9999作为GPIO操作数,首位5-9代表GPIO端口号GPIOA -~ GPIOE,第二位和第三位组成的两位十进制数代表管脚号0-15,单个操作数仅能操作一个管脚,第四位代表管脚电平,0代表低电平,1代表高电平。
switch(control[0])
{
case 5:
port=control[1]*10+control[2];
port_bit=1<<(port);
GPIO_WriteBit(GPIOA,port_bit,control[3]);
printf("GPIOA.PORT%d\n",port);
break;
case 6:
port=control[1]*10+control[2];
port_bit=1<<(port);
GPIO_WriteBit(GPIOB,port_bit,control[3]);
printf("GPIOB.PORT%d\n",port);
break;
case 7:
port=control[1]*10+control[2];
port_bit=1<<(port);
GPIO_WriteBit(GPIOC,port_bit,control[3]);
printf("GPIOC.PORT%d\n",port);
break;
case 8:
port=control[1]*10+control[2];
port_bit=1<<(port);
GPIO_WriteBit(GPIOD,port_bit,control[3]);
printf("GPIOD.PORT%d\n",port);
break;
case 9:
port=control[1]*10+control[2];
port_bit=1<<(port);
GPIO_WriteBit(GPIOE,port_bit,control[3]);
printf("GPIOE.PORT%d\n",port);
break;
default:
dac_value=control[0]*1000+control[1]*100+control[2]*10+control[3];
printf("dac:%d\n",dac_value);
DAC_SetChannel1Data(DAC_Align_12b_R, dac_value);
break;
}
四、控制端的设计方案
上位机采用了QT架构方案,该方案天然具有跨平台优势,除IOS系统需要开发者账户无法编译外,本文设计并实现了横跨Windows、Ubuntu、Mac、Android和Deepin等系统的全平台控制端应用,控制端形态可以为任意运行上述系统的电子设备。下图4.1为控制软件主页面。
图4.1 控制软件主界面示意图
4.1 界面设计
4.1.1 网络连接部分
网络部分包含三个控件,地址、端口号和连接按钮。地址控件采用的是一个标签和一个文本输入框的组合,端口号控件采用的是一个文本框和一个整型数字调整框的组合。限定该调整框内数值的范围为1-65535,步长为1。在未连接受控端时,使能该部分,如图4.1,连接后,切换为控制界面,如图4.1.2。
4.1.2 输出控制部分
控制部分包含三个控件,模拟输出控制控件、继电器控制空间和数字输出控制控件。模拟控制控件是一个文本框和一个浮点数字调整框的组合,设定调整框内数值的范围为0-3.3,步长为0.01。继电器控制包含4个按键,数字输出包含4个控制按键。控制界面如图4.1.2.
图4.1.2 控制界面
4.1.3 布局
页面布局采用QT自缩放行列布局,每一行的控件为一组,每一组组内按列排列,组外按行排列。这样,当控制软件窗口分辨率改变时,控制软件会自动改变内部各控件的大小,不会出现显示不全或者控件过小的问题。下图4.1.5和图4.1.6为不同比例时,控制软件自动调整后的主界面。
图4.1.5 长宽比例为1:1时,主界面示意图
图4.1.5 长宽比例为2:1时,主界面示意图
4.2 程序流程设计
控制软件主函数较为简单,主要依赖类似“中断与服务函数”机制的“信号与槽”机制来运行。
4.2.1 主函数流程
主函数大致可以分为三步。第一步,创建应用,设定全局主题、窗体颜色和字体。随后,根据界面文件,渲染并显示主程序界面。最后,主函数结束,程序调度交由信号与槽机制管理。
4.2.2 网络连接部分的信号与槽
该部分定义了一个信号和一个槽函数。“clicked”信号会在“连接”按钮被点击后发出,该信号发出后,会名为“MainWindow::on_pushButton_clicked()”的槽函数。该函数首先禁用网络部分的全部控件,并将“连接”按钮的文本由“连接”改为“请稍候”,随后创建一个虚函数作为“QTcpSocket::connected”信号的槽函数,最后根据地址控件内的地址文本和端口控件的毒端口数值向受控端发送TCP协议请求连接的报文。
当连接成功后,会切换至控制界面。
QObject::connect(mSocket,&QTcpSocket::connected,this,[&](){
GSocket=mSocket;
GSocket->write("0000");//输出电压清零
ControlWindow *cw=new ControlWindow;
cw->show();
this->close();
qDebug()<<"connect";
});
4.2.3 模拟输出部分的信号和槽
每次浮点数值调整框的数值改变时,都会触发“QDoubleSpinBox:: value Changed(double)”信号,调用其对应的“MainWindow:: on_doubleSpinBox_value Changed(double arg1)”槽函数。该槽函数中会读取浮点数值调整框中的数值,调用DAC输出的输出矫正函数,得到应设置的DAC数值,调用发送协议函数,将该数值根据通信协议处理后向受控端发出。
void ControlWindow::on_doubleSpinBox_valueChanged(double arg1)//voltage
{
arg1=dac_out_correct(arg1);
QByteArray arr;
QString str;
str=QString("%1").arg(QString::number((int)arg1),4,QLatin1Char('0'));
arr=str.toUtf8();
GSocket->write(arr);
qDebug()<<str ;
}
4.2.3 继电器控制和数字输出部分的信号和槽
任一负载控制按键被按下后,会发出该按键的“clicked”信号,调用该按键的“clicked”信号对应的槽函数。该槽函数首先会读取发出“clicked”信号的按键的状态,随后查表得到当前按键对应的端口和管脚号,生成对应的控制字,最后调用发送协议函数,将生成的控制字处理后发出。
void ControlWindow::on_pushButton_2_clicked(bool checked)//IO1
{
res_safe_check(ui);
ui->doubleSpinBox->setValue(0);
qDebug()<<(int)checked+IO1;
QByteArray arr;
arr=QByteArray::number((int)checked+IO1);
GSocket->write(arr);
QMessageBox::information(this,"操作","修改成功", QMessageBox::Yes, QMessageBox::Yes);
}
4.3 DAC输出矫正函数的实现
间隔0.2V采集一次DAC输出电压,输入matlab,基于线性模型y=a*x+b,其中x为设定电压,y为输出电压,分段使用matlab进行线性拟合,求解系数a和系数b。在上位机中根据采集的输出电压分段,反解DAC应当设定的输出电压,完成DAC的输出校正。
int dac_out_correct(double dac_value)
{
if(dac_value<0.1)
{
dac_value/=0.95;
}
else if(dac_value<0.2)
{
dac_value-=-0.0123;
dac_value/=1.0728;
}
else if(dac_value<0.3)
{
dac_value-=0.0368;
dac_value/=0.8272;
}
else if(dac_value<0.4)
{
dac_value-=-0.0735;
dac_value/=1.1950;
}
else if(dac_value<0.5)
{
dac_value-=0.0801;
dac_value/=0.8100;
}
else if(dac_value<0.6)
{
dac_value-=-0.0364;
dac_value/=1.0400;
}
else if(dac_value<0.7)
{
dac_value-=0.0032;
dac_value/=0.9780;
}
else if(dac_value<0.8)
{
dac_value-=0.1124;
dac_value/=0.8220;
}
else if(dac_value<1.0)
{
dac_value-=-0.0348;
dac_value/=1.006;
}
else if(dac_value<1.2)
{
dac_value-=-0.0393;
dac_value/=1.0105;
}
else if(dac_value<1.4)
{
dac_value-=-0.0405;
dac_value/=1.0115;
}
else if(dac_value<1.6)
{
dac_value-=-0.0391;
dac_value/=1.0105;
}
else if(dac_value<1.8)
{
dac_value-=-0.0327;
dac_value/=1.0065;
}
else if(dac_value<2.0)
{
dac_value-=0.195;
dac_value/=0.8800;
}
else if(dac_value<2.2)
{
dac_value-=0.06;
dac_value/=0.9475;
}
else if(dac_value<2.4)
{
dac_value-=-0.0786;
dac_value/=1.0105;
}
else if(dac_value<2.6)
{
dac_value-=0.0810;
dac_value/=1.0115;
}
else if(dac_value<2.8)
{
dac_value-=-0.0797;
dac_value/=1.0110;
}
else if(dac_value<3)
{
dac_value-=-0.0825;
dac_value/=1.0120;
}
else if(dac_value<3.2)
{
dac_value-=-0.0615;
dac_value/=1.0050;
}
else if(dac_value<3.23)
{
dac_value-=1.7145;
dac_value/=0.4500;
}
else if(dac_value<=3.3)
{
dac_value=4095;
}
else
{
dac_value=0;
}
dac_value/=DAC_STEP;
if(dac_value>4095)
dac_value=4095;
return dac_value ;
}
五、效果展示
实物如图所示,具体效果请参见视频。
六、结论及展望
本文实现了一个基于CH32的远程控制平台,可以在网络覆盖范围内远程操控受控端的模拟和数字输出及继电器通断。根据网络覆盖范围的大小,可以实现任意距离的通信。