C#与西门子PLC通讯——高手快速入门

提示1:参照本文,你将通过一个实际案例深入了解如何实现一个通讯交互方案的功能。 提示2:如果你希望先完成一个简单的项目原型,请跳转C#与西门子PLC通讯——熟手快速入门。 提示3:如果你第一次来,请跳转到C#与西门子PLC通讯——新手快速入门以了解背景设定。

C#与西门子PLC通讯 系列文章目录

往期博客参考 建议先看下面这两篇,了解预设背景。 C#与西门子PLC通讯——新手快速入门 C#与西门子PLC通讯——熟手快速入门

番外篇 C#与西门子PLC通讯——手搓S7通讯协议

代码已同步至: Gitee:https://gitee.com/lukailin/auto-parking-system Github:https://github.com/Millance/AutoParkingSystem

文章目录

前言

又过三日,斯电气之士志在不凡,再请吾赐以开发之微言,吾思之经久,遂书笔记一篇,以赞其志。

本文基于C# .Net Core和西门子博图TIA Portal V17搭建。由于手边没有西门子PLC实物,所以采用S7-PLCSIM Advanced V4.0作为模拟PLC,以实现0成本完成通讯测试实例。

本文将以一个自动化立体车库作为案例入手,完成基于领域驱动设计(DDD)的项目设计。
https://img-blog.csdnimg.cn/1de3cf3ed23c4830bb06015459b1f083.jpeg

一、需求分析

1.1 背景

随着城市交通日益拥堵,自动化立体车库系统成为解决停车难题的创新方案。该系统涉及到大量的设备,如PLC控制器用于车库的自动化操作,数据库用于存储车辆信息,用户界面用于用户与系统的交互。 在自动化立体车库系统中,与西门子PLC的高效通讯是确保系统稳定运行的关键之一。本博客将带领读者深入探讨如何使用C#与西门子PLC进行通讯,实现对车库设备的灵活控制。

1.2 主要功能

  • PLC通讯: 实现C#与西门子PLC的通讯,包括读取PLC中的状态信息和发送控制指令。 + 数据库访问: 通过Entity Framework Core实现对车辆信息的持久化存储,包括车辆的入库和出库记录。 + 业务逻辑: 实现车库的业务逻辑,包括车位管理、车辆入库和出库等操作。 + 用户界面: 使用ASP.NET Core MVC或Blazor实现用户友好的界面,显示车库状态,提供用户操作界面。

1.3 技术选型

  • PLC通讯服务: 使用S7netplus等通讯库实现C#与西门子PLC的通讯。 + 数据库访问: 利用Entity Framework Core进行数据库操作,支持多种数据库后端。 + 业务逻辑: 基于领域驱动设计(DDD)的概念,实现业务逻辑服务接口。 + 用户界面: 使用ASP.NET Core MVC,与业务逻辑和PLC通讯服务集成。

1.4 系统架构

  • AutoParkingSystem.Core: 实现领域模型和业务逻辑。 + AutoParkingSystem.Infrastructure: 实现数据库访问操作和PLC通讯服务,使用Entity Framework Core和S7netplus等库。 + AutoParkingSystem.Model: 存放所有的数据库对象实体。 + AutoParkingSystem.Repository: 存放数据库上下文和迁移文件。 + AutoParkingSystem.Web: 实现用户界面,集成业务逻辑和PLC通讯服务的接口,展示车库状态和实现用户操作。 + AutoParkingSystem.Tests: 编写单元测试和集成测试,确保系统的稳定性和可靠性。

https://img-blog.csdnimg.cn/direct/ccebd09e6075408c883829487fc68a49.png

1.5 依赖注入和反射

通过在Program.cs中配置依赖注入容器,实现各个服务和组件的动态加载和实例化,提高系统的灵活性和可扩展性。

二、业务实现

2.1 PLC通讯服务

AutoParkingSystem.Infrastructure项目中实现与西门子PLC的通讯服务。首先,创建接口定义:

// AutoParkingSystem.Core/Services/IPlcCommunicationService.cs
public interface IPlcCommunicationService
{
   
    bool IsConnected {
    get; }
    Task<bool> ConnectAsync(string ipAddress, int rack, int slot);
    Task<int> ReadIntAsync(int dbArea, int offset);
    Task WriteIntAsync(int dbArea, int offset, short value);

    // 其他通讯方法...
}

然后,在AutoParkingSystem.Infrastructure项目中实现该接口:

// AutoParkingSystem.Infrastructure/Services/SiemensPlcCommunicationService.cs
public class SiemensPlcCommunicationService : IPlcCommunicationService
{
   
    private Plc? plc;

    public bool IsConnected
    {
   
        get
        {
   
            if (plc == null) {
    return false; }
            return plc.IsConnected;
        }
    }

    public async Task<bool> ConnectAsync(string ipAddress, int rack, int slot)
    {
   
        plc = new Plc(CpuType.S71500, ipAddress, (short)rack, (short)slot);
        await plc.OpenAsync();
        return plc.IsConnected;
    }

    public async Task<int> ReadIntAsync(int dbArea, int offset)
    {
   
        if (plc == null || !plc.IsConnected)
        {
   
            throw new InvalidOperationException("PLC is not connected.");
        }

        var result = await plc.ReadAsync(DataType.DataBlock, dbArea, offset, VarType.Int, 1);
        if (result == null)
        {
   
            return 0;
        }
        else
        {
   
            return (short)result;
        }
    }

    public async Task WriteIntAsync(int dbArea, int offset, short value)
    {
   
        if (plc == null || !plc.IsConnected)
        {
   
            throw new InvalidOperationException("PLC is not connected.");
        }

        await plc.WriteAsync(DataType.DataBlock, dbArea, offset, value);
    }

    // 其他通讯方法的实现...
}

2.2 数据库创建

2.2.1 定义数据库对象

使用Entity Framework Core实现对车辆信息的数据库访问。

AutoParkingSystem.Model项目中定义数据库对象ParkPosition:
https://img-blog.csdnimg.cn/direct/fbae898c8dff4daa86181b004382ca5a.png

namespace AutoParkingSystem.Model
{
   
    [Table("park_position")]
    public class ParkPosition
    {
   
        /// <summary>
        /// 位置id
        /// </summary>
        [Key]
        [Column("id")]
        public int Id {
    get; set; }

        /// <summary>
        /// 位置名称
        /// </summary>
        [Column("position_name")]
        [MaxLength(10)]
        public string PositionName {
    get; set; } = string.Empty;

        /// <summary>
        /// 停放车辆的车牌号
        /// </summary>
        [Column("license_plate_number")]
        [MaxLength(10)]
        public string LicensePlateNumber {
    get; set; } = string.Empty;

        /// <summary>
        /// 进入位置的时间
        /// </summary>
        [Column("park_in_time")]
        public DateTime ParkInTime {
    get; set; } = DateTime.Now;
    }
}

2.2.2 定义数据库上下文

AutoParkingSystem.Repository中添加Entity Framework Core的NuGet包。

注:这里用的是MySql数据库,可以根据本地数据库类型找到对应的包

https://img-blog.csdnimg.cn/direct/9c046654d5654fd4aac65a809946a8bb.png

创建数据库上下文ParkDbContext.cs

namespace AutoParkingSystem.Repository
{
   
    public class ParkDbContext : DbContext
    {
   
        // 添加车位累
        public DbSet<ParkPosition> ParkPositions {
    get; set; }

        public ParkDbContext(DbContextOptions<ParkDbContext> options) : base(options) {
    }
    }
}

2.2.3 数据库链接字
  • 14
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值