实验采用带模拟量,分辨率为1-5V,量程为0--101kpa的真空表
数据采集模块采用DAM-8021, 16位模块
算法描述如下:
真空表读数范围: 0到-101kpa
模拟量输出: 1-5V
一次AD数据采集结果为(由串口助手取得): >+03.921-00.000
此时真空表读数: 74.2
则系数A=(3.921-1)/74.2=0.0393
真空表模拟量输出修正系数: 是指真空表模拟量输出的偏差.
其取得方法为, 将真空去掉,让真空表读数为零, 读一次AD采样的结果, 例如其值为+00.981-00.000, 因为这个真空表的最小模拟量值为1, 因此误差为0.019
AD采样转换结果= (当前AD采样值-1+真空表模拟量输出修正系数)/系数A
为什么要当前AD采样值减1? 这个笔者也不好理解, 经过实验证明确实如此. 也许是真空表是1-5V, 而不是0-5V的原因? 如果有朋友知道为什么, 谢谢回贴指导下笔者.
按上面的示例结果, AD数据采集结果为>+03.921-00.000
则 AD采样转换结果= (3.921-1+0.019) /0.0393= 74.8 , 因为是举的例子, 其真空表模拟量输出修正系数不是现场真实的值,因此计算结果不是74.2, 这里我只是说明计算方法而已.
下面附上代码:
1 using System; 2 using System.Collections.Generic; 3 using System.ComponentModel; 4 using System.Data; 5 using System.Drawing; 6 using System.Linq; 7 using System.Text; 8 using System.Windows.Forms; 9 using System.Threading; 10 11 namespace test1 12 { 13 //http://www.cnblogs.com/hackpig/ 猪悟能‘s博客 14 15 public partial class Form1 : Form 16 { 17 Thread myThread2; 18 private bool PlcMonitorProcEndFlag = false; 19 bool f1 = false; 20 21 public Form1() 22 { 23 InitializeComponent(); 24 CheckForIllegalCrossThreadCalls = false; 25 } 26 27 string oldstr = string.Empty; 28 private void serialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e) 29 { 30 string data = serialPort1.ReadExisting(); 31 bool f2=false; 32 try 33 { 34 if (data.Length == 8) f2 = true; 35 string[] ary1 = data.Split(‘-‘); 36 string s1=string.Empty; 37 if (f2 || ary1.Length == 4) 38 { 39 f1 = true; 40 if (f2) 41 s1 = data.Substring(1, data.Length - 1); 42 else 43 s1 = ary1[0].Substring(1, ary1[0].Length - 1); 44 double v1 = double.Parse(s1); 45 46 double xs = 0.0396f;// 0396f; 47 48 /* 49 真空表读数范围: 0到-101kpa 50 模拟量输出: 1-5V 51 52 示例: 模量量结果, >+03.921-00.000 53 * 真空表读数, 74.2 54 则xs=(3.921-1)/74.2=0.0393 55 * 56 将真空去掉,让真空表读数为零, 读一次模拟输出, 其值为+00.981-00.000, 因为正常值为1, 因此误差为0.019 57 这个值在加到变量v1上去. 58 */ 59 60 v1 = v1 - 1 + 0.019; 61 v1 = v1 /xs; 62 this.textBox1.Text = v1.ToString("0.00000"); 63 64 string newstr = s1 + ": " + v1.ToString("0.00000") + Environment.NewLine; 65 if(!newstr.Equals(oldstr)) 66 this.richTextBox1.AppendText(newstr); 67 68 oldstr = newstr; 69 70 if (this.richTextBox1.Text.Length > 50000) this.richTextBox1.Text = ""; 71 72 } 73 } 74 catch (Exception e1) 75 { 76 f1 = false; 77 } 78 f1 = false; 79 } 80 81 private void Form1_Load(object sender, EventArgs e) 82 { 83 try 84 { 85 serialPort1.Open(); 86 } 87 catch 88 { 89 MessageBox.Show("port2 dont‘t open"); 90 Environment.Exit(-1); 91 } 92 myThread2 = new Thread(new ThreadStart(PlcMonitorProc)); 93 myThread2.Start(); 94 } 95 96 private void PlcMonitorProc() 97 { 98 while (!PlcMonitorProcEndFlag) 99 { 100 if (!f1) 101 { 102 serialPort1.Write("#01" + Environment.NewLine); 103 Thread.Sleep(50); 104 } 105 } 106 PlcMonitorProcEndFlag = false; 107 } 108 109 private void Form1_FormClosing(object sender, FormClosingEventArgs e) 110 { 111 PlcMonitorProcEndFlag = true; 112 myThread2.Join(); 113 } 114 115 private void stop_Click(object sender, EventArgs e) 116 { 117 PlcMonitorProcEndFlag = true; 118 } 119 120 private void textBox1_TextChanged(object sender, EventArgs e) 121 { 122 123 } 124 125 private void richTextBox1_TextChanged(object sender, EventArgs e) 126 { 127 128 } 129 130 } 131 }
DAM8021, DAM8041这样的AD采集模块, 支持485接口, 因此可以直接用串口助手发送指令的方式取得测量结果, 相比9111卡那样的AD采集板卡, 还需要插入电脑主机槽中并且要装驱动程序, 是方便很多.
这种卡只需要IPC用串口发送字符串 "#01" 就可以取01通道的采集结果.
经用上面代码采集的数据, 跟真空表读数是完全一致的.
下面是采集的一组数据:
AD采样值 AD值计算出的真空值 真空表实际值