1、用 VB 进行串口实时数据采集VB-界面速成通道 /ChenLL 发表于 2007-08-10, 20:28 用 VB 进 行 串 口 实 时 数 据 采 集 本 文 介 绍 VB6.0 利 用 MSComm 通 信 控 件 , 开 发 微 机 通 过 串 口 对 工 业 仪 表 进 行 实 时数 据 采 集 的 编 程 技 术 。 给 出 的 程 序 代 码 具 有 通 用 性 , 并 有 详 细 的 注 释 , 可 以 直 接 或 稍 加改 动 后 用 于 其 他 数 据 采 集 或 实 时 控 制 程 序 中 。 -一 台 工 业 专 用 实 时 检 测 仪 表 , 接 高 精 度 位
2、移 传 感 器 , 用 于 测 量 微 小 形 变 或 微 量 位 移, 仪 表 测 量 精 度 为 0.01 毫 米 , 测 量 范 围 最 大 值 为 50 毫 米 。 该 仪 表 带 有 一 个 9 针 的RS-232C 串 口 , 能 与 微 机 进 行 串 口 数 据 通 信 , 实 时 传 送 检 测 数 据 , 通 过 微 机 软 件 处理 可 实 现 工 业 实 时 监 控 。 -该 仪 表 的 串 口 数 据 通 信 协 议 是 : 数 据 传 输 速 率 为 9600bps, 1 位 开 始 位 , 8 位数 据 位 , 1 位 停 止 位 , 无 奇 偶 校 验 位 。
3、仪 表 每 秒 发 送 50 帧 检 测 数 据 , 每 帧 数 据 由 4个 字 节 组 成 。 第 一 个 字 节 定 义 为 二 进 制 常 数 0F0H, 是 每 帧 数 据 开 始 的 标 志 字 节 ; 后面 连 续 2 个 字 节 为 数 据 字 节 , 采 用 压 缩 的 BCD 码 编 码 方 式 , 高 位 在 前 , 低 位 在 后 ,即 一 个 字 节 表 示 两 位 十 进 制 数 , 则 两 个 字 节 表 示 四 位 十 进 制 数 , 小 数 点 采 用 固 定 形 式 ,定 义 在 两 字 节 中 间 ; 第 四 个 字 节 为 符 号 字 节 , 该 字 节
4、 第 八 位 为 1, 即 : 1 x x x x x x x 则 为 负 数 ; 第 八 位 为 0, 即 : 0 x x x x x x x 则 为 正 数 。 -例 如 : 0F0H 26H 87H 80H 0F0H 34H 62H 00H 表 示 26.87 34.62。 -通 信 传 输 速 率 为 9600bps, 则 最 快 速 度 1.04ms 发 送 一 个 字 节 , 仪 表 每 秒 发送 50 帧 数 据 , 每 帧 数 据 有 4 个 字 节 , 即 每 秒 发 送 200 个 字 节 , 平 均 5.0ms 发 送一 个 字 节 , 连 续 读 取 串 口 数 据 时
5、 要 在 程 序 中 添 加 循 环 等 待 程 序 。 -为 了 实 现 实 时 监 测 功 能 , 接 收 数 据 的 读 取 要 尽 可 能 的 快 速 , 则 设 置 MSComm1的 属 性 如 下 : RThreshold = 1 接 收 缓 冲 区 收 到 一 个 字 节 产 生 OnComm 事 件InputLen = 1 每 次 读 取 一 个 字 节-仪 表 每 秒 发 送 50 帧 数 据 , 微 机 收 到 一 帧 完 整 数 据 至 少 需 要 20 ms 时 间 , 然 后再 进 行 数 据 处 理 。 如 果 微 机 在 下 一 帧 数 据 接 收 前 即 20m
6、s 内 能 将 数 据 计 算 处 理 完 毕, 则 接 收 缓 冲 区 内 只 会 保 存 有 一 帧 数 据 , 不 会 存 有 两 帧 以 上 数 据 , 接 收 缓 冲 区 的 大 小 不会 影 响 实 时 监 测 效 果 ( 接 收 缓 冲 区 4 字 节 ) , 这 时 完 全 可 以 实 现 实 时 监 测 或 实 时 控 制; 如 果 微 机 在 20ms 内 不 能 将 数 据 计 算 处 理 完 毕 , 接 收 缓 冲 区 设 置 得 又 很 大 , 在 数 据计 算 处 理 完 毕 前 , 接 收 缓 冲 区 内 就 会 保 存 有 两 帧 以 上 数 据 , 而 且 一
7、 次 工 作 时 间 越 长 , 缓冲 区 内 滞 留 数 据 帧 就 越 多 , 数 据 采 集 和 数 据 处 理 之 间 产 生 逐 渐 增 大 的 额 外 时 间 差 , 当 接收 缓 冲 区 充 满 后 , 时 间 差 不 再 增 大 , 固 定 在 某 一 值 , 部 分 数 据 因 不 能 及 时 采 集 到 接 收 缓冲 区 中 , 数 据 产 生 丢 失 现 象 , 真 实 工 作 情 况 就 会 和 微 机 处 理 结 果 产 生 较 大 的 时 间 差 , 对实 时 监 测 和 实 时 控 制 很 不 利 , 这 种 情 况 下 接 收 缓 冲 区 的 大 小 就 会 影
8、 响 实 时 监 测 效 果 , 所以 接 收 缓 冲 区 设 置 不 能 过 大 , 以 保 证 数 据 处 理 的 实 时 性 。 -设 置 接 收 数 据 模 式 采 用 二 进 制 形 式 , 即 InputMode=comInputModeBinary, 但 用 Input 属 性 读 取 数 据 时 , 不 能 直 接 赋 值 给 Byte 类 型 变 量 , 只 能 通 过 先 赋值 给 一 个 Variant 类 型 变 量 , 返 回 一 个 二 进 制 数 据 的 数 组 , 再 转 换 保 存 到 Byte类 型 数 变 量 中 。 -VB 中 有 Byte 类 型 变
9、量 , 但 没 有 字 节 的 位 处 理 语 句 , 符 号 字 节 的 位 处 理 要 判 断 符号 字 节 的 值 是 否 大 于 127, 大 于 127 则 为 负 数 ; 压 缩 的 BCD 码 存 入 Byte 类 型变 量 , VB 系 统 只 按 十 进 制 数 处 理 , 这 要 通 过 一 个 简 单 算 法 换 算 , 解 压 BCD 码 才 能还 原 成 十 进 制 表 示 数 值 。 假 如 a 是 Byte 类 型 变 量 , D 是 Single 类 型 变 量 , 将 一 个压 缩 的 BCD 码 存 入 a 中 , 则 算 法 是 : D=(a16) 10
10、a (a16) 16 则 D=a (a16) 6-程 序 清 单 : -在 通 用 声 明 中 定 义 程 序 所 用 变 量 : Dim ab(4) As Byte 字 节 数 据 类 型 数 组 , 用 来 存 储 接 收 到 的 一 组 字 节 数 据Dim av As Variant 用 来 从 接 收 缓 冲 区 读 取 数 据Dim i As IntegerDim j As IntegerDim w As Integer 接 收 数 据 个 数 计 数 器Dim b1 As SingleDim b2 As SingleDim WW As Single 十 进 制 检 测 值Dim
11、MaxW As Single 最 大 值Dim MinW As Single 最 小 值-在 窗 体 中 添 加 名 为 Command1 的 开 始 按 钮 和 名 为 MSComm1 的 MSComm 控 件 。 - 开 始 按 钮 的 Click 事 件 处 理 程 序 主 要 是 对 MSComm1 控 制 的 参 数 初 始 化 设置 , 程 序 中 大 部 分 参 数 在 设 计 时 可 在 MSComm1 控 制 的 属 性 窗 口 中 设 置 : Private Sub Command1_Click()开 始 按 钮With MSComm1.CommPort=2 使 用 COM
12、2.Setting=“9600,N,8,1“ 设 置 通 信 口 参 数.InBufferSize=40 设 置 MSComm1 接 收 缓 冲 区 为 40 字 节.OutBufferSize=2 设 置 MSComm1 发 送 缓 冲 区 为 2 字 节.InputMode = comInputModeBinary 设 置 接 收 数 据 模 式 为 二 进 制 形 式.InputLen = 1 设 置 Input 一 次 从 接 收 缓 冲 读 取 字 节 数 为 1.SThreshold = 1 设 置 Output 一 次 从 发 送 缓 冲 读 取 字 节 数 为 1.InBuff
13、erCount = 0 清 除 接 收 缓 冲 区.OutBufferCount = 0 清 除 发 送 缓 冲 区MaxW = 99 最 大 值 赋 初 值MinW = 99 最 小 值 赋 初 值w = 0 数 据 个 数 计 数 器 清 零.RThreshold = 1 设 置 接 收 一 个 字 节 产 生 OnComm 事 件If .PortOpen = False Then 判 断 通 信 口 是 否 打 开.PortOpen = True 打 开 通 信 口If Err Then 错 误 处 理MsgBox “串 口 通 信 无 效 “Exit SubEnd IfEnd IfEn
14、d WithEnd Sub-为 了 达 到 实 时 数 据 采 集 目 的 , 实 时 数 据 采 集 处 理 程 序 采 用 MSComm 事 件 驱 动方 式 。 -MSComm1_OnComm 的 事 件 处 理 程 序 只 处 理 comEvReceive 事 件 , 首先 判 断 帧 数 据 的 开 始 字 节 , 关 闭 OnComm 接 收 事 件 , 然 后 接 收 数 据 字 节 , 将 压 缩BCD 进 行 还 原 转 换 , 再 接 收 符 号 字 节 , 判 断 数 据 符 号 , 判 断 数 据 最 大 最 小 值 , 最 后 打开 OnComm 接 收 事 件 ,
15、等 待 下 一 次 OnComm 事 件 产 生 : Private Sub MSComm1_OnComm()With MSComm1Select Case .CommEvent判 断 MSComm1 通 信 事 件Case comEvReceive 收 到 Rthreshold 个 字 节 产 生 的 接 收 事 件av = .Input 读 取 一 个 接 收 字 节ab(1) = av(0) 转 换 保 存 到 字 节 数 据 类 型 数 组If ab(1) = HF0 Then 判 断 是 否 为 数 据 开 始 标 志RThreshold = 0 关 闭 OnComm 事 件 接 收
16、DoDoEventsLoop Until .InBufferCount = 3 循 环 等 待 MSComm1 接 收 缓 冲 区 =3 个 字 节w = w 1 计 数 器 累 加 计 数av = .Input 读 取 第 二 个 数 据 字 节 ( BCD 码 高 位 字 节 )ab(2) = av(0) 转 换 保 存 到 字 节 数 据 类 型 数 组av = .Input 读 取 第 三 个 数 据 字 节 ( BCD 码 低 位 字 节 )ab(3) = av(0) 转 换 保 存 到 字 节 数 据 类 型 数 组av = .Input 读 取 第 四 个 数 据 字 节 ( 符
17、 号 位 字 节 )ab(4) = av(0) 转 换 保 存 到 字 节 数 据 类 型 数 组 b1 = ab(2) 6 (ab(2)16) 高 位 字 节 压 缩 BCD 码 转 换 为 实 数b2 = ab(3) 6 (ab(3)16) 低 位 字 节 压 缩 BCD 码 转 换 为 实 数WW = b1 b2 / 100 数 值 组 合 , 标 定 小 数 点If ab(4) 127 Then WW= WW 判 断 数 据 符 号 位Label1(0) = Format(WW, “0.00“)显 示 毫 米 单 位 数 值 , 2 位 小 数Label1(1) =Format(WW
18、/25.4, “0.000“)显 示 英 寸 单 位 数 值 , 3 位 小 数If WW MaxW And WW 51 Then判 断 最 小 值MinW = WWLabel1(4) = Format(MinW, “0.00“) 显 示 毫 米 单 位 最 小 值 , 2 位 小 数Label1(5) = Format(MinW/25.4,“0.000“)显 示 英 寸 单 位 最 小 值 , 3 位 小 数End If.RThreshold = 1 打 开 MSComm1 事 件 接 收End IfCase ElseEnd SelectEnd WithEnd Sub 基于 VB 的串口数据
19、采集 来源:机电论文 | 类别:技术 | 时间:2008-6-21 14:44:00 字体:大 中 小要求:用 VB 编写一个小软件,采集电子数显千分表的数据数显表接口参数:数显表的专用接口可与 PC 机的 RS232(9 针)相接,其波特率 4800,无奇偶校检,8 位数据位,1 位停止位,以 AcsII 码发送数据窗体设计:1 个 listbox,1 个 textbox,1 个 MSComm 控件,2 个 CommandButton程序设计:Dim indata As VariantDim data(100) As SinglePrivate Sub Command1_Click()Sta
20、tic ii = i + 1data(i) = Text1.TextList1.AddItem data(i)End Sub .按键一次,采集一个数据,并存入 List1 中Private Sub Command2_Click()MSComm1.PortOpen = False .关端口Unload MeEnd Sub .退出Private Sub Form_Load()MSComm1.CommPort = 1 .使用 Com1 口MSComm1.Settings = “4800,n,8,1“ .设置通讯参数MSComm1.RThreshold = 10MSComm1.streshold =
21、10MSComm1.PortOpen = True .打开串口Text1.Text = “End SubPrivate Sub MSComm1_OnComm()Select Case MSComm1.CommEventCase comEvReceive .有接收事件发生indata = MSComm1.InputText2.Text = (indata / 10) text1 实时显示数显表的数据MSComm1.InBufferCount = 0 .清空输入寄存器End SelectEnd Sub我这有一段 VB 程序是为了画实时采集曲线的。 软件编程我不行,如果大家有看得懂得,请帮我看看。
22、程序不多 Private Sub MSComm1_OnComm() Dim Inbyte() As Byte Dim buffer As String Dim datatemp(1000) As Single If num 199 Then Call renew 刷新绘图区 读取仪表返回数据串 Select Case MSComm1.CommEvent Case comEvReceive Inbyte = MSComm1.Input 这地方看不懂,数组可以这样赋值吗? For i = LBound(Inbyte) To UBound(Inbyte) buffer = buffer + Hex(
23、Inbyte(i) + Chr(32) for 语句也没看懂,尤其是 buffer 这赋的是什么值? Next i Case comEvSend End Select 获取十进制测量数据 这下面的又是没看懂,应该是将十六进制转换为十进制,怎么转换的呢? If Len(Trim(Mid(buffer, 1, 2) = 1 Then datatemp(num) = Val( “&H “ & Mid(buffer, 3, 2) & Str( “0 “) & Mid(buffer, 1, 2) * 0.01 Else datatemp(num) = Val( “&H “ & Mid(buffer, 3
24、, 2) & Mid(buffer, 1, 2) * 0.01 End If 绘制曲线 Private Sub draw() Picture1.Cls Picture1.DrawWidth = 2 Picture1.BackColor = QBColor(7) 下面的程序我看不懂,用的是什么原理画的曲线呢? Picture1.Scale (0, 50)-(200, 0) For i = 1 To num - 1 X1 = (i - 1): Y1 = datatemp(i - 1) X2 = i: Y2 = datatemp(i) Picture1.Line (X1, Y1)-(X2, Y2),
25、 QBColor(1) Next i End Sub 问题点数:100 回复次数:10 显 示 所 有 回 复 修改 删除 举报 引用 回复 加为好友 发送私信 在线聊天 CathySun118 失 .悟 等级: 可用分等级:富农 总技术分:88266 总技术分排名:66 2发表于:2007-06-25 14:44:411 楼 得分:0连点法阿修改 删除 举报 引用 回复 加为好友 发送私信 在线聊天Winters_le发表于:2007-06-26 09:41:372 楼 得分:0画曲线啊,用这个吧: 实时曲线左移函数,定义在模块中 Public Declare Function BitBlt
26、 Lib “gdi32 “ (ByVal hDestDC As Long, ByVal x As Long, ByVal y As Long, ByVal nWidth As Long, ByVal nHeight As Long, ByVal hSrcDC As Long, ByVal xSrc As Long, ByVal ySrc As Long, ByVal dwRop As Long) As Long 建立一个类,作为画实时曲线 Option Explicit Public pCurveNUM As Integer Public pCurveName As String Public
27、 pCurveMax As Double Public pCurvemin As Double e 其 实 我 真 的 叫 迪 米 亚 路 等级: 可用分等级:中农 总技术分:1658 总技术分排名:12870 Private pricCurve As PictureBox Private priCurvePoint(6) As Integer Private priCurveData(6) As Double Private priDrawY0(6) As Double Private priDrawY1(6) As Double Private priDrawNMinute As Inte
28、ger Private priDrawTMinute As Integer Private WithEvents priTimerDraw As Timer Public Property Let ltDrawTimer(ByRef lTimer As Timer) Set priTimerDraw = lTimer End Property Public Property Let ltGiveCurveData(ByVal lDataPoint As Variant) Dim i% For i = 1 To pCurveNUM priCurvePoint(i) = CInt(lDataPoi
29、nt(i) Next End Property Public Property Let ltGetPicture(ByRef lDrawPicBox As PictureBox) Set pricCurve = lDrawPicBox End Property Private Sub sDrawTheRealTimeCurve() Dim ypixels, xpixels, i% Dim ShowMode As Long, ii As Long, tm As String, hBmp As Long pricCurve.DrawWidth = 1 hBmp = pricCurve.hDC Sh
30、owMode = &HCC0020 ii = BitBlt(hBmp, 0, 0, pricCurve.ScaleWidth - 1, pricCurve.ScaleHeight - 1, hBmp, 1, 0, ShowMode) Dim T As Integer T = Minute(Now() priDrawNMinute = T If priDrawNMinute priDrawTMinute Then pricCurve.CurrentX = pricCurve.ScaleWidth - 19 pricCurve.CurrentY = pricCurve.ScaleHeight -
31、11 pricCurve.Print priDrawNMinute End If priDrawTMinute = priDrawNMinute pricCurve.ScaleMode = vbPixels ypixels = pricCurve.ScaleHeight - 1 xpixels = pricCurve.ScaleWidth - 1 For 1 to 6 curves If pCurveNUM 6 Or pCurveNUM 1 Then pricCurve.Line (xpixels - 1, priDrawY0(2)-(xpixels - 1, priDrawY1(2), vb
32、White If pCurveNUM 2 Then pricCurve.Line (xpixels - 1, priDrawY0(3)-(xpixels - 1, priDrawY1(3), vbGreen If pCurveNUM 3 Then pricCurve.Line (xpixels - 1, priDrawY0(4)-(xpixels - 1, priDrawY1(4), spColor(3).FillColor If pCurveNUM 4 Then pricCurve.Line (xpixels - 1, priDrawY0(5)-(xpixels - 1, priDrawY1
33、(5), spColor(4).FillColor If pCurveNUM 5 Then pricCurve.Line (xpixels - 1, priDrawY0(6)-(xpixels - 1, priDrawY1(6), spColor(5).FillColor For i = 1 To 6 priDrawY0(i) = priDrawY1(i) Next End Sub Public Sub clsInit() Dim i% For i = 1 To 6 priDrawY0(i) = pricCurve.Height priDrawY1(i) = pricCurve.Height Next