jetson nano上编译与使用西门子PLC通讯库snap7
文章目录
- 一.西门子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库
下载源代码
下载地址:
https://sourceforge.net/projects/snap7/files/1.4.2/
解压下载好的文件,进入如下图所示目录
空白处右键打开命令行,输入如下代码进行编译源代码以及安装
sudo make -f arm_v6_linux.mk install
四.Qt Cmake导入snap7库
从example/cpp文件夹中拷贝snap7.h snap7.cpp两个文件到自己的项目中
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相关推荐
- 解决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 ...
- 在Jetson Nano上编译 pyrealsense2库包,并在Intel的tof相机上进行测试
关于如何从源码编译pyrealsense2 文章目录: 1 编译librealsense中python相关的库 2 使用pyrealsense2获取Intel 的tof相机视频流用例 1 编译libr ...
- 在Jetson Nano上安装RTL8821cu驱动
在Jetson Nano上安装RTL8821cu驱动 下载该芯片的驱动 编译 网卡模式转换 Jetson Nano没有自带无线网卡,我用的是USB无线网卡,而且还是TP-Link的TL-WDN5200 ...
- 在Jetson Nano上十行代码实现目标检测(jetson_inference)
网上有一个10行代码搞定目标检测的视频教程 参考网址:https://www.bilibili.com/video/av91150116/ 经测非常实用,通过10行代码实现目标检测,在Jetson N ...
- 小白从零开始在jetson nano上进行YOLOV3-Tiny 与 tensorrt加速检测
一.前期准备需要 1.一块jetson nano版 2.SD卡(已经烧录好了镜像资源) 3.电脑上下载XFPT7(对于学生完全免费)(方便从电脑上直接传输文件进入板子) 二.软件需求(在电脑上,因为在 ...
- Jetson nano 上使用ROS进行双目摄像头(CSI-IMX219)操作标定
Jetson nano 上使用ROS进行双目摄像头(CSI-IMX219)操作标定 Nvidia的Jetson nano上使用索尼的IMX219相机操作ROS CSI-IMX219简介 imx219是 ...
- 基于PP-ShiTu的零售商品结算系统设计与在Jetson Nano上部署推理使用
文章目录 第一章 作品概述 1.1 团队介绍 1.2 背景 1.3 简介 1.4 创新点与问题 1.5 发展前景 1.6 技术路线 第2章 技术方案 2.1 主体检测 2.2 特征提取 2.3 向量检 ...
- 在jetson nano上安装ROS melodic
Jetson nano的镜像使用的是Ubuntu18.04 LTS (绰号Bionic),因此在jetson nano上安装ROS得选择Melodic版,但是因为jetson nano使用的是ARM6 ...
- 【MindSpore易点通·漫游世界】在Jetson Nano上安装MindSpore 1.6.0 CPU版
尽管在官网,MindSpore没有CUDA10的aarch64版本.(注:当时时刻为2022年2月) 只有aarch的CPU版本: Python的版本也只有3.6.9.但是作为昇思开发者的张小白,仍然 ...
最新文章
- Linux系统的启动流程以及做个小小的Linux
- 数据库授予用户增删改查的权限的语句_软件测试之浅谈数据库技术概述
- ubuntu16.04 server unrar解压rar文件提示command not found和解压tar.bz2文件
- python 惰性序列_讨论 - 廖雪峰的官方网站
- python3(四)Pandas库
- python打开串口失败_python 如何防止串口通信失败?
- redis单线程原理___Redis为何那么快-----底层原理浅析
- oracle 讲师费用,20080929--ORACLE培训笔记未整理版(讲师:ORA-600)
- 个人总结---连通图的最小生成树算法
- Unity3d之求物体体积
- python车牌字符分割_OpenCV+Python识别车牌和字符分割的实现
- 超图软件 linux gis软件,超图(GIS)软件详细功能介绍.doc
- 思科 配置标准ACL
- 隐藏在网络邻居背后的协议,快来看看你家网络有几种?
- 基于RS的沈阳土地利用情况
- 24L01/SI24R1调试笔记
- Android - NETD解读
- Introduction to OOC Programming Language
- 我为什么开始写博客,并要坚持下去?
- 项目要求完成杀毒软件,可是为什么网上关于杀毒软件的资料那么少啊
热门文章
- springboot上传文件大小限制解决方法
- D435i激光发射器要不要关
- D. Returning Home(建图 + 堆优化最短路)
- MEION:滤波器输出信号幅度处理
- css基础 层叠样式表 选择器
- Android的动画:ScaleAnimation,AlphaAnimation,RotateAnimation,TranslateAnimation,Code,DrawableAnimation
- atu打开服务器端文件失败,ATU操作流程.docx
- VL50-简易秒表,60秒钟进位1分钟,60分钟是一小时,设计进制到60分钟时暂停计数
- 用python语言编写从一到一百累加之和
- wmware10 安装xp iso出现 non-bootable disk 80