这两天帮老爸干个活儿。写个程序去读PLC里面的数据
端口设置如下:
SerialPort com = new SerialPort(“COM4”, 9600, Parity.Even, 7, StopBits.One);
从D200开始读,读9个数据,感觉这东西还不算难。
在论坛里找了找,有收获,写了测试
发现,D200-D204读取正常,D205读取就会返回15H(接收错误),不知道为什么,求高手指点!
附程序
端口设置如下:
SerialPort com = new SerialPort(“COM4”, 9600, Parity.Even, 7, StopBits.One);
从D200开始读,读9个数据,感觉这东西还不算难。
在论坛里找了找,有收获,写了测试
发现,D200-D204读取正常,D205读取就会返回15H(接收错误),不知道为什么,求高手指点!
附程序
SerialPort com = new SerialPort("COM4", 9600, Parity.Even, 7, StopBits.One); string[] po = new string[9];//读取指令 string[] check = new string[9];//校验位 public int[] apb = new int[9];//amount per box,每箱件数 private void FirstUse() { if (com.IsOpen) { com.Close(); } com.Open(); } public static string Chr(int asciiCode) { if (asciiCode >= 0 && asciiCode <= 255) { System.Text.ASCIIEncoding asciiEncoding = new System.Text.ASCIIEncoding(); byte[] byteArray = new byte[] { (byte)asciiCode }; string strCharacter = asciiEncoding.GetString(byteArray); return (strCharacter); } else { throw new Exception("ASCII Code is not valid."); } } private void Form1_Load(object sender, EventArgs e) { po[0] = "0119002"; po[1] = "0119202"; po[2] = "0119402"; po[3] = "0119602"; po[4] = "0119802"; po[5] = "0119A02"; po[6] = "0119C02"; po[7] = "0119E02"; po[8] = "011A002"; check[0] = "60"; check[1] = "62"; check[2] = "64"; check[3] = "66"; check[4] = "68"; check[5] = "6A"; check[6] = "6C"; check[7] = "6E"; check[8] = "61"; FirstUse(); } private void 刷新ToolStripMenuItem_Click(object sender, EventArgs e) { //string sReadData = ""; for (int i = 0; i <= 8; i++) { this.txtRead0.Text=""; string sReadCmd = Chr(2) + po[i] + Chr(3) + check[i]; //string sReadCmd = "2" + po[i] + "3" + check[i]; com.Write(sReadCmd); //等待1秒钟 System.Threading.Thread.Sleep(1000); // 从串口读数据 byte[] data = new byte[1024]; try { int j=com.Read(data, 0, 1024); } catch (Exception eg) { MessageBox.Show(eg.ToString()); } //假如首位为2,则表示数据有效.这里有个问题,在第二次读,第2位才为"2",第三次又是首位为2,需要再测试 if (data[0] == 2) { string sReceiveData = System.Text.Encoding.ASCII.GetString(data); //MessageBox.Show(sReceiveData); //解析命令,将读到的字符解析成数字,注意高低位的转换 string sLow = sReceiveData.Substring(1, 2); //string sHigh = sReceiveData.Substring(3, 2); //int res = Convert.ToInt32(sHigh)+ Convert.ToInt32(sLow); int res = Convert.ToInt32(sLow, 16); //+ Convert.ToInt32(sHigh, 16); this.txtRead0.Text = res.ToString(); string temp=(int.Parse(txtRead0.Text)*apb[i]).ToString(); switch (i) { case 0: { tb13.Text = txtRead0.Text; tb14.Text = temp; break; } case 1: { tb23.Text = txtRead0.Text; tb24.Text = temp; break; } case 2: { tb33.Text = txtRead0.Text; tb34.Text = temp; break; } case 3: { tb43.Text = txtRead0.Text; tb44.Text = temp; break; } case 4: { tb53.Text = txtRead0.Text; tb54.Text = temp; break; } case 5: { tb63.Text = txtRead0.Text; tb64.Text = temp; break; } case 6: { tb73.Text = txtRead0.Text; tb74.Text = temp; break; } case 7: { tb83.Text = txtRead0.Text; tb84.Text = temp; break; } case 8: { tb93.Text = txtRead0.Text; tb94.Text = temp; break; } } } else { i--; com.Close(); com.Open(); } } }
求各位高手不吝指点!多谢!
解决方案
10
你得明白一点计算机的基础知识:
二进制才是全部数据的基础,不要随便转为字符串。
你收发的都是byte[], 你直接处理byte,不要用asciiEncoding.GetString();
这种 string check = “6C”肯定也不对,
应该是相似这样的: byte c = 0x6c ;
二进制才是全部数据的基础,不要随便转为字符串。
你收发的都是byte[], 你直接处理byte,不要用asciiEncoding.GetString();
这种 string check = “6C”肯定也不对,
应该是相似这样的: byte c = 0x6c ;
30
所以先让你用串口调试助手测试,先把发什么,收什么,都代表什么意思,弄弄清楚
然后再研究怎么样用代码去实现这个过程
不要一开始就纠结代码
等调试代码的时候,完全可以抛开PLC了,只要你发送出去的跟用调试助手发出去的一样,接收到的也能正确解析,把代码直接连PLC保证也是好使的