西门子S7通讯——基于Snap7

2024-04-28 18:44
文章标签 通讯 西门子 s7 snap7

本文主要是介绍西门子S7通讯——基于Snap7,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

0.环境配置

0.0 下载 Snap源码:

官网地址:https://snap7.sourceforge.net/
这里我下载的 1.4.2/snap7-full-1.4.2.7z 。

0.1 库编译与安装

这里我使用的是 x86 架构下的 Unbuntu 64 位系统,如果使用其他系统,请根据实际情况调整。

  • 解压并进入源码文件目录下,这里解压出来的文件名称为:snap7-full-1.4.2
  • 编译并安装sanp7库
sudo make -f x86_64_linux.mk clean
sudo make -f x86_64_linux.mk all
sudo make -f x86_64_linux.mk install
  • 将 .h 、.cpp 和库文件拷贝到程序依赖文件目录
    • 1.3.1 库文件路径位于:./snap7-full-1.4.2/build/bin/x86_64-linux/libsnap7.so
    • 1.3.2 .h 与 .cpp 路径: ./snap7-full-1.4.2/examples/cpp/snap7.h 和 ./snap7-full-1.4.2/examples/cpp/snap7.cpp

1.连接PLC

此处需要在博图软件中,查询到PLC所配置的网络的地址,并将电脑配置到同一网段。此外还需要获知所需读写的PLC的机架号与槽号,连接时需要用到。

/* RemAddress: PLC IP 地址* Rack: PLC 机架号* slot: PLC 槽号*/
int ConnectTo(const char *RemAddress, int Rack, int Slot);
// 示例
TS7Client *client_ = new TS7Client();
int result = 0;
if((result = client_->ConnectTo(PLC_IP, PLC_RACK_NUMBER, PLC_SLOT_NUMBER) != 0)) {std::cerr << "Connect PLC Error ! err msg : "<< CliErrorText(result).data() << std::endl;
}

2. 读写操作

2.1 使用DBRead读写
  • 读取一个bool值
/*	DBNumber:DB 区编号*	Start:起始地址*	Size:读取的字节数,最少读取一个字节。*	*pUsrData 存储数据的变量指针。*/
int DBRead(int DBNumber, int Start, int Size, void *pUsrData);
// 在读取完成后,需要手动进行位运算,其中低位为x.0。
bool value = false;
unsigned char data;
client_->DBRead(66, 0, 1, &data);
value = ((data >> 3) & 1);
  • 写一个bool值
/*	DBNumber:DB 区编号- Start:起始地址- Size:写入的字节数,最少写入一个字节。- *pUsrData 存储数据的变量指针。*/
int DBWrite(int DBNumber, int Start, int Size, void *pUsrData)
// 在读取完成后,需要手动进行位运算,其中低位为x.0。
bool value = false;
unsigned char data;
data = value > 0 ? (data | (value << 3)) : (data & (~(value << 3)));
client_->DBWrite(66, 0, 1, &data);

此外,还有MBRead、MBWrite、EBRead、EBWrite等等,使用方法上除了无需传入DBNumber外相同。

2.2 使用 ReadArea 与 WriteArea 进行读写操作

相较于 DBRead 和 DBWrite 等函数接口,使用 ReadArea 和 WriteArea 的可操作行更高。从源码中看,实际上 DBRead 和 DBWrite 等函数接口也均是基于 ReadArea 和 WriteArea 进行封装的。

  • ReadArea 数据块读取
/** Area : 数据块类型,需根据snap7.h中定义的 Area ID 输入- DBNumber:DB 区编号- Start:起始地址- Amount:需要读取的 WordLen 数量- WordLen:pUsrData 中的字节长度,需要使用根据snap7.h中定义的 Word Length 输入。- *pUsrData 存储数据的变量指针**/
int WriteArea(int Area, int DBNumber, int Start, int Amount, int WordLen, void *pUsrData)
// 示例
unsigned char data[sizeof(float)];
float read_real = 0.0f ;
int result = 0;if((result = client_->ReadArea(S7AreaDB, 66, 0x400, sizeof(float), S7WLByte, &data) != 0){std::cerr << "Read PLC area fail, error code : " << CliErrorText(result).data() << std::endl;
}// 数据端序转换 !!!
for (int i = 0; i < sizeof(float); i++) {*((unsigned char*)read_real + i) = data[sizeof(float) - i - 1];
}std::count << "Read real : " << read_real << std::endl;
  • WriteArea 数据块写入
unsigned char data[sizeof(float)];
float read_real = 666.66f ;
int result = 0;for (int i = 0; i < sizeof(float); i++) {data[sizeof(float) - 1 - i] = *((unsigned char*)read_real + i);
}if((result = client_->WriteArea(S7AreaDB, 66, 0x400, sizeof(float), S7WLByte, &data) != 0){std::cerr << "Read PLC area fail, error code : " << CliErrorText(result).data() << std::endl;
}std::count << "Read real : " << read_real << std::endl;

注意:
1、当 WordLen 类型为 S7WLBit 时,Amount只能为 1 ,否则会抛出数据长度超出限制。
2、WordLen 输入 S7WLByte 实际上相当于我们常用的枚举,和当中的值无关。
3、 pUsrData中使用 “Byte” 类型读取时,所存储的数据端序为 “大端序” 。而我们PC通常所用 x86 架构的CPU为 “小端序” 存储;ARM 则默认为 “小端序”,但可配置端序 。C/C++编程的数据存储方式与机器所使用的CPU有关,所以我们需要自行转换端序。

这里为了方便读取一整个 Struct ,我使用的是一个 unsigned char 的数组,最后根据根据实际情况机型解析。

调试过程中,我在输入地址为十进制时,则会抛出一个 “errCliAddressOutOfRange” 的错误,填写十六进制地址时,则能够正常读写。目前未知具体原因。

3. 最后

Snap7库中还有很多其他的接口,需要之后慢慢去了解。

如有错误,请各位大佬斧正!😁

这篇关于西门子S7通讯——基于Snap7的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/943974

相关文章

Java Websocket实例【服务端与客户端实现全双工通讯】

Java Websocket实例【服务端与客户端实现全双工通讯】 现很多网站为了实现即时通讯,所用的技术都是轮询(polling)。轮询是在特定的的时间间隔(如每1秒),由浏览器对服务器发 出HTTP request,然后由服务器返回最新的数据给客服端的浏览器。这种传统的HTTP request 的模式带来很明显的缺点 – 浏 览器需要不断的向服务器发出请求,然而HTTP

STM32 HAL CAN通讯 实操

1、简介 相比于串口通讯,对于刚接触CAN通讯的小白来说,CAN通讯相对复杂,看各种视频、帖子理论,总是一知半解。本次通过傻瓜式操作,先实现CAN通讯的交互,以提高小白的信心,也便于自己复习观看。本次以STM32CubeMX进行初始化配置,通过Keil 5软件进行软件设计,通过CAN盒实现进行数据的交互。该流程实际以STM32F0、F1、F3、F4、F7实测好用(理论上都适用),这三种型号单片机

C++ 上位软件通过Snap7开源库访问西门子S7-1200/S7-1500数据块的方法

C++ 上位软件通过Snap7开源库访问西门子S7-1200/S7-1500数据块的方法

C#编写上位机通过OPC DA读取西门子PLC数据

Sync_RW 引用:Quick.OpcComRcw 文档中原程序会报错: 原因:需要在安装有Simatic NET V14的电脑上运行这个程序。 需要注释掉下面程序,否则读取时会无故障提示退出。 //finally里的程序要注释掉,否则一点击read按钮,程序会直接无故障提示退出//finally//{// // Free the unmanaged memory/

关于Qt在子线程中使用通讯时发生无法接收数据的情况

在多线程应用中,串口通讯或TCP通讯的场景常常涉及到持续的读写操作,如果子线程处理不当,可能会导致信号阻塞问题。本文将通过串口通讯或TCP通讯为例,详细解释如何在多线程环境中避免信号阻塞,并提供代码示例。 1. 问题背景 假设我们在一个应用程序中使用多线程处理串口或TCP通讯,通常会在子线程中实现持续的数据读取。为了确保实时处理数据,常见的做法是在子线程的 run() 方法中使用 while

QQ通讯协议

不管UDP还是TCP,最终登陆成功之后,QQ都会有一个TCP连接来保持在线状态。这个TCP连接的远程端口一般是80,采用UDP方式登陆的时候,端口是8000。因此,假如你所在的网络开放了80端口(80端口是最常用端口。。就是通常访问Web的端口,禁掉它的话,你的网络对你来说价值已经不大了),但没有屏蔽腾讯的服务器IP,恭喜你,你是可以登陆成功QQ的。 二、聊天消息通信。       采用UDP协

串口与Labview通讯的调试

在学习Labview和串口的通讯和调试的时候。首先必须先了解一些Labview的基础知识,然后就是了解串口,在调试的过程中,我们需要下位机来辅助我们的程序编写与调试,也就是我们平时使用的单片机,如果没有单片机也不要紧,可以使用虚拟串口来把电脑的串口相连接,这样也可以达到我们的预期效果 工欲善其事,必先利其器 让我们先来做一些准备工作 在这里可以把两个虚拟的串口相连接,在上图的左边,可以看到我

西门子数控软件6FC系列

西门子数控软件6FC系列是一款功能强大的数控解决方案,广泛应用于工业自动化领域。以下是对西门子数控软件6FC系列的详细介绍: 一、产品概述         西门子数控软件6FC系列属于SINUMERIK数控系统,是西门子工业软件部提供的重要产品之一。该系列软件旨在为企业提供高效、精确的机床自动化解决方案,满足从单件生产到大批量生产,从简单工件到复杂工件的各种生产需求。 二、主

不等了,华为计划在5.5G阶段就实现6G的空天地一体通讯网络功能

朋友们,你们是否曾经幻想过,无论身处何地,都能保持与世界的无缝连接?在偏远的山区、在茫茫的大海、甚至是在飞机上,都能享受畅通无阻的网络服务? 现在,这不再是幻想,华为正计划将这一切变为现实。在最近召开的空天信息产业国际生态大会上,华为的余承东宣布了一项激动人心的计划——在5.5G时代就实现6G的空天地一体通讯网络功能。 一、星地融合,永不失联 华为一直在探索如何将卫星通信技术与地面网络相

副本技能-使用RabbitMQ做即时消息通讯,使用STOMP协议

1.消息通讯的基础环境 技术使用: 后端使用Spring Websocket通讯,前端使用SocketJS,非长连接,有心跳检测信息交互使用RabbitMQ的插件Stomp 给RabbitMQ安装Stomp的插件 安装前: 安装后: 安装步骤(我的RabbitMQ是使用的Docker) 1.进入Docker容器RabbitMQ的后台(docker exec -it 容器ID /bin