目录
一、背景
Tag读写为单次请求与应答场景的功能,用于解决频次不高,单次查询,更改从站数据的需求。
二、可行性分析
用Eip Scanner Demo与PLC进行Tag读写测试,并抓取报文分析
WireShark报文及Eip Scanner Demo的界面,可以看到读到了3个字节,最后一个字节为0x65,与PLC内部数据一致。
PLC内部的数据显示:要读取的Tag绝对路径为Application.PLC_PRG.Sum
从报文看,Eip Scanner Demo主要有两个动作
1、Enip
2、读Tag
在确认之前,需要先验证Eip Scanner Demo在有生产者连接的前提下,读写Tag是否正常。得到验证的报文与视频如下:
1、Enip
2、ForwardOpen建立生产者连接,进行IO通讯
3、随机读Tag
4、ForwardCloss关闭生产者连接
经过验证,Eip ScannerDemo的方案可满足要求,采用此方案。
三、开发调试
针对Tag读写的三个场景,分别设计不同返回类型的方法,通过重载实现。
其中有个底层共用功能:将字符串组织成报文。单独写个方法实现。
将读的功能统一返回为vector类,再通过不同的功能场景解析出对应数据。
于是TagMess.h为:
class TagMess{
public:
TagMess();
~TagMess();
uint8_t readTagUint8(std::string tagMesStr);
float readTagFloat(std::string tagMesStr);
//bool readTagBool(std::string tagMesStr);
bool writeTagUint8(std::string tagMesStr,uint8_t value);
bool writeTagFloat(std::string tagMesStr,float value);
bool writeTagBool(std::string tagMesStr,bool value);
private:
std::vector<uint8_t> readTag(std::string tagMesStr);
bool WriteTag(std::string tagMesStr,bool value);
bool WriteTag(std::string tagMesStr,uint8_t value);
bool WriteTag(std::string tagMesStr,float value);
void strMessSolve(std::string tagMesStr);
//tag报文
std::vector<uint8_t> tagDataToprotocolFormat;
//str输入的解析
std::vector<uint8_t> strToTagData;
};
需要注意:在Tag的string转化成报文过程中,如Application.GVL_Enet_Master.Master_left_shoulder_pitch_joint.MotorRunMode。
最后一个字符串MotorRunMode若字符数为奇数,则补个0x00。
验证的代码如下:
int main() {
Logger::setLogLevel(LogLevel::DEBUG);
std::string U8TagStr="Application.PLC_PRG.TagU8";
std::string FlTagStr="Application.PLC_PRG.TagFl";
std::string BlTagStr="Application.PLC_PRG.TagBl";
TagMess tagTest;
//read U8
Logger(LogLevel::INFO)<<"Read Tag uint8_t";
uint8_t U8=tagTest.readTagUint8(U8TagStr);
Logger(LogLevel::INFO)<<"TagU8 is :"<<(int)U8;
//write U8
Logger(LogLevel::INFO)<<"Write Tag uint8_t";
bool result=tagTest.writeTagUint8(U8TagStr,3);
Logger(LogLevel::INFO)<<"TagU8 write :"<<std::boolalpha<<result;
//read FL
Logger(LogLevel::INFO)<<"Read Tag float";
float FL=tagTest.readTagFloat(FlTagStr);
Logger(LogLevel::INFO)<<"TagFl is :"<<FL;
//write FL
Logger(LogLevel::INFO)<<"Write Tag float";
result=tagTest.writeTagFloat(FlTagStr,3.15);
Logger(LogLevel::INFO)<<"TagFl write :"<<std::boolalpha<<result;
//read BL
Logger(LogLevel::INFO)<<"Read Tag Bool";
result=tagTest.readTagUint8(BlTagStr);
Logger(LogLevel::INFO)<<"TagBl write :"<<std::boolalpha<<result;
//write BL
Logger(LogLevel::INFO)<<"Write Tag Bool";
result=tagTest.writeTagBool(BlTagStr,1);
Logger(LogLevel::INFO)<<"TagBl write :"<<std::boolalpha<<result;
return EXIT_SUCCESS;
}
运行输出的log如下:
[INFO] Read Tag uint8_t
[DEBUG] Opened TCP socket fd=3
Local Port is20675
[DEBUG] Connecting to 192.168.2.88:44818
[INFO] Registered session 42351796
[INFO] Unregistered session 42351796
[DEBUG] Close TCP socket fd=3
[INFO] TagU8 is :3
[INFO] Write Tag uint8_t
[DEBUG] Opened TCP socket fd=3
Local Id and Port bind Err20675
[DEBUG] Connecting to 192.168.2.88:44818
[INFO] Registered session 58787944
[INFO] Unregistered session 58787944
[DEBUG] Close TCP socket fd=3
[INFO] TagU8 write :true
[INFO] Read Tag float
[DEBUG] Opened TCP socket fd=3
Local Id and Port bind Err20675
[DEBUG] Connecting to 192.168.2.88:44818
[INFO] Registered session 75151796
[INFO] Unregistered session 75151796
[DEBUG] Close TCP socket fd=3
[INFO] TagFl is :3.15
[INFO] Write Tag float
[DEBUG] Opened TCP socket fd=3
Local Id and Port bind Err20675
[DEBUG] Connecting to 192.168.2.88:44818
[INFO] Registered session 91580198
[INFO] Unregistered session 91580198
[DEBUG] Close TCP socket fd=3
[INFO] TagFl write :true
[INFO] Read Tag Bool
[DEBUG] Opened TCP socket fd=3
Local Id and Port bind Err20675
[DEBUG] Connecting to 192.168.2.88:44818
[INFO] Registered session 7947923
[INFO] Unregistered session 7947923
[DEBUG] Close TCP socket fd=3
[INFO] TagBl write :false
[INFO] Write Tag Bool
[DEBUG] Opened TCP socket fd=3
Local Id and Port bind Err20675
[DEBUG] Connecting to 192.168.2.88:44818
[INFO] Registered session 24387944
[INFO] Unregistered session 24387944
[DEBUG] Close TCP socket fd=3
[INFO] TagBl write :true
wireshark报文如下:
此系列的b站视频见:
基于EIPScanner的Linux Ethernet/IP的多生产者连接及Tag读写实现分享(一 引言)_哔哩哔哩_bilibili
参考代码见:
咸鱼ID:tb764914262