该方法程序通过C#网络编程实现。通过加入组播组,接收组播信息,确定信道状态并读取设备分配频率值,经由该频率值设置频谱模块中心频率,采用自动跟踪或手动跟踪方式,将设备工作信号置于频谱中心,从而实现信号快速跟蹤。
《当代通信》是由信息产业部主管,中国通信企业协会主办,中国电信博物馆承办的通信类综合刊物。自1994年创刊以来,因其丰富的内容、权威的报道,形成了自己的特色和影响。
新型通信装备,普遍采用网络接口集中控制,通过组播方式定时播发状态信息,通过捕获状态信息,可以明确了解设备工作状态,通过单播方式控制设备工作状态,从而达成通信。
本装置采用捕获状态信息,获取频率参数,通过频率参数设置频谱模块中心频率值,将信号频谱置于中心位置观察,判断信号质量,达到检测信号的目的。
1 基本原理
多台调制解调器的控制网口和频谱模块的数据网口连接到控制交换机,然后连接到信号监测计算机,通过信号监测计算机程序,捕获调制解调器控制网口的控制信号,解析信号格式,读取频率信息,利用此频率信息,控制频谱模块的中心频率,将信号显示在屏幕中央,以便观察信号质量。其基本原理如图1所示。
2 接收组播状态信息并提取频率信息部分关键代码
通过定义组播地址和组播端口,加入组播组(注意区分组播地址端口与单播地址端口的区别),并接收组播信息[1-3]。
receiveUdpClient = new UdpClient(local_port);
receiveUdpClient.JoinMulticastGroup(multicast_IP);
remoteipendpoint = new IPEndPoint(IPAddress.Any, 0);
Thread threadReceive = new Thread(ReceiveMessage);
threadReceive.Name = "ReceiveThread";
threadReceive.Start();
线程threadReceive中的ReceiveMessage()函数通过无限循环,不断接收组播信息,并将接收到的十六进制信息以ASCII方式显示出来。displaytheresult(byte[] test)从接收信息帧中提取信道状态,显示在信道状态标签中。此处涉及十六进制与ASCII码之间的转换,以及频率值计算等帧解析内容,是程序的难点之一。
void displaytheresult(byte[] test)
{
if(test[7]==0x93) //帧标识
{ byte tempbyte=test[11]; //信道状态
switch( tempbyte)
{ case 0x20:
lbl_status_Text="空闲";
break;
……
}}
if(test[7]==0x97) //帧标识
{ byte[] tempbytes1=new byte[4]; //取接收频率字节,从15到18字节
tempbytes1[0] =test[15]; //倒序
tempbytes1[1] =test[16];
tempbytes1[2] =test[17];
tempbytes1[3] =test[18];
uint tempint=System.BitConverter.ToUInt32(tempbytes1,0); //变换为32bits整数
tempint-=9750000; //频率变换
lbl_ReceiveFrequency_Text = tempint.ToString();
((Label)(this.Controls.Find(tempstr22, true)[0])).Text = lbl_ReceiveFrequency_Text;
…… //发送频率,从19到23字节;通信对方电话号码,从33到36字节
}}
3 操作频谱模块部分关键代码
第一步、分配频率组播信息仅仅在分配频率时出现一次,因此,频率信息稍纵即逝,必须持续监听组播信息,获取分配的频率值,结合判断信道状态,确定频率的有效性,如果频率有效,且获取了频率信息,则将频率值显示在发送频率或接收频率标签上。
第二、在接收频率或发送频率标签上点击鼠标或设置为自动跟踪方式,点击鼠标触发事件,该事件将标签频率值设置为频谱模块中心频率,频谱模块的频谱中心显示通信信号,通过该信号观察信号质量,从而实现发送频率或接收频率的快速跟踪。
频谱模块控制采用标准SCPI命令[4-5],但是频谱控件的操作参考资料少,功能强大,编程使用比较复杂,是本程序的另一个难点。
设置频谱模块中心频率代码如下。
private void btn_centerfrequency_setup_Click(object sender, EventArgs e)
{double center_freq1 = double.Parse(tbox_centerfrequency.Text);
center_freq1 = center_freq1 * 1000000;
ulong center_freq2 = Convert.ToUInt64(center_freq1);
string center_freq3 = center_freq2.ToString();
string center_freq4 = ":FREQ:CENT " , center_freq3 , '\n';
if (socket != null)
{if (socket.Connected)
{socket.Send(Encoding.ASCII.GetBytes(center_freq4));
readout_x_data();
display_x_data();}}}
設置频谱模块扫宽代码如下:
private void btn_span_setup_Click(object sender, EventArgs e)
{double span1 = double.Parse(tbox_span.Text);
span1 = span1 * 1000000;
ulong span2 = Convert.ToUInt64(span1);
string span3 = span2.ToString();
string span4 = ":FREQ:SPAN " , span3 , '\n';
if (socket!=null)
{if(socket.Connected)
{ socket.Send(Encoding.ASCII.GetBytes(span4));
readout_x_data();
display_x_data();}}}
参考电平的设置,没有采用设置频谱模块参数的方式实现,而是直接设置频谱控件的Y轴范围,实现控制参考电平,其代码如下所示:
private void btn_reflevel_setup_Click(object sender, EventArgs e)
{int yreflevel = int.Parse(tbox_ref_level.Text);
int ybase = yreflevel - yinterval * 10;
yAxis1.SetMinMax(ybase, yreflevel);}
循环读取频谱模块频谱数据,解析该数据并显示频谱图的代码如下所示:
private void timer1_Tick(object sender, EventArgs e)
{double[] temp_data = new double[601];
if (socket.Connected)
{ socket.Send(Encoding.ASCII.GetBytes(":TRAC:DATA? TRACE1\n"));
temp_data = GetData(); //接收频谱数据
PlotData(temp_data); //绘制频谱图
value_display(); //MARKER动态显示
if(peak_enable) //峰值搜索
{peak_x = getmaxandindex(temp_data);
xyCursor1.XPosition = peak_x;
peak_enable = false; }}}
4 结论
该方法程序运行结果如图2所示。
该方法程序还具有存储频谱图片功能、频谱录像及回放功能、标识读数功能、峰值搜索功能等频谱模块常用功能,便于在快速跟踪信号频率的基础上,达到快速判断信号质量的目的。该程序实际使用稳定可靠,跟踪快速,达到任务目的。
参考文献:
[1] 张景峰,邹澎涛.C#中实现IP组播的关键技术[J].电脑开发与应用,2007(9):67-68.
[2] 陈建华.C#中利用UDP协议实现信息的广播和组播[J].软件,2011(11):4-6.
[3] 管丽娜.基于C#的IP组播通信应用设计与实现[J]. 河北省科学院学报,2007(3):12-16.
[4] 秦凡,韦高.基于VISA库及SCPI命令的仪器程控测量[J].现代电子技术,2011(11):118-120.
[5] 徐宙,刘连照,程彦杰,等.基于C#的数字存储示波器控制软件设计与实现[J].计量与测试技术,2016(2):53-55.