C#读取三菱FX PLC

FTD_Fred 2014-12-28 09:53:55
这两天帮老爸干个活儿。。写个程序去读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();
}
}






}


求各位大神不吝指教!多谢!
...全文
994 15 打赏 收藏 转发到动态 举报
写回复
用AI写文章
15 条回复
切换为时间正序
请发表友善的回复…
发表回复
埃和智能 2017-08-26
  • 打赏
  • 举报
回复
高级语言和三菱PLC通讯的资料这里最全了: http://blog.sina.com.cn/s/blog_16d7d3ecb0102x6wj.html
埃和智能 2017-04-21
  • 打赏
  • 举报
回复
这个有封装好的类,函数齐全,功能完善: http://www.ymmfa.com/read-gktid-1578771.html
lzjing1984 2016-10-08
  • 打赏
  • 举报
回复
大牛啊,大牛啊,大牛
FTD_Fred 2015-01-01
  • 打赏
  • 举报
回复
引用 8 楼 rtdb 的回复:
你得明白一点计算机的基础知识: 二进制才是所有数据的基础,不要随便转为字符串。 你收发的都是byte[], 你直接处理byte,不要用asciiEncoding.GetString(); 这种 string check = "6C"肯定也不对, 应该是类似这样的: byte c = 0x6c ;
引用 10 楼 Z65443344 的回复:
[quote=引用 7 楼 FTD_Fred 的回复:] 昨天调试了一下,发现可能是跟16进制数的字母有关系,发送ABCDEF的时候就出错了,那么问题来了,如何发送16进制数中的字母?
所以先让你用串口调试助手测试,先把发什么,收什么,都代表什么意思,弄弄清楚 然后再研究如何用代码去实现这个过程 不要一开始就纠结代码 等调试代码的时候,完全可以抛开PLC了,只要你发送出去的跟用调试助手发出去的一样,接收到的也能正确解析,把代码直接连PLC保证也是好使的[/quote] 多谢两位,这几天好好看了一下相关的知识,已经解决了,谢谢~另外新年快乐,分数不多接好~
rtdb 2014-12-30
  • 打赏
  • 举报
回复
你得明白一点计算机的基础知识: 二进制才是所有数据的基础,不要随便转为字符串。 你收发的都是byte[], 你直接处理byte,不要用asciiEncoding.GetString(); 这种 string check = "6C"肯定也不对, 应该是类似这样的: byte c = 0x6c ;
FTD_Fred 2014-12-30
  • 打赏
  • 举报
回复
昨天调试了一下,发现可能是跟16进制数的字母有关系,发送ABCDEF的时候就出错了,那么问题来了,如何发送16进制数中的字母?
於黾 2014-12-30
  • 打赏
  • 举报
回复
遇到问题学会分解,先把其中一个步骤弄明白,不要眉毛胡子一把抓,都不知道问题大约出在哪里
於黾 2014-12-30
  • 打赏
  • 举报
回复
引用 7 楼 FTD_Fred 的回复:
昨天调试了一下,发现可能是跟16进制数的字母有关系,发送ABCDEF的时候就出错了,那么问题来了,如何发送16进制数中的字母?
所以先让你用串口调试助手测试,先把发什么,收什么,都代表什么意思,弄弄清楚 然后再研究如何用代码去实现这个过程 不要一开始就纠结代码 等调试代码的时候,完全可以抛开PLC了,只要你发送出去的跟用调试助手发出去的一样,接收到的也能正确解析,把代码直接连PLC保证也是好使的
老张一笑 2014-12-30
  • 打赏
  • 举报
回复
给老爸干活,代码写得就是那么任性. 支持3楼,先拿串口调试工具,测试没问题. 本身串口通讯不难,较复杂的是协议的解析
FTD_Fred 2014-12-29
  • 打赏
  • 举报
回复
引用 4 楼 FTD_Fred 的回复:
[quote=引用 3 楼 Z65443344 的回复:] 你先用串口调试助手,看能否得到数据,如果也不能,说明你PLC里没定义D205之后的地址要从串口输出,需要把它映射给串口 然后你再把你的程序放一台电脑上运行,串口接另一台电脑的串口,运行串口调试助手,看接收到的到底是什么东西,好确定到底是发送错误还是接收错误
之前PLC已经在D200-D208里面放入了1-9了,应该不是地址的问题 如果再接到串口的话看来得买一根线了,晚上试试看,多谢 是不是我电脑接到PLC上,打开串口调试助手是接受不到数据的?[/quote] OK,现在对这东西有一些基本的概念了,之前想的太简单了,多谢大神,希望晚上回家能调试成功!
於黾 2014-12-29
  • 打赏
  • 举报
回复
要看你的PLC编程是主动发送还是被动接收(主站还是从站) 如果是主动发送,你串口调试助手只要打开串口就有数据不断的发送过来 如果是从站,你需要用串口调试助手将指令发给PLC,然后看收到的是什么 D区有没有数据跟你串口有没有响应是完全两个概念 D区你不设置1-9,它也是客观存在的,只不过里面的数据是0而已 而你串口到底绑定哪些地址是需要设置的,并不是什么都不用做就能从串口读到任何数据的
FTD_Fred 2014-12-29
  • 打赏
  • 举报
回复
引用 3 楼 Z65443344 的回复:
你先用串口调试助手,看能否得到数据,如果也不能,说明你PLC里没定义D205之后的地址要从串口输出,需要把它映射给串口 然后你再把你的程序放一台电脑上运行,串口接另一台电脑的串口,运行串口调试助手,看接收到的到底是什么东西,好确定到底是发送错误还是接收错误
之前PLC已经在D200-D208里面放入了1-9了,应该不是地址的问题 如果再接到串口的话看来得买一根线了,晚上试试看,多谢 是不是我电脑接到PLC上,打开串口调试助手是接受不到数据的?
於黾 2014-12-29
  • 打赏
  • 举报
回复
你先用串口调试助手,看能否得到数据,如果也不能,说明你PLC里没定义D205之后的地址要从串口输出,需要把它映射给串口 然后你再把你的程序放一台电脑上运行,串口接另一台电脑的串口,运行串口调试助手,看接收到的到底是什么东西,好确定到底是发送错误还是接收错误
FTD_Fred 2014-12-29
  • 打赏
  • 举报
回复
没人关注么……求大神解答
FTD_Fred 2014-12-29
  • 打赏
  • 举报
回复
快上班了,自己占个沙发

110,539

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧