文章目录

  • 一.西门子snap7介绍
  • 二.西门子S7通讯介绍
  • 三.jetson nano编译snap7库
  • 四.Qt Cmake导入snap7库
  • 五.snap7主要函数说明
    • 1.与PLC建立连接
    • 2.读写PA区变量
    • 3.读写MK区变量
  • 六.通讯程序示例

一.西门子snap7介绍

Snap7 是一个基于以太网与S7系列的西门子PLC通讯的开源库。支持包括S7系列的S7-200、S7-200 Smart、S7-300、S7-400、S7-1200以及S7-1500的以太网通信。支持32/64位英特尔/ AMD的所有平台。 例如:

  • Windows ( 除了 windows Me和95);

  • Linux和类Linux(树莓派,UBeagleBone Black,DOO 等),

  • BSD;

  • Oracle Solaris ;

  • Apple OSX

支持语言也比较广:

  • Pascal;

  • C#;

  • C++;

  • C;

  • LabVIEW

  • Python;

  • Node.js

  • Java.

二.西门子S7通讯介绍

西门子S7系列PLC采用以下两种通讯方式:

  • 开放式的TCP\IP,可以用于连接PLC与其他非西门子硬件
  • 西门子自己开发的S7 Protocol以太网通讯协议,用于西门子内部硬件通讯

这两者的传输报文是不一样的,如下图:

西门子数存储到二进制时方式是大端模式(BIG-Endian),而我们的普通电脑常常为小端模式(Liitle-Endian)。
大端模式是指数据的低位保存在内存的高地址中,而数据的高位保存在内存的低地址中.
小端模式是指数据的低位保存在内存的低地址中,而数据的高位保存在内存的高地址中。
例如:双字 DWORD 0X2F11214C

PLC:

PC:

所以数据需要进行转换

三.jetson nano编译snap7库

  1. 下载源代码

    下载地址:

    https://sourceforge.net/projects/snap7/files/1.4.2/

  2. 解压下载好的文件,进入如下图所示目录

  3. 空白处右键打开命令行,输入如下代码进行编译源代码以及安装

    sudo make -f arm_v6_linux.mk install
    

四.Qt Cmake导入snap7库

  1. 从example/cpp文件夹中拷贝snap7.h snap7.cpp两个文件到自己的项目中

  2. cmake设置如下

    cmake_minimum_required(VERSION 3.5)project(snap7Test VERSION 0.1 LANGUAGES CXX)set(CMAKE_INCLUDE_CURRENT_DIR ON)
    set(CMAKE_AUTOUIC ON)
    set(CMAKE_AUTOMOC ON)
    set(CMAKE_AUTORCC ON)
    set(CMAKE_CXX_STANDARD 17)
    set(CMAKE_CXX_STANDARD_REQUIRED ON)find_package(QT NAMES Qt5 REQUIRED COMPONENTS Widgets)
    find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Widgets Gui)set(PROJECT_SOURCESmain.cppmainwindow.cppmainwindow.hmainwindow.uisnap7.cppsnap7.h
    )add_executable(${PROJECT_NAME} ${PROJECT_SOURCES})target_link_libraries(${PROJECT_NAME} PRIVATE Qt${QT_VERSION_MAJOR}::Widgets Qt${QT_VERSION_MAJOR}::Gui)
    target_link_libraries(${PROJECT_NAME} PRIVATE libsnap7.so)
    

    主要在下面这两个,一个是把snap7.h和snap7.cpp添加到自己的项目中,一个是添加libsnap7.so库到项目中

    
    set(PROJECT_SOURCESmain.cppmainwindow.cppmainwindow.hmainwindow.uisnap7.cppsnap7.h
    )target_link_libraries(${PROJECT_NAME} PRIVATE libsnap7.so)
    

五.snap7主要函数说明

ConnectTo(const char *RemAddress, int Rack, int Slot);//函数说明:通过PLC的IP地址*RemAddress建立连接。// *RemAddress PLC的IP地址,
// Rack s7200SMART PLC的齿数,一般为0
// Slot s7200SMART PLC的槽数,一般为1
Disconnect();//函数说明:断开PC与PLC的连接
ReadArea(int Area, int DBNumber, int Start, int Amount, int WordLen, void *pUsrData);//函数说明:读PLC某个区域的值//Area表示内存区。取值0x84:V区  0x83:M区  0x82:O区  0x81:I区  0x1C:C区  0x1D:T区
//DBNumber表示区域号,只有在对DB块使用时才有用,默认设置为0
//Start表示起始地址。当函数功能为读bit时,int addr =Start/8; int bit = Start%8;
// 此时表示第addr地址的第Bit位。如Start = 8;则表示第1号地址的第0位,即addr.Bit(1.0);
//Amount表示要读取的数据长度,当函数类型为读bit时,只能为1
//WordLen决定函数的功能,函数功能有读位,字节,字,双字。取值: 0x1:Bit  0x2:Byte
// 0x4:Word  0x6:DW  0x8 : Real 0x1c : C区(16Bit)  0x1D:T区(16Bit)
//注意:读Word和DWord功能有问题,高位字节在前,低位字节在后(跟我们的程序反过来)
//*pUsrData表示数据缓冲区,读取的数据存入该缓冲区
WriteArea(int Area, int DBNumber, int Start, int Amount, int WordLen, void *pUsrData);//函数说明:写PLC某个区域的值//Area表示内存区。取值0x84:V区  0x83:M区  0x82:O区  0x81:I区  0x1C:C区  0x1D:T区
//DBNumber表示区域号,只有在对DB块使用时才有用,默认设置为0
//Start表示起始地址。当函数功能为写bit时,int addr =Start/8; int bit = Start%8;
// 此时表示第addr地址的第Bit位。如Start = 8;则表示第1号地址的第0位,即addr.Bit(1.0);
//Amount表示要写的数据长度,当函数类型为写bit时,只能为1
//WordLen决定函数的功能,函数功能有写位,字节,字,双字。取值: 0x1:Bit  0x2:Byte
// 0x4:Word  0x6:DW  0x8 : Real 0x1c : C区(16Bit)  0x1D:T区(16Bit)
//注意:读Word和DWord功能有问题,高位字节在前,低位字节在后(跟我们的程序反过来)
//*pUsrData表示数据缓冲区,写入PLC的数据存入该缓冲区
DBRead(int DBNumber, int Start, int Size, void *pUsrData);//函数说明:读V区的Byte值//DBNumber读V区识别号码,只有在对DB块使用时才有用,默认设置为0
//Start读PLC的起始地址
//Size读PLC的字节个数
//*pUsrData数据缓冲区,函数读到的数据存在这个缓冲区内
DBWrite(int DBNumber, int Start, int Size, void *pUsrData);    //函数说明:写V区的Byte值//DBNumber读V区识别号码,只有在对DB块使用时才有用,默认设置为0
//Start读PLC的起始地址
//Size读PLC的字节个数
//*pUsrData数据缓冲区,函数读到的数据存在这个缓冲区内
//area用于区分I、Q、M、DB区域,具体选择如下
areas = ADict({'PE': 0x81,  #input 输入区'PA': 0x82,  #output 输出区'MK': 0x83,  #bit memory 中间存储区(M区)'DB': 0x84,  #DB区'CT': 0x1C,  #counters'TM': 0x1D,  #Timers
})


1.与PLC建立连接

#include "snap7.h"TS7Client* client = new TS7Client;
char *Address = "192.168.1.10";
int Rack = 0;
int Slot = 1;
client->ConnectTo(Address, Rack, Slot);

2.读写PA区变量

int l_byData[1] = { 1 };
client->WriteArea(S7AreaPA, 0, 4, 1, S7WLBit, &l_byData); //PA区的0.4写入值1
client->ReadArea(S7AreaPA, 0, 4, 1, S7WLBit, &l_byData); //PA区的0.4读取值1

3.读写MK区变量

byte l_byData[4] = { 0 };
float l_fSpeed = 50;//字节转换
l_byData[3] = *((byte*)&l_fSpeed + 0);
l_byData[2] = *((byte*)&l_fSpeed + 1);
l_byData[1] = *((byte*)&l_fSpeed + 2);
l_byData[0] = *((byte*)&l_fSpeed + 3);client->WriteArea(S7AreaMK, 0, 4, 4, S7WLDWord, &l_byData); //写入值client->ReadArea(S7AreaMK, 0, 4, 4, S7WLDWord, &l_byData); //读取值
//转换
*((byte*)&l_fSpeed + 0) = l_byData[3];
*((byte*)&l_fSpeed + 1) = l_byData[2];
*((byte*)&l_fSpeed + 2) = l_byData[1];
*((byte*)&l_fSpeed + 3) = l_byData[0];

六.通讯程序示例

打包下载地址:https://download.csdn.net/download/qq_30150579/87382222

# cmakeList.txt
cmake_minimum_required(VERSION 3.5)project(snap7Test VERSION 0.1 LANGUAGES CXX)set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(CMAKE_AUTOUIC ON)
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)find_package(QT NAMES Qt5 REQUIRED COMPONENTS Widgets)
find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Widgets Gui)set(PROJECT_SOURCESmain.cppmainwindow.cppmainwindow.hmainwindow.uisnap7.cppsnap7.h
)add_executable(${PROJECT_NAME} ${PROJECT_SOURCES})target_link_libraries(${PROJECT_NAME} PRIVATE Qt${QT_VERSION_MAJOR}::Widgets Qt${QT_VERSION_MAJOR}::Gui)
target_link_libraries(${PROJECT_NAME} PRIVATE libsnap7.so)
//main.cpp
#include "mainwindow.h"#include <QApplication>int main(int argc, char *argv[])
{QApplication a(argc, argv);MainWindow w;w.show();return a.exec();
}
// mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H#include <QMainWindow>
#include "snap7.h"QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACEclass MainWindow : public QMainWindow
{Q_OBJECTpublic:MainWindow(QWidget *parent = nullptr);~MainWindow();private:Ui::MainWindow *ui;TS7Client* client;char *Address;int Rack = 0;int Slot = 1;private slots:void on_ConnectpushButton_clicked();void on_DisconnectpushButton_clicked();void on_WritePApushButton_clicked();void on_ReadPApushButton_clicked();void on_WriteMKpushButton_clicked();void on_ReadMKpushButton_clicked();
};
#endif // MAINWINDOW_H
// mainwindow.cpp
#include "mainwindow.h"
#include "./ui_mainwindow.h"#include <QDebug>
#include <QMessageBox>
#include "snap7.h"MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow)
{ui->setupUi(this);client = new TS7Client;
}MainWindow::~MainWindow()
{delete ui;
}void MainWindow::on_ConnectpushButton_clicked()
{QByteArray ad(ui->lineEdit->text().toUtf8());Address = ad.data();Rack = ui->lineEdit_2->text().toInt();Slot = ui->lineEdit_3->text().toInt();int tmp = client->ConnectTo(Address, Rack, Slot);if(tmp==0){QMessageBox::information(this,tr("success"),tr("PLC连接成功"));}else{QMessageBox::critical(this,tr("error"),tr("PLC连接失败"));}
}void MainWindow::on_DisconnectpushButton_clicked()
{int tmp = client->Disconnect();if(tmp==0){QMessageBox::information(this,tr("success"),tr("PLC断开成功"));}else{QMessageBox::critical(this,tr("error"),tr("PLC断开失败"));}
}void MainWindow::on_WritePApushButton_clicked()
{int l_byData[1] = { ui->lineEdit_6->text().toInt() };int tmp = client->WriteArea(S7AreaPA, 0, ui->lineEdit_7->text().toInt(), 1, S7WLBit, &l_byData);if(tmp==0){QMessageBox::information(this,tr("success"),tr("写入成功"));}else{QMessageBox::critical(this,tr("error"),tr("写入失败"));}
}void MainWindow::on_ReadPApushButton_clicked()
{int l_byData[1] = { 0 };int tmp = client->ReadArea(S7AreaPA, 0, ui->lineEdit_7->text().toInt(), 1, S7WLBit, &l_byData);if(tmp==0){QMessageBox::information(this,tr("success"),tr("读取成功"));ui->lineEdit_8->setText(QString("%1").arg(l_byData[0]));}else{QMessageBox::critical(this,tr("error"),tr("读取失败"));}
}void MainWindow::on_WriteMKpushButton_clicked()
{byte l_byData[4] = { 0 };float l_fSpeed = ui->lineEdit_5->text().toFloat();l_byData[3] = *((byte*)&l_fSpeed + 0);l_byData[2] = *((byte*)&l_fSpeed + 1);l_byData[1] = *((byte*)&l_fSpeed + 2);l_byData[0] = *((byte*)&l_fSpeed + 3);int tmp = client->WriteArea(S7AreaMK, 0, ui->lineEdit_4->text().toInt(), 4, S7WLDWord, &l_byData);if(tmp==0){QMessageBox::information(this,tr("success"),tr("写入成功"));}else{QMessageBox::critical(this,tr("error"),tr("写入失败"));}
}void MainWindow::on_ReadMKpushButton_clicked()
{byte l_byData[20] = {0};float l_fSpeed = {0};int tmp = client->ReadArea(S7AreaMK, 0, ui->lineEdit_4->text().toInt(), 4, S7WLDWord, &l_byData);if(tmp==0){QMessageBox::information(this,tr("success"),tr("读取成功"));*((byte*)&l_fSpeed + 0) = l_byData[3];*((byte*)&l_fSpeed + 1) = l_byData[2];*((byte*)&l_fSpeed + 2) = l_byData[1];*((byte*)&l_fSpeed + 3) = l_byData[0];ui->lineEdit_9->setText(QString("%1").arg(l_fSpeed));}else{QMessageBox::critical(this,tr("error"),tr("读取失败"));}
}

jetson nano上编译与使用西门子PLC通讯库snap7相关推荐

  1. 解决Jetson nano上编译librealsense错误:Could NOT find Vulkan (missing: VULKAN_LIBRARY VULKAN_INCLUDE_DIR)

    1 我的Jetson nano环境 zhihui@zhihui-desktop:~$ jetson_release -v- NVIDIA Jetson Nano (Developer Kit Vers ...

  2. 在Jetson Nano上编译 pyrealsense2库包,并在Intel的tof相机上进行测试

    关于如何从源码编译pyrealsense2 文章目录: 1 编译librealsense中python相关的库 2 使用pyrealsense2获取Intel 的tof相机视频流用例 1 编译libr ...

  3. 在Jetson Nano上安装RTL8821cu驱动

    在Jetson Nano上安装RTL8821cu驱动 下载该芯片的驱动 编译 网卡模式转换 Jetson Nano没有自带无线网卡,我用的是USB无线网卡,而且还是TP-Link的TL-WDN5200 ...

  4. 在Jetson Nano上十行代码实现目标检测(jetson_inference)

    网上有一个10行代码搞定目标检测的视频教程 参考网址:https://www.bilibili.com/video/av91150116/ 经测非常实用,通过10行代码实现目标检测,在Jetson N ...

  5. 小白从零开始在jetson nano上进行YOLOV3-Tiny 与 tensorrt加速检测

    一.前期准备需要 1.一块jetson nano版 2.SD卡(已经烧录好了镜像资源) 3.电脑上下载XFPT7(对于学生完全免费)(方便从电脑上直接传输文件进入板子) 二.软件需求(在电脑上,因为在 ...

  6. Jetson nano 上使用ROS进行双目摄像头(CSI-IMX219)操作标定

    Jetson nano 上使用ROS进行双目摄像头(CSI-IMX219)操作标定 Nvidia的Jetson nano上使用索尼的IMX219相机操作ROS CSI-IMX219简介 imx219是 ...

  7. 基于PP-ShiTu的零售商品结算系统设计与在Jetson Nano上部署推理使用

    文章目录 第一章 作品概述 1.1 团队介绍 1.2 背景 1.3 简介 1.4 创新点与问题 1.5 发展前景 1.6 技术路线 第2章 技术方案 2.1 主体检测 2.2 特征提取 2.3 向量检 ...

  8. 在jetson nano上安装ROS melodic

    Jetson nano的镜像使用的是Ubuntu18.04 LTS (绰号Bionic),因此在jetson nano上安装ROS得选择Melodic版,但是因为jetson nano使用的是ARM6 ...

  9. 【MindSpore易点通·漫游世界】在Jetson Nano上安装MindSpore 1.6.0 CPU版

    尽管在官网,MindSpore没有CUDA10的aarch64版本.(注:当时时刻为2022年2月) 只有aarch的CPU版本: Python的版本也只有3.6.9.但是作为昇思开发者的张小白,仍然 ...

最新文章

  1. Linux系统的启动流程以及做个小小的Linux
  2. 数据库授予用户增删改查的权限的语句_软件测试之浅谈数据库技术概述
  3. ubuntu16.04 server unrar解压rar文件提示command not found和解压tar.bz2文件
  4. python 惰性序列_讨论 - 廖雪峰的官方网站
  5. python3(四)Pandas库
  6. python打开串口失败_python 如何防止串口通信失败?
  7. redis单线程原理___Redis为何那么快-----底层原理浅析
  8. oracle 讲师费用,20080929--ORACLE培训笔记未整理版(讲师:ORA-600)
  9. 个人总结---连通图的最小生成树算法
  10. Unity3d之求物体体积
  11. python车牌字符分割_OpenCV+Python识别车牌和字符分割的实现
  12. 超图软件 linux gis软件,超图(GIS)软件详细功能介绍.doc
  13. 思科 配置标准ACL
  14. 隐藏在网络邻居背后的协议,快来看看你家网络有几种?
  15. 基于RS的沈阳土地利用情况
  16. 24L01/SI24R1调试笔记
  17. Android - NETD解读
  18. Introduction to OOC Programming Language
  19. 我为什么开始写博客,并要坚持下去?
  20. 项目要求完成杀毒软件,可是为什么网上关于杀毒软件的资料那么少啊

热门文章

  1. springboot上传文件大小限制解决方法
  2. D435i激光发射器要不要关
  3. D. Returning Home(建图 + 堆优化最短路)
  4. MEION:滤波器输出信号幅度处理
  5. css基础 层叠样式表 选择器
  6. Android的动画:ScaleAnimation,AlphaAnimation,RotateAnimation,TranslateAnimation,Code,DrawableAnimation
  7. atu打开服务器端文件失败,ATU操作流程.docx
  8. VL50-简易秒表,60秒钟进位1分钟,60分钟是一小时,设计进制到60分钟时暂停计数
  9. 用python语言编写从一到一百累加之和
  10. wmware10 安装xp iso出现 non-bootable disk 80