在实现基于链状通讯的阴保电位自动采集和传输后,作为该系统的加强和补充,我们开发了阴保电位采集仪的遥测功能。
该功能为单个阴保电位采集仪的定制功能,即在距离装有阴保电位采集仪的测试桩1米~4000米范围内,通过计算机发送具体的动作指令,采集仪接收指令并执行指定的动作,完成后发送数据回执,计算机接收并存储,回到基地后上传至数据库服务器中。
阴保电位采集仪节点机的程序编写过程:
步骤 | 应用工具/平台 | 工作内容 |
1 | 在STM32 Cube | 建立项目工程开发源文件 |
2 | Keil uVisions | 完成实际功能的开发编写、编译 |
3 | M3U8 Downloader | 烧写代码至数据采集芯片中 |
4 | 串口调试助手 | 数据及功能测试 |
部分核心代码:
void AnalysisDataPacket(void){
//返回错误的约定:如果该命令与本桩有关则根据设定来决定是否返回错误信息,如果该命令与本桩无关则不必返回错误信息,接收的全部是16进制的数字
bool Inspect=true;
uint8_t ErrorCode=0;
for(int i=0;i<70;i++){
SendBuffer[i]=0x00;//文件头设定
}
//分析文件头
if (ReceiveBuffer[0] != 0x59 || ReceiveBuffer[1] != 0x51 || ReceiveBuffer[2]!=0x43 || ReceiveBuffer[3]!=0x59 ){
Inspect=false;
ErrorCode=0x011;//错误代码11:标识文件头的错误
}
//分析文件尾
if ( ReceiveBuffer[66]!=0x59 || ReceiveBuffer[67]!=0x42 || ReceiveBuffer[68]!=0x44 || ReceiveBuffer[69]!=0x57 ){
Inspect=false;
ErrorCode=0x022;//错误代码22:标识文件尾的错误
}
//是否是属于本线和本站的接收命令
if( ReceiveBuffer[4]!=0x01 || ReceiveBuffer[6]!=0x00 ){
Inspect=false;
ErrorCode=0x33;//错误代码33:不是遥测
}
//是否是属于本线和本站的接收命令
if( ReceiveBuffer[5]!=YBDWPipeline || ReceiveBuffer[7]!=YBDWPile ){
Inspect=false;
ErrorCode=0x44;//错误代码44:不是本线或者本站的接收命令
}
if(Inspect==true){
//准备返回的数据
for(int i=0;i<4;i++){
SendBuffer[i]=ReceiveBuffer[i] ;//文件头设定
SendBuffer[66+i]=ReceiveBuffer[66+i] ;//文件尾设定
}
SendBuffer[4]=0x11;//传输类型
SendBuffer[5]=YBDWPipeline;//线号
SendBuffer[6]=YBDWPile;//桩号
SendBuffer[7]=0x00;//接收方
SendBuffer[8]=ReceiveBuffer[8];//会话标识
SendBuffer[9]=ReceiveBuffer[9];//具体的命令
//根据具体的命令来进行实际操作
switch(ReceiveBuffer[9]){
case Set_LineAndPile://设置线号和桩号、本线的起始和结束桩号
//合成一个字,分别为:本桩的桩号、线号、起始桩号、结束桩号
LineAndPile_To_Flash=((uint32_t)(ReceiveBuffer[18]<<24))| ((uint32_t)(ReceiveBuffer[19]<<16))|((uint32_t)(ReceiveBuffer[20]<<8))|( (uint32_t)(ReceiveBuffer[21]) );
Func_SetLineAndPile();
HAL_Delay (10);
Func_GetLineAndPile();
break;
case Get_LineAndPile://获取线号和桩号、本线的起始和结束桩号
Func_GetLineAndPile();
break;
......
default: //不支持的命令
break;
}
//写日期、时间
HAL_RTCEx_WakeUpTimerEventCallback (&hrtc);//向第10~15位写入日期时间
//返回数据
HAL_UART_Transmit(&hlpuart1,SendBuffer,70,10); //串口1向LORA发送整个缓冲区
}
else
{
if(ReceiveBuffer[17]==0x99&&ReceiveBuffer[5]!=YBDWPipeline && ReceiveBuffer[7]!=YBDWPile ){
//根据配置决定是否将错误返回,只与本桩的信号才回馈信息
SendBuffer[5]=YBDWPipeline;//线号
SendBuffer[6]=YBDWPile;//桩号
SendBuffer[65]=ErrorCode;
HAL_UART_Transmit(&hlpuart1,SendBuffer,70,10); //串口1向LORA发送整个缓冲区
}
}
开发上位机程序在Visual studio 2015平台下采用C#语言编写,完成后的程序界面如下:
部分核心代码:
private void OnReceiveMsg(string s1){
if (not string.IsNullOrEmpty(s1)){
//接收数据的处理
this.BeginInvoke(new Action(() => {
//显示原始数据
......
//分析包头和包尾
Int32 I1 = STEMP.IndexOf("00AC");
Int32 I2 = STEMP.IndexOf("00EE");
if (I1>0 && I2>0 && (I2 - I1)==32 )
{
//正确的数据,进入数据处理
......
//得到数据结果,根据结果进行相应的显示或者存储
axiSevenSegmentAnalogX1.Value = YBDWDealWithData.XTDianYa.dValue;//电池电压
axiSevenSegmentAnalogX2.Value = YBDWDealWithData.YBDianWei.dValue;//通电电位
axiSevenSegmentAnalogX3.Value = YBDWDealWithData.SPDianWei.dValue;//断电电位
axiSevenSegmentAnalogX4.Value = YBDWDealWithData.TYNDianYa.dValue;//光伏电压
axiSevenSegmentAnalogX5.Value = YBDWDealWithData.YHDianYa.dValue;//交流电压
axiSevenSegmentAnalogX6.Value = YBDWDealWithData.EHDianYa.dValue;//温度
......
//显示趋势图
......
FuncDrawYBDW();
if (SaveToMdb)
{
//存入本地数据库
using(OleDbConnection MyAccess = new OleDbConnection(StrConn)){
//插入数据记录
......
OleDbInsert.ExecuteNonQuery();
}
}
}));
}
}
部分指令列表:
中文含义 | 指令格式 |
设置系统时间 | set SystemDatetime 2019-3-10 17:02:34 |
设置工程量的偏移量(零位和满度) | set EngineeringOffsetMin 2.23 set EngineeringOffsetMax 7.6 |
设置线号和桩号(包括地理坐标位置) | Set LineNumber WHX //设置线号 Set PileNumber 1 //设置桩号 |
设置桩头和桩尾 | Set PileNumberEnd 50 //设置桩尾 Set PileNumberStart 1 //设置桩头 |
设置软件的版本号信息 | Set VersionNumber 版本 //版本号 Set VersionDatetime 版本 //时间 |
设置实时采样频率(阴保电位)、采集时长 | Set SamplingFrequency-YBDW 200 |
设置实时采样频率(IR降)、采集时长 | Set SamplingFrequency-IR 50 |
设置实时采样频率(太阳能电池板)、采集时长 | Set SamplingFrequency-BatteryPanel 50 |
数据帧的定义:
序号 | 字段名称汉字 | 字段名称英文 | 起始位置 | 长度 | 说明 |
1 | 包头 | PackageHead | 0 | 4 | YQCY |
2 | 传输类型 | TransmissionType | 4 | 1 | 1为遥测,2为链状通讯,3为星型通讯 |
3 | 发送方线号 | SendLineNumber | 5 | 1 | 遥测为0,链状通讯为实际的发送方所在的线号 |
4 | 发送方桩号 | SendPileNumber | 6 | 1 | 遥测为0,链状通讯为实际的发送方所在的桩号 |
5 | 接收方线号 | ReceLineNumber | 7 | 1 | 遥测为0,链状通讯为实际的接收方所在的线号 |
6 | 接收方桩号 | RendPileNumber | 8 | 1 | 遥测为0,链状通讯为实际的接收方所在的桩号 |
7 | 命令标识 | CommandIdentification | 9 | 1 | 用于握手认证和确认传输命令的唯一性 |
8 | 命令名称 | CommandName | 10 | 1 | 命令对应的名称 |
9 | 命令传输时间 | SendDatetime | 11 | 6 | 年月日、时分秒 |
10 | 备用 | ReserveData | 17 | 2 | |
11 | 数据区 | CommandParameter | 19 | 48 | 数据传输时放传输的数据,数据接收时放命令的参数 |
12 | 包尾 | PackageTail | 67 | 4 | YBDW |
系统运行逻辑示意图:
目前市面上,阴保电位采集仪的数据一般都采用形式多样的网络传输,极少有单个传输的功能,阴保电位遥测功能属于补全的一个措施。一方面,它可作为整个系统的加强延伸了系统功能的外延;另一方面,点对点传输可以传输更多的系统信息,对于网络故障诊断和修复提供了手段,丰富了系统的整个应用。
PS:以前发表文章都是不收费用并且杂志社还免费寄送刊样。现在发表文章很多杂志社都需要收取费用(比如审稿费等),寄送杂志也要收取费用(比如邮寄费用)。
不过,很多情况下作者也属无奈,单位每年都要评比,不发表论文不行。所以,还是要提高写作者的稿件质量。
《电脑编程技巧与维护》,2021年7月下半月刊,38页。