中央热水项目
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

7.3 KiB

S7 PLC 地址类型扩展说明

更新概述

本次更新为S7ConnectorUtil工具类新增了以下地址类型的支持:

  • I区: 数字量输入 (Input)
  • Q区: 数字量输出 (Output)
  • AIW区: 模拟量输入字 (Analog Input Word)
  • AQW区: 模拟量输出字 (Analog Output Word)

支持的地址格式

1. I区 - 数字量输入

地址格式:

  • 位地址: I0.1, I1.5, I2.3
  • 字节地址: I0, I1, I10

特性:

  • DaveArea: PE (Process Inputs)
  • 数据类型: Boolean (位) 或 Byte (字节)
  • 通常只读,由外部传感器/开关控制
  • 写入时会记录警告日志

示例:

// 读取输入位 I0.1
Object value = connector.readData("I0.1");  // 返回 0 或 1

// 读取输入字节 I0
Object value = connector.readData("I0");    // 返回 0-255

2. Q区 - 数字量输出

地址格式:

  • 位地址: Q0.1, Q1.5, Q2.3
  • 字节地址: Q0, Q1, Q10

特性:

  • DaveArea: PA (Process Outputs)
  • 数据类型: Boolean (位) 或 Byte (字节)
  • 可读写,用于控制继电器/指示灯等

示例:

// 读取输出位 Q0.1
Object value = connector.readData("Q0.1");  // 返回 0 或 1

// 写入输出位 Q0.1
connector.writeData("Q0.1", 1);  // 置位

// 写入输出字节 Q0
connector.writeData("Q0", 255);  // 所有位都置1

3. AIW区 - 模拟量输入字

地址格式:

  • AIW0, AIW64, AIW128

特性:

  • DaveArea: PE (Process Inputs)
  • 数据类型: Word (2字节, 0-65535)
  • 只读,用于读取模拟量传感器(温度、压力等)
  • 通常对应PLC的模拟量输入模块
  • 写入时会记录警告日志

示例:

// 读取模拟量输入 AIW0
Object value = connector.readData("AIW0");  // 返回 0-65535

// 转换为实际值(例如温度传感器 0-10V 对应 0-100°C)
int rawValue = (Integer) value;
double temperature = rawValue * 100.0 / 65535.0;

4. AQW区 - 模拟量输出字

地址格式:

  • AQW0, AQW64, AQW128

特性:

  • DaveArea: PA (Process Outputs)
  • 数据类型: Word (2字节, 0-65535)
  • 可读写,用于控制模拟量执行器(变频器、调节阀等)
  • 通常对应PLC的模拟量输出模块

示例:

// 读取模拟量输出 AQW0
Object value = connector.readData("AQW0");  // 返回 0-65535

// 写入模拟量输出(例如设置变频器频率 0-50Hz)
double frequency = 25.0;  // 25Hz
int outputValue = (int)(frequency * 65535.0 / 50.0);
connector.writeData("AQW0", outputValue);

DaveArea映射表

PLC区域 DaveArea枚举 说明
M区 FLAGS 位存储区/Merkers
I区 INPUTS 数字量输入/Inputs
Q区 OUTPUTS 数字量输出/Outputs
V区(DB) DB 数据块/Data Block
AIW INPUTS 模拟量输入(映射到输入区)
AQW OUTPUTS 模拟量输出(映射到输出区)

数据库配置示例

配置I区点位

-- 数字量输入点位
INSERT INTO collection_params_manage (
    device_install_id,
    register_addr,
    is_use,
    other_name,
    building_id
) VALUES (
    1,
    'I0.1',        -- 急停按钮状态
    1,
    'emergency_stop',
    '1'
);

配置Q区点位

-- 数字量输出点位
INSERT INTO collection_params_manage (
    device_install_id,
    register_addr,
    is_use,
    other_name,
    building_id
) VALUES (
    1,
    'Q0.1',        -- 启动指示灯
    1,
    'start_indicator',
    '1'
);

配置AIW区点位

-- 模拟量输入点位(温度传感器)
INSERT INTO collection_params_manage (
    device_install_id,
    register_addr,
    mt_ratio,       -- 倍率
    digits,         -- 小数点
    is_use,
    other_name,
    building_id
) VALUES (
    1,
    'AIW0',        -- 温度传感器
    0.0015259,      -- 倍率: 100/65535 ≈ 0.0015259
    2,              -- 2位小数
    1,
    'temperature_sensor',
    '1'
);

配置AQW区点位

-- 模拟量输出点位(变频器控制)
INSERT INTO collection_params_manage (
    device_install_id,
    register_addr,
    is_use,
    other_name,
    building_id
) VALUES (
    1,
    'AQW0',        -- 变频器频率设定
    1,
    'vfd_frequency',
    '1'
);

实际应用案例

案例1: 读取多个传感器数据

// 在S7PlcCollectionJob中自动采集
// 配置以下点位:
// - I0.1: 急停按钮
// - I0.2: 启动按钮
// - AIW0: 温度传感器
// - AIW64: 压力传感器

// 系统会每5分钟自动读取并保存到数据库

案例2: 手动控制输出

@Autowired
private S7PlcCollectionJob s7PlcCollectionJob;

// 通过API控制Q区输出
@PostMapping("/control/light")
public HttpResult controlLight(@RequestParam boolean on) {
    Constant.WEB_PLC_FLAG = true;
    try {
        // 获取Q0.1对应的cpmId
        Long cpmId = getCpmIdByOtherName("start_indicator");
        s7PlcCollectionJob.writeData(cpmId, on ? 1 : 0);
        return HttpResult.ok();
    } finally {
        Constant.WEB_PLC_FLAG = false;
    }
}

案例3: 模拟量转换

// 温度传感器: 0-10V 对应 0-100°C
// AIW0 原始值: 0-65535

// 在Service中进行转换
public double getTemperature() {
    CollectionParamsManageEntity param = 
        collectionParamsManageMapper.selectDeviceInstallByOtherName(
            "temperature_sensor", "1"
        );
    
    // 原始值已经应用了倍率 0.0015259
    BigDecimal rawValue = param.getCurValue();
    
    // 直接得到摄氏度
    return rawValue.doubleValue();
}

注意事项

1. I区和AIW区的只读特性

  • 这些区域由PLC硬件或外部设备控制
  • 尝试写入会导致警告日志
  • 在实际应用中应避免写入操作

2. Q区和AQW区的写入权限

  • 确保PLC程序允许外部写入
  • 注意PLC程序中是否有互锁逻辑
  • 写入前确认设备状态安全

3. 模拟量量程匹配

  • AIW/AQW的0-65535对应实际物理量
  • 需要在PLC中配置正确的量程
  • 或在Java代码中进行转换计算

4. 地址偏移

  • AIW和AQW的地址通常是2的倍数(AIW0, AIW64, AIW128...)
  • 具体取决于PLC硬件配置
  • 请参考PLC硬件手册

测试建议

1. 使用PLC仿真软件

  • S7-PLCSIM Advanced
  • 可以模拟各种地址类型的读写
  • 验证地址解析是否正确

2. 逐步测试

  1. 先测试M区和V区(最常用)
  2. 再测试I区和Q区(数字量)
  3. 最后测试AIW和AQW(模拟量)

3. 监控日志

  • 查看读写操作的日志
  • 确认数据类型转换正确
  • 检查是否有警告或错误

常见问题

Q1: 为什么I区写入会有警告?

A: I区是输入区,通常由外部硬件控制。写入I区在技术上可行,但不符合PLC编程规范,可能导致意外行为。

Q2: AIW和AQW的地址为什么是64、128这样的数字?

A: 这取决于PLC的硬件配置。每个模拟量通道占用2个字节,地址间隔由模块插槽位置决定。

Q3: 如何确定模拟量的量程?

A:

  1. 查看PLC硬件模块手册
  2. 检查PLC程序中的量程配置
  3. 使用万用表测量实际电压/电流
  4. 对比PLC显示值和实际值进行校准

Q4: Q区写入后PLC没有响应?

A:

  1. 检查PLC程序是否覆盖了Q区
  2. 确认PLC处于RUN模式
  3. 检查是否有硬件故障
  4. 验证网络连接正常

更新日期: 2026-06-23
版本: v1.1