今天中午没睡午觉,头昏眼花的,实在写不了代码,把这几天写的Server层数据采集的程序整理了一下。

WatrLevelDataCollectServer.cs

 using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO.Ports;
using SMOS.Model.Device;
using System.Text.RegularExpressions; namespace SMOS.Server.Impl.Collection
{
public class WaterLevelDataCollectServer : DataCollectServer
{
private SerialPort comm = new SerialPort();
private bool Closing = false;//是否正在关闭串口,执行Application.DoEvents,并阻止再次invoke
private bool Listening = false;//是否没有执行完invoke相关操作
private List<byte> buffer = new List<byte>();//默认分配1页内存,并始终限制不允许超过
private byte[] binary_data = new byte[];//FF FF 01 03 1B 1D
private decimal dataValue = ;
private bool dataCatched;
private bool workManner = true;//工作方式,true--使用设备默认的自动报告方式,false--使用查询方式
/// <summary>
/// 采集水位计数据(默认方式,自动报告方式)
/// </summary>
/// <param name="waterLevelSetInfo"></param>
/// <returns></returns>
public override Model.Device.DeviceRecordInfo GetData(Model.Device.DeviceSetInfo deviceSet)
{
WaterLevelSetInfo entity = deviceSet as WaterLevelSetInfo;
//根据当前串口对象,来判断操作
if (comm.IsOpen)
{
comm.Close();
}
try
{
comm.PortName = entity.Port;
comm.BaudRate = entity.BaudRate;
comm.Open();
}
catch (Exception ex)
{
throw ex;
}
if(workManner == false )//采集水位计数据(查询方式,需要对设备进行手动设置)
{
//发送采集指令 ,16进制发送
byte extensionNo = 0x01;//分机编号默认为"01"
byte checkData = 0x6B;//在分机编号默认时,校验位为“6B”
checkData =(byte)(0xFC + 0x6E + (int)extensionNo);
MatchCollection mc = Regex.Matches("FC 6E "+""+extensionNo+"00 00 "+ checkData.ToString("X"), @"(?i)[\da-f]{2}");
List<byte> buf = new List<byte>();//填充到临时列表中
//依次添加到列表中
foreach (Match m in mc)
{
buf.Add(byte.Parse(m.Value, System.Globalization.NumberStyles.HexNumber));
}
//转换列表为数组后发送
comm.Write(buf.ToArray(), , buf.Count);
}
WaterLevelRecordInfo waterLevelRecordInfo = new WaterLevelRecordInfo();
//添加事件注册
comm.DataReceived += comm_DataReceived;
DateTime dtOld = DateTime.Now;
while (true)
{
if (DateTime.Compare(dtOld.AddSeconds(Convert.ToDouble(entity.AcquisitionInterval)), DateTime.Now) > )
{
System.Threading.Thread.Sleep();
if (dataCatched)
{
waterLevelRecordInfo.MeasuredLevel = dataValue;
waterLevelRecordInfo.RecordTime = DateTime.Now;
waterLevelRecordInfo.DeviceID = entity.DeviceID;
//end operation //解绑事件
comm.DataReceived -= comm_DataReceived;
comm.Close();
return waterLevelRecordInfo as DeviceRecordInfo;
}
}
else
{
comm.DataReceived -= comm_DataReceived;
comm.Close();
return null;
}
}
}
/// <summary>
/// 串口数据接收
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void comm_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
if (Closing) return;//如果正在关闭,忽略操作,直接返回,尽快的完成串口监听线程的一次循环
try
{
Listening = true;//设置标记
int n = comm.BytesToRead;//记录缓存
byte[] buf = new byte[n];//声明一个临时数组存储串口数据
comm.Read(buf, , n);//读取缓冲数据
dataCatched = false;//缓存记录数据是否捕获到
//缓存数据
buffer.AddRange(buf);
//完整性判断
while (buffer.Count >= )//至少要包含头(2字节)+分机编号(1字节)+测量数据(2字节)+校验(1字节)
{
//查找数据头
if (buffer[] == 0xFF && buffer[] == 0xFF)
{
int len = ;//数据长度
//数据完整判断第一步,长度是否足够
if (buffer.Count < len) break;
buffer.CopyTo(, binary_data, , len);//复制一条完整数据到数据缓存
//分析数据
dataValue = (decimal)((binary_data[] * + binary_data[]) / 1000.000);
dataCatched = true;
buffer.RemoveRange(, len);//正确分析一条数据,从缓存中移除数据
}
else
{
//如果数据开始不是头,则删除数据
buffer.RemoveAt();
}
}
}
catch (Exception ex)
{
dataCatched = false;
}
finally
{
Listening = false;//可以关闭串口
}
}
}
}

在WaterLevelDataCollectServer这个类里主要通过GetData这个方法来实现的水位计数据的采集,使用SerialPort控件,当串口接收导数据的时候自动触发comm_DataReceived事件,但是由于这个事件被触发的时刻不确定,所以在GetData方法中使用循环等待,当接收到数据时跳出循环,并将采集结果返回。

  在没有实际设备的时候可以用串口调试助手并通过虚拟串口给程序发送数据,注意COM口,波特率等通信参数的设置应该一一对应。

用C#实现通过串口对设备的数据采集--Server层的更多相关文章

  1. S3C6410串口平台设备注册流程分析

    1.mdesc->map_io() start_kernel -->setup_arch(&command_line); -->paging_init(mdesc); --& ...

  2. [python] 3 、基于串口通信的嵌入式设备上位机自动测试程序框架(简陋框架)

    星期一, 20. 八月 2018 01:53上午 - beautifulzzzz 1.前言 做类似zigbee.ble mesh...无线网络节点性能测试的时候,手动操作然后看表象往往很难找出真正的原 ...

  3. [连载]《C#通讯(串口和网络)框架的设计与实现》-2.框架的总体设计

    目       录 C#通讯(串口和网络)框架的设计与实现... 1 (SuperIO)- 框架的总体设计... 1 第二章           框架总体的设计... 2 2.1           ...

  4. 【工业串口和网络软件通讯平台(SuperIO)教程】二.架构和组成部分

    1.1    架构结构图 1.1.1    层次示意图 1.1.2    模型对象示意图 1.2    IO管理器 IO管理器是对串口和网络通讯链路的管理.调度.针对串口和网络通讯链路的特点,在IO管 ...

  5. Linux下串口编制【转】

    串行口是计算机一种常用的接口,具有连接线少,通讯简单,得到广泛的使用.常用的串口是RS-232-C接口(又称EIA RS-232-C)它是在1970年由美国电子工业协会(EIA)联合贝尔系统.调制解调 ...

  6. Smart210学习记录------linux串口驱动

    转自:http://blog.chinaunix.net/xmlrpc.php?r=blog/article&uid=27025492&id=327609 一.核心数据结构 串口驱动有 ...

  7. 四轴飞行器1.2.2 RT-Thread 串口

    四轴飞行器1.2.2 RT-Thread 串口        本来是打算说根据RT-Thread的设备管理提供的驱动接口些串口驱动的,但是仔细一看,我去,串口驱动写好了,只需要调用就可以了.下面我们说 ...

  8. Linux串口编程详解(转)

    串口本身,标准和硬件 † 串口是计算机上的串行通讯的物理接口.计算机历史上,串口曾经被广泛用于连接计算机和终端设备和各种外部设备.虽然以太网接口和USB接口也是以一个串行流进行数据传送的,但是串口连接 ...

  9. linux串口编程总结

    串口本身.标准和硬件 † 串口是计算机上的串行通讯的物理接口.计算机历史上,串口以前被广泛用于连接计算机和终端设备和各种外部设备.尽管以太网接口和USB接口也是以一个串行流进行数据传送的.可是串口连接 ...

随机推荐

  1. 【C++】不要在构造函数或析构函数内调用虚函数

    这个问题来自于<Effective C++>条款9:永远不要在构造函数或析构函数中调用虚函数 . 假设有如下代码: class Transaction {// 所有交易的基类 public ...

  2. 【数据库】mysql中复制表结构的方法小结

    mysql中用命令行复制表结构的方法主要有一下几种: 1.只复制表结构到新表 ? 1 CREATE TABLE 新表 SELECT * FROM 旧表 WHERE 1=2 或者 ? 1 CREATE ...

  3. 【bzoj3119】Book 数学

    题目描述 一个长度为N的序列的首项为X,以后的每一项要么比前一项大A,要么比前一项小B.已知总和为M,求一组可行方案. 输入 第一行一个正整数N.第二行四个整数依次是X,A,B,M. 输出 输出一行N ...

  4. sql语句左链接left join--3张表关联

    表A---------------------------------关联第一张表B-----------------------关联第二张表c select * fomr 表名A left join ...

  5. 【HLSDK系列】服务端 UpdateClientData 函数

    首先说明下,这个函数是写在 mp.dll 里的. 服务器会给每个客户端发送一些数据,其中两大数据种类就是 clientdata_t 和 entity_state_t 这里要说的是 clientdata ...

  6. P4622 [COCI2012-2013#6] JEDAN

    题目背景 COCI 题目描述 有N个数排成一行(数值代表高度),最初所有的数都为零,你可以选择连续的一段等高的数,将它们都增加1(除了开头和结尾那个数)如下图表示了两次操作: 现在有一些数字看不清了, ...

  7. 洛谷 P1987 摇钱树

    题目戳 题目描述 Cpg 正在游览一个梦中之城,在这个城市中有n棵摇钱树...这下,可让Cpg看傻了...可是Cpg只能在这个城市中呆K天,但是现在摇钱树已经成熟了,每天每棵都会掉下不同的金币(不属于 ...

  8. 【BZOJ2727】双十字(动态规划,树状数组)

    [BZOJ2727]双十字(动态规划,树状数组) 题面 BZOJ 洛谷 题解 我们去年暑假的时候考试考过. 我当时写了个大暴力混了\(70\)分.... 大暴力是这么写的: 预处理每个位置向左右/上/ ...

  9. SCWS中文分词,安装说明(以:Win32环境、utf8字符集为例)

    SCWS官方网站:http://www.xunsearch.com/scws/ 1. 根据您当前用的 PHP 版本,下载相应已编译好的 php_scws.dll 扩展库.    目前支持 PHP-5. ...

  10. Java之JNI的介绍与应用20170622

    /*************************************************************************************************** ...