網上有很多關于ok卡官網支持的pos機器,三菱PLC的MC通信協(xié)議分析和實現(xiàn)的知識,也有很多人為大家解答關于ok卡官網支持的pos機器的問題,今天pos機之家(www.tjfsxbj.com)為大家整理了關于這方面的知識,讓我們一起來看下吧!
本文目錄一覽:
ok卡官網支持的pos機器
大家好,今天我來說一下上位機與三菱PLC的通信協(xié)議MC協(xié)議。
MC協(xié)議概述官方的定義:MC通訊協(xié)議,就是對方設備通過C24或者E71模塊與PLC 的CPU軟元件數(shù)據(jù)和程序的讀出/寫入PLC用的通訊方式的名稱。
以上聽得拗口,口語化表達的意思就是:PC電腦通過C24模塊或者E71模塊,按照一定的數(shù)據(jù)格式,讀寫PLC軟元件的過程。
在三菱PLC的通訊設置端,如下圖所示,通信協(xié)議設置中有很多種類型。第一種是無順序協(xié)議,這是直接通過TCP/UDP發(fā)送數(shù)據(jù)給PC上位機端,上位機也只直接發(fā)送數(shù)據(jù),這種情況下PLC要去解析數(shù)據(jù)格式,相對來說比較麻煩, 我只做過與松下PLC直接按照無協(xié)議通訊做過項目,對方的工程師調試這個無協(xié)議搞了一周,比較繁瑣,不推薦使用。
GX Developer 設置MC協(xié)議
還有就是MC協(xié)議,我寫的程序是參考《Q系列MELSEC通訊協(xié)議參考手冊(中文).pdf》寫的,協(xié)議可以參見我CSDN博客中https://download.csdn.net/download/yangchuang1992/10911284
MC協(xié)議類型表格
對象模塊中C24代表串口(RS232 RS485),E71代表網口通信,這個要看具體的PLC那端通信是串口還是網口。串口 通訊幀(數(shù)據(jù)格式)有四種,QnA兼容3C幀,QnA兼容4C幀,QnA兼容2C幀,A兼容1C幀,形式對應著1~5,對應著PLC中就是上上圖中的下拉列表中的格式1到5。數(shù)據(jù)格式有ASCII代碼和二進制代碼,那上面最多可以組合出10種通訊格式, 那是不是我們都要實現(xiàn)呢?
QnA兼容3C幀、QnA兼容4C幀、QnA兼容3E幀可以訪問Q/QnA PLC CPU 全部軟元件和全部文件。
QnA兼容2C幀,可以訪問QnA PLC CPU軟元件和全部文件
A 兼容 1C 幀 A 兼容 1E 幀 ,可以訪問QnA PLC CPU軟元件和全部文件
綜上,我們串口使用QnA兼容3C幀,網口QnA兼容3E幀,可以覆蓋Q/QnA系列的PLC讀取。
我這里只說寄存器D的讀寫操作
ASCII模式如下1. 串口QnA兼容3C幀格式(格式1,2,3,4都行),使用格式3來讀寄存器說明報文
由于串口數(shù)據(jù)不能一次性發(fā)送,數(shù)據(jù)是分多次發(fā)送的, 所以一個完整的幀數(shù)據(jù)有起始和結尾符標記, STX =0X02 表示開始 ETX=0X03表示結尾符, 代表一幀數(shù)據(jù)完成。
寫入PLC報文
要注意這里的寄存器編號要是6位,不足補0, 讀取個數(shù)是十六進制表示
正?;貜停?/p>
正常返回報文
其中,數(shù)據(jù)部分有大小端區(qū)分,如果數(shù)據(jù)超過了65535,就要用2個字表示,高低位要互換
異常回復:
異常返回報文
其中出錯編碼可以在PLC相關手冊中查詢。
使用格式3來寫寄存器寫說明報文
上位機寫入數(shù)據(jù):
寫入PLC數(shù)據(jù)報文
正常返回:
寫入正常報文
異常返回:
2.QnA 兼容 3E 幀讀數(shù)據(jù):
讀數(shù)據(jù)報文
正常返回
正常返回報文
異常返回
寫數(shù)據(jù):
寫數(shù)據(jù)報文
正常返回
正常返回報文
異常返回
異常返回報文
/// 讀取的數(shù)據(jù)
private int ReadMitNWord(string strIoName, int nNum, ref string result)
{
int nRet = PLCReturn.PLC_OK;
if (null == _Connection)
throw new Exception("PLC連接對象位null");
string sendData = "";
if (_Connection.ConnectType() == "COM")
{
sendData = string.Format("{0}{1}0000D*{2}{3:X4}{4}", GetHeader(), Type.Read, strIoName, nNum, (char)0x03);
}
else if (_Connection.ConnectType() == "TCP")
{
sendData = string.Format("{0}00180010{1}0000D*{2}{3:X4}", GetHeader(), Type.Read, strIoName, nNum);
}
//發(fā)送報文
_Connection.SendData(sendData);
//接收報文-->內部已經有1秒超時
string recvData = _Connection.GetResponse(1000);
if (!string.IsNullOrEmpty(recvData))
{
//去掉末尾多余的 \\0
recvData = recvData.TrimEnd(\'\\0\');
byte[] redvBytes = Encoding.ASCII.GetBytes(recvData);
if (_Connection.ConnectType() == "COM")
{
if (recvData.Contains("QACK")) //正常結束
{
}
else if (recvData.Contains("QNAK"))//異常結束
{
//截取數(shù)據(jù)
result = recvData.Substring(14);
nRet = PLCReturn.PLC_ERR;
}
}
else if (_Connection.ConnectType() == "TCP")
{
string resultCOde = recvData.Substring(18, 4);
if (resultCOde.Contains("0000")) //正常結束
{
//獲取數(shù)據(jù)部分
nRet = PLCReturn.PLC_OK;
result = recvData.Substring(22);
}
else//異常結束
{
nRet = PLCReturn.PLC_ERR;
}
}
}
else
{
nRet = PLCReturn.PLC_TIMEOUT;
}
return nRet;
}
//寫入
private void WriteMitNWord(string strIoname, int nNum, string data)
{
if (null == _Connection)
throw new Exception("PLC連接對象位null");
string sendData = "";
if (_Connection.ConnectType() == "COM")
{
sendData = string.Format("{0}{1}0000D*{2}{3:X3}{4}", GetHeader(), Type.Write, strIoname, nNum, data);
}
else if (_Connection.ConnectType() == "TCP")
{
int dataLength = 24 + nNum * 4;
sendData = string.Format("{0}{1:X4}0010{2}0000D*{3}{4:X4}{5}", GetHeader(), dataLength, Type.Write, strIoname, nNum, data);
}
//發(fā)送數(shù)據(jù)
_Connection.SendData(sendData);
string recvData = _Connection.GetResponse(1000);
if (!string.IsNullOrEmpty(recvData))
{
if (_Connection.ConnectType() == "COM")
{
if (recvData.Contains("QACK"))//成功
{
}
else if (recvData.Contains("QNAK"))//異常
{
}
}
else if (_Connection.ConnectType() == "TCP")
{
string resultCOde = recvData.Substring(18, 21);
if (resultCOde.Contains("0000")) //正常結束
{
//獲取數(shù)據(jù)部分
}
else//異常結束
{
}
}
}
}
我以寫入PLC位置為例子,結構體PlcDefine.PlcPfPos是x,y,z坐標:
public int SetPfMovePos(int nPfNo, PlcDefine.PlcPfPos pos)
{
int nRet = PLCReturn.PLC_OK;
if (pos.Angle < 0)
pos.Angle = pos.Angle + 360;
if (pos.Angle >= 360)
pos.Angle = pos.Angle - 360;
string strIOName = string.Format("{0:D6}", 6020);
int nX = (int)(pos.X * 10000);
int nY = (int)(pos.Y * 10000);
int nA = (int)(pos.Angle * 100000);
//轉換數(shù)據(jù)
string strData = string.Empty;
strData += Invert2Word(string.Format("{0:X8}", nX));
strData += Invert2Word(string.Format("{0:X8}", nY));
strData += Invert2Word(string.Format("{0:X8}", nA));
WriteMitNWord(strIOName, 6, strData);
return nRet;
}
以上就是關于ok卡官網支持的pos機器,三菱PLC的MC通信協(xié)議分析和實現(xiàn)的知識,后面我們會繼續(xù)為大家整理關于ok卡官網支持的pos機器的知識,希望能夠幫助到大家!
