这两天帮老爸干个活儿。。写个程序去读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);
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();
}
}
}
求各位大神不吝指教!多谢!
------解决思路----------------------
你得明白一点计算机的基础知识:
二进制才是所有数据的基础,不要随便转为字符串。
你收发的都是byte[], 你直接处理byte,不要用asciiEncoding.GetString();
这种 string check = "6C"肯定也不对,
应该是类似这样的: byte c = 0x6c ;
------解决思路----------------------
所以先让你用串口调试助手测试,先把发什么,收什么,都代表什么意思,弄弄清楚
然后再研究如何用代码去实现这个过程
不要一开始就纠结代码
等调试代码的时候,完全可以抛开PLC了,只要你发送出去的跟用调试助手发出去的一样,接收到的也能正确解析,把代码直接连PLC保证也是好使的