智能保鲜柜的感知与控制系统(附源码)

1. 概要

  • 了解现场网感知与控制的基本方法
  • 掌握基于RS232的协议设计与通信方法在此基础上实现对现场设备状态数据的采集、对设备的控制。
  • 针对快递柜系统设计实现一个对现场快递柜状态数据采集、显示、参数设置、抽屉打开、保鲜控制等功能软件系统。

2.成果展示

  • 抽屉控制
    在这里插入图片描述

  • 参数设置
    在这里插入图片描述
    在这里插入图片描述

  • 温度感知
    在这里插入图片描述
    在这里插入图片描述

相关说明

  • 使用python+QT实现
  • 总体设计参考这位博主的博客传送门
  • 开发过程中遇到许多小问题,这里就不一一列举啦(遇到问题可以私信我讨论)
  • UI文件我这里就不转成python代码发出来了(因为很长又没什么意义,需要的可以私信我)
  • 废话不多说,直接上代码

20230706更新

源代码我放在阿里云盘了点我

主程序

control.py

from PySide2.QtWidgets import *
from PySide2.QtCore import *
from send import *
from receive import *
from data_struct import *
from PySide2.QtUiTools import QUiLoader
from PySide2.QtGui import QIcon, QColor
import time  # 时间模块
import threading  # 线程模块
import serial  # 串口模块
import ctypes
import inspect
import datetime
import pyqtgraph as pg

serial_port = 38400
port = 'COM2'
# 串口配置
com = serial.Serial(port, serial_port)


class MySignal(QObject):
    status_text_print = Signal(QTextBrowser, str)


def async_raise(tid, exc_type):
    """raises the exception, performs cleanup if needed"""
    tid = ctypes.c_long(tid)
    if not inspect.isclass(exc_type):
        exc_type = type(exc_type)
    res = ctypes.pythonapi.PyThreadState_SetAsyncExc(tid, ctypes.py_object(exc_type))
    if res == 0:
        raise ValueError("invalid thread id")
    elif res != 1:
        ctypes.pythonapi.PyThreadState_SetAsyncExc(tid, None)
        raise SystemError("PyThreadState_SetAsyncExc failed")


def stop_thread(thread):  # 强制关闭线程
    async_raise(thread.ident, SystemExit)


def status_show(temp_current, temp_msg):
    temp_current.setText(temp_msg)


def compressor_btn_off_clicked():
    print('压缩机关闭....')
    send_compressor_control_frame(com, False)


def thread_up(com):
    receive_data(com)


def receive():  # 接收数据线程
    receive_thread = threading.Thread(target=lambda: thread_up(com))
    receive_thread.setDaemon(True)
    receive_thread.start()
    return receive_thread


class Software:
    def __init__(self):
        # 从文件中加载UI定义
        loader = QUiLoader()
        loader.registerCustomWidget(pg.PlotWidget)
        self.ui = QUiLoader().load('control.ui')
        # 设置窗口icon
        self.ui.setWindowIcon(QIcon('icon.ico'))
        # 设置不可用
        self.set_enable(False)
        self.ms = MySignal()
        self.ms.status_text_print.connect(status_show)
        # 线程
        self.thread_flash_ui = None
        self.thread_receive_data = None
        # 保存接收到的温度数据
        self.temp_now_list = []
        # 时间线
        self.time_line_list = []
        # 窗口渲染
        self.plot_widget = self.ui.widget
        self.plot_widget.setBackground('#172C4B')
        self.plot_widget.setLabel('left', '温度℃')
        self.plot_widget.setLabel('bottom', '时间/s')
        # 按钮绑定函数
        self.ui.sys_on_btn.clicked.connect(self.sys_btn_on_clicked)
        self.ui.sys_off_btn.clicked.connect(self.sys_btn_off_clicked)
        self.ui.compressor_on_btn.clicked.connect(self.compressor_btn_on_clicked)
        self.ui.compressor_off_btn.clicked.connect(compressor_btn_off_clicked)
        self.ui.box_btn1.clicked.connect(lambda: self.box_btn_on_clicked(1))
        self.ui.box_btn2.clicked.connect(lambda: self.box_btn_on_clicked(2))
        self.ui.box_btn3.clicked.connect(lambda: self.box_btn_on_clicked(3))
        self.ui.box_btn4.clicked.connect(lambda: self.box_btn_on_clicked(4))
        self.ui.box_btn5.clicked.connect(lambda: self.box_btn_on_clicked(5))
        self.ui.box_btn6.clicked.connect(lambda: self.box_btn_on_clicked(6))
        self.ui.box_btn7.clicked.connect(lambda: self.box_btn_on_clicked(7))
        self.ui.box_btn8.clicked.connect(lambda: self.box_btn_on_clicked(8))
        self.ui.box_btn9.clicked.connect(lambda: self.box_btn_on_clicked(9))
        self.ui.box_btn10.clicked.connect(lambda: self.box_btn_on_clicked(10))
        self.ui.submit_btn.clicked.connect(self.submit_btn_clicked)

    def sys_btn_on_clicked(self):
        print('系统开启....')
        self.thread_flash_ui = self.flash_ui()
        self.thread_receive_data = receive()
        self.ui.sys_status_show.setText('运行中')
        self.ui.compressor_status_show.setText('关闭')
        self.set_enable(True)
        self.ui.sys_on_btn.setEnabled(False)
        # 如果串口未开启,则开启串口
        if not com.isOpen():
            com.open()

    def sys_btn_off_clicked(self):
        # 判断界面上的按钮是否为开启状态,如果是,则发送关闭帧
        # 串口关闭
        self.set_enable(False)
        self.ui.sys_on_btn.setEnabled(True)
        # 关闭线程
        stop_thread(self.thread_flash_ui)
        stop_thread(self.thread_receive_data)
        self.ui.sys_status_show.setText('关闭')
        self.ui.compressor_status_show.setText('停止')
        self.ui.current_temp_show.setText('None')
        send_compressor_control_frame(com, False)

    def compressor_btn_on_clicked(self):
        print('压缩机开启....')
        # 2.1 发送压缩机控制帧
        send_compressor_control_frame(com, True)
        # 压缩机开启按钮不可用
        self.ui.compressor_on_btn.setEnabled(False)

    def box_btn_on_clicked(self, num):
        # 点击按钮之后,将按钮上的文本修改成“开启”,如果原来是“开启”,则修改成“关闭”
        btn = self.ui.groupBox_box.findChild(QPushButton, 'box_btn{}'.format(num))
        if btn.text() == '开启':
            btn.setText('关闭')
        else:
            btn.setText('开启')
        # 获取所有按钮上的内容,存放到列表中
        mylist = []
        for btn in self.ui.groupBox_box.children():
            if isinstance(btn, QPushButton) and btn.text() != '确定':
                mylist.append(btn.text())
                # 如果是开启状态,则替换成1,否则替换成0
                if btn.text() == '开启':
                    mylist[-1] = 1
                else:
                    mylist[-1] = 0
        print(f"抽屉状态{mylist}")
        # 3. 发送开锁帧
        send_unlock_frame(com, mylist)

    def submit_btn_clicked(self):
        # 设置默认控制面板数据
        # 遍历所有文本框,如果无输入,则使用默认值
        for text in self.ui.groupBox_sys.children():
            # 如果按钮是QTextEdit类型
            if isinstance(text, QTextEdit):
                # 如果文本框有输入,则使用输入值
                if text.toPlainText():
                    # 如果是设置温度,则将输入值转换成浮点型
                    if text.objectName() == 'set_temp':
                        data_control_set['set_temp'] = float(text.toPlainText())
                    # 如果是设备代码,则将输入值字节化
                    elif text.objectName() == 'dev_code':
                        data_control_set['dev_code'] = int(text.toPlainText(), 16).to_bytes(5, 'big')
                        # print(text.toPlainText().encode('utf-8'))
                    else:
                        data_control_set[text.objectName()] = int(text.toPlainText())
        # print('设置参数:{}'.format(data_control_set))
        # 4. 发送设置温度帧
        send_set_temperature_frame(com, data_control_set['set_temp'])
        # print(f"设置的温度是{data_control_set['set_temp']},类型是{type(data_control_set['set_temp'])}")
        # 5. 发送设置参数帧
        send_set_parameter_frame(com, data_control_set)
        # 6. 发送温度控制偏差
        send_set_temperature_control_deviation_frame(com, data_control_set['temp_control'])
        # 7. 发送设置设备地址帧
        send_set_device_address_frame(com, data_control_set['dev_code'])

    # 控件可用性全局设置
    def set_enable(self, enable):
        # if enable:
        # self.ui.box_submit_btn.setEnabled(enable)
        self.ui.submit_btn.setEnabled(enable)
        self.ui.compressor_on_btn.setEnabled(enable)
        self.ui.compressor_off_btn.setEnabled(enable)
        self.ui.sys_off_btn.setEnabled(enable)
        for btn in self.ui.groupBox_box.children():
            # 如果按钮是QPushButton类型
            if isinstance(btn, QPushButton) and btn.text() != '确定':
                btn.setEnabled(enable)
                btn.setText('关闭')
        for text in self.ui.groupBox_sys.children():
            # 如果按钮是QTextEdit类型
            if isinstance(text, QTextEdit):
                text.setEnabled(enable)
                text.setText('')

    # 强制关闭线程

    def flash_ui(self):  # 界面刷新线程
        flash_thread = threading.Thread(target=self.flash)
        flash_thread.setDaemon(True)
        flash_thread.start()
        return flash_thread

    def flash(self):
        while True:
            # 实时温度数据
            self.temp_now_list.append(float(get_temp(control_table_status['current_temp'])))
            self.time_line_list.append(datetime.datetime.now().strftime('%H:%M:%S'))
            self.ms.status_text_print.emit(self.ui.current_temp_show, get_temp(control_table_status['current_temp']))
            if control_table_status['compressor_status'] == 0x00:
                self.ms.status_text_print.emit(self.ui.compressor_status_show, '停止')
            elif control_table_status['compressor_status'] == 0x01:
                self.ms.status_text_print.emit(self.ui.compressor_status_show, '预启动')
            elif control_table_status['compressor_status'] == 0x02:
                self.ms.status_text_print.emit(self.ui.compressor_status_show, '运行')
            elif control_table_status['compressor_status'] == 0x03:
                self.ms.status_text_print.emit(self.ui.compressor_status_show, '故障')
            time.sleep(1)
            self.drawing_on_panel()  # 在界面上画图1s更新一次
            # print(self.temp_now_list)
            # print(self.time_line_list)

    def drawing_on_panel(self):
        if len(self.temp_now_list) > 13:
            # 保留最近40个数据
            self.temp_now_list = self.temp_now_list[-13:]  # 浮点类型
            self.time_line_list = self.time_line_list[-13:]  # 字符串类型
        y = self.temp_now_list
        xax = self.plot_widget.getAxis('bottom')  # 坐标轴x
        ticks = [list(zip(range(len(self.time_line_list)), self.time_line_list))]
        xax.setTicks(ticks)
        pen = pg.mkPen({'color': (155, 200, 160), 'width': 4})  # 画笔设置
        self.plot_widget.plot(y, clear=True, pen=pen, symbol='o', symbolBrush=QColor(113, 148, 116))  # 画图


app = QApplication([])  # 创建QApplication对象
status = Software()  # 创建软件状态对象
status.ui.show()  # 显示窗口
app.exec_()  # 运行程序

数据帧发送

send.py

# 数据封装成帧
# 数据帧格式:
# 信息头(2B)+帧长(1B)+帧号(1B)[取值:1~255]+设备地址(1B)[1~120,0为上位机地址)]+功能号(1B)+数据(NB)+CRC校验(2B)+帧尾(2B)
# 帧头固定:0xFFFF
# 帧尾固定:0xFFF7
# 固定部分10B,可变部分为数据部分,帧长度为整个数据帧的长度
from struct import *
import serial

frame_num = 0  # type: int  # 定义全局变量帧号


# todo: 1.发送查询帧(10byte)
def send_query_frame(com, addr=0x01):
    res = com.write(query_frame(addr))
    return res

# todo: 2.启停压缩机控制帧(11byte)
def send_compressor_control_frame(com, compressor_control_data, addr=0x01):
    res = com.write(compressor_control_frame(addr, compressor_control_data))
    return res

# todo: 3.开锁帧(12byte)
def send_unlock_frame(com, box_control_data, addr=0x01):
    res = com.write(box_control_frame(addr, box_control_data))
    return res


# todo: 4.设置温度帧(11byte)
def send_set_temperature_frame(com, set_temperature_data, addr=0x01):
    print(f"我是设置温度方法{set_temperature_data}")
    res = com.write(set_temperature_frame(addr, set_temperature_data))
    return res

# todo: 5.设置参数帧(28byte)
def send_set_parameter_frame(com, data_control_set, addr=0x01):
    res = com.write(set_parameter_frame(addr, data_control_set))
    return res

# todo: 6.设置温度控制偏差帧(11byte)
def send_set_temperature_control_deviation_frame(com, temp_control_deviation, addr=0x01):
    res = com.write(set_temperature_control_deviation_frame(addr, temp_control_deviation))
    return res

# todo: 7.设置设备地址帧(16byte)
def send_set_device_address_frame(com, dev_code_data, addr=0x01):
    res = com.write(set_device_address_frame(addr, dev_code_data))
    return res


# 封装成帧
def packet_data_to_frame(addr, func_num, data):  # type: (int, int, bytes) -> bytes
    """
    :param addr: 16进制的设备地址,范围:OX1~OX78,类型为int
    :param func_num: 功能码
    :param data: bytes类型的数据
    :return: 返回一个bytes类型的数据帧
    """
    global frame_num
    # print(f"设备地址{pack('B', addr)}")
    frame_head = pack('2B', 255, 255)  # 0xFFFF 帧头
    frame_length = pack('B', len(data) + 10)  # 帧长
    num = pack('B', frame_num)  # 帧号
    address = pack('B', addr)  # 设备地址
    fc_num = pack('B', func_num)  # 功能码
    crc_check_bytes = frame_length + num + address + fc_num + data
    crc_frame = pack('H', crc_check(crc_check_bytes))  # CRC校验位
    frame_tail = pack('2B', 255, 247)  # 0xFFF7 帧尾
    # 封装
    frame_packet = frame_head + frame_length + num + address + fc_num + data + crc_frame + frame_tail
    frame_num = (frame_num + 1) % 256
    return frame_packet


# 1. 查询帧(10Byte)
def query_frame(addr):
    """
    :param addr: 16进制的设备地址,范围:OX1~OX78,类型为int
    :return: 返回一个bytes类型的查询帧
    """
    data = packet_data_to_frame(addr, 1, b'')
    print(f"查询帧发送:{data},长度为:{len(data)}")
    return data


# 2.启停压缩机控制帧(11Byte)
def compressor_control_frame(addr, compressor_control_data):
    """
    :param addr: 16进制的设备地址,范围:OX1~OX78,类型为int
    :param compressor_control_data: bool类型,True为启动,False为停止
    :return:
    """
    if compressor_control_data:
        control_byte = pack('B', 1)
    else:
        control_byte = pack('B', 0)
    data = packet_data_to_frame(addr, 2, control_byte)
    # print(len(data))
    print(f"启停压缩机控制帧发送:{data},长度为:{len(data)}")
    return data


# 3.开锁帧(12Byte)
def box_control_frame(addr, box_control_data):
    """
    :param addr:16进制的设备地址,范围:OX1~OX78
    :param box_control_data: 抽屉控制数据列表[]
    :return:返回一个12bytes的数据帧
    """
    byte1 = 0
    byte2 = 0
    # 字节处理,方法:将box_control_data的前八位取出,将这8位作为一个整体,转成10进制
    for i in range(8):
        byte1 += box_control_data[i] * 2 ** i
    for i in [8, 9]:
        byte2 += box_control_data[i] * 2 ** (i - 8)
    # 数据帧封装
    # print(byte1.to_bytes(1, 'big') + byte2.to_bytes(1, 'big'))
    data = packet_data_to_frame(addr, 3, byte1.to_bytes(1, 'big') + byte2.to_bytes(1, 'big'))
    print(f"开锁帧发送:{data},长度为:{len(data)}")
    # print(f"封装好的开锁帧:{data}")
    return data


# 4. 设置温度帧(11Byte)
def set_temperature_frame(addr, set_temperature_data):
    """
    :param addr: 16进制的设备地址,范围:OX01~OX78
    :param set_temperature_data: 温度数据类型为int
    :return: 返回一个11bytes的数据帧
    """
    temp = temp_convert(set_temperature_data)
    data = packet_data_to_frame(addr, 4, temp.to_bytes(1, 'big'))
    # 将res转成bytes类型
    print(f"设置温度帧发送:{data},长度为:{len(data)}")
    return data


# 5. 设置参数帧(28Byte)
def set_parameter_frame(addr, set_parameter_data):
    """
    :param addr: 16进制的设备地址,范围:OX01~OX78
    :param set_parameter_data: 参数数据列表,类型为字典
    :return: 返回一个28bytes的数据帧
    """
    # 参数数据列表
    dev_id = set_parameter_data['dev_code']  # 设备ID
    # 判断dev_id是否是字符串
    if isinstance(dev_id, str):
        dev_id = int(dev_id, 16).to_bytes(5, 'big')
    dev_addr = set_parameter_data['dev_addr'].to_bytes(1, 'big')  # 设备地址
    time_gap = set_parameter_data['time_gap'].to_bytes(1, 'big')  # 时间间隔
    compressor_delay = set_parameter_data['compressor_delay'].to_bytes(1, 'big')  # 压缩机延时
    set_temp = temp_convert((set_parameter_data['set_temp'])).to_bytes(1, 'big')  # 设定温度
    temp_control = set_parameter_data['temp_control'].to_bytes(1, 'big')  # 温度控制
    res = dev_id + dev_addr + b'\x00' + time_gap + compressor_delay + b'\x00\x00' + set_temp + temp_control \
          + b'\xFF\xFF\xFF\xFF\x00'
    print(len(res), res)
    data = packet_data_to_frame(addr, 5, res)
    print(f"设置参数帧发送:{data},长度为:{len(data)}")
    return data


# 6. 设置温度控制偏差帧(11Byte)
def set_temperature_control_deviation_frame(addr, set_temperature_control_deviation_data):
    """
    :param addr: 16进制的设备地址,范围:OX01~OX78
    :param set_temperature_control_deviation_data: int类型的数据,温控偏差值
    :return:返回一个11bytes的数据帧
    """
    data = packet_data_to_frame(addr, 6, set_temperature_control_deviation_data.to_bytes(1, 'big'))
    print(f"设置温度控制偏差帧发送:{data},长度为:{len(data)}")
    return data


# 7. 设置设备地址帧(16Byte)
def set_device_address_frame(addr, dev_code_data):
    """
    :param addr: 设备地址
    :param dev_code_data: 设备代码bytes类型
    :return: 返回一个16bytes的数据帧
    """
    # 如果dev_code_data是字符串,则转成bytes类型
    if isinstance(dev_code_data, str):
        dev_code_data = int(dev_code_data, 16).to_bytes(5, 'big')
    data = packet_data_to_frame(addr, 7, dev_code_data + addr.to_bytes(1, 'big'))
    print(f"设置设备地址帧发送:{data},长度为:{len(data)}")
    return data


# crc16算法
def crc_check(data_bytes):
    """
    :param data_bytes: bytes类型的字符串
    :return: 返回一个int类型的校验值
    """
    crc_16 = 0xFFFF
    for pos in data_bytes:
        # print(pos)
        crc_16 ^= pos  # 每一个数据与CRC寄存器进行异或
        for i in range(len(data_bytes)):  # 循环计算每一个数据
            if (crc_16 & 1) != 0:  # 判断最后一位是否为1
                crc_16 >>= 1  # 右移一位
                crc_16 ^= 0xA001  # 异或A001
            else:
                crc_16 >>= 1  # 右移一位
    return eval(hex(((crc_16 & 0xff) << 8) + (crc_16 >> 8)))  # 返回校验值


# 温度值处理
def temp_convert(set_temperature_data):
    # 将set_temperature_data转成浮点数
    set_temperature_data = float(set_temperature_data)
    s = str(set_temperature_data).split('.')
    add_bit1 = '0'  # 整数部分的符号位7th
    add_bit2 = '0'  # 小数部分的符号位0th
    if int(s[0]) < 0:
        add_bit1 = '1'
    num1 = abs(int(s[0]))  # 整数部分,取绝对值
    num2 = int(s[1])  # 小数部分
    if num2 >= 5:
        add_bit2 = '1'
    # print(f"整数部分符号位{add_bit2}, 小数部分符号位{add_bit1}")
    # 将num1转成2进制
    res = bin(num1)
    print(res)
    res_list = list(res)
    res_list.insert(2, add_bit1)
    res_list.insert(len(res_list) + 1, add_bit2)
    for i in range(10 - len(res_list)):  # 补齐10位
        res_list.insert(3, '0')
    res = ''.join(res_list)
    print(res_list)
    res = int(res, 2)
    return res

数据帧接收

receive.py

# 数据接收
import serial
from send import send_compressor_control_frame
from data_struct import *


# 定义状态帧字典
def receive_data(com):  # 接收数据线程
    while True:
        # if soft_status.ui.sys_on_btn.isEnabled():
        com_data = com.read(80)
        res = receive_frame(com_data)
        for r in res:
            if r[2] == 0x2C:
                control_table_attributes['dev_code'] = r[6:11]
                control_table_attributes['addr'] = r[11]
                control_table_attributes['time_gap'] = r[13]
                control_table_attributes['compressor_delay'] = r[14]
                control_table_attributes['temp_set'] = r[17]
                control_table_attributes['temp_control'] = r[18]
                print(f"control_table_attributes{control_table_attributes}")
                control_table_status['dev_code'] = r[24:29]
                control_table_status['sys_status'] = r[29]
                control_table_status['compressor_status'] = r[31]
                control_table_status['temp_set'] = r[32]
                control_table_status['current_temp'] = r[33]
                control_table_status['box_status'] = r[36:38]
                print(f"control_table_status:{control_table_status}")
                temp_now = get_temp(control_table_status['current_temp'])
                print(f"当前温度:{temp_now}")
                compressor_control(temp_now, com)


def get_temp(temp_now):
    if temp_now > 128:
        temp_convert = '{:0>8}'.format(str(bin(temp_now))[3:])
        temp_convert = str(int(temp_convert[1:7], 2) + 1 / 2 * int(temp_convert[7], 2))
        temp_convert = '-' + temp_convert
        return temp_convert
    else:
        temp_convert = '{:0>8}'.format(str(bin(temp_now))[2:])
        # print(temp_convert)
        temp_convert = str(int(temp_convert[1:7], 2) + 1 / 2 * int(temp_convert[7], 2))
        return temp_convert


# 压缩机控制
def compressor_control(temp_now, com):
    # if soft_status.ui.compressor_btn_on_clicked.isEnabled():
    # 如果温度低于当前值
    # check_num = control_table_attributes['compressor_delay']
    flag_temp1 = float(get_temp(control_table_status['temp_set'])) - control_table_attributes['temp_control'] + 1
    flag_temp2 = float(get_temp(control_table_status['temp_set'])) + control_table_attributes['temp_control'] - 1
    if float(temp_now) <= flag_temp1:
        send_compressor_control_frame(com, False)
        # print("关闭压缩机")
    # 如果温度高于当前值
    if float(temp_now) >= flag_temp2:
        send_compressor_control_frame(com, True)
        # print("打开压缩机")
    # else:
    #     send_compressor_control_frame(com, False)


def receive_frame(hex_datas):  # 匹配帧头和帧尾,获取匹配成功的帧
    res_frame = []
    for i in range(0, len(hex_datas) - 1):
        if hex_datas[i] == 0xFF and hex_datas[i + 1] == 0xFF:
            for j in range(i, len(hex_datas) - 1):
                if hex_datas[j] == 0xFF and hex_datas[j + 1] == 0xF7:
                    result = hex_datas[i:j + 2]
                    if len(result) == 14 or len(result) == 44:
                        res_frame.append(result)
    return res_frame  # 返回匹配成功的帧(列表)

相关数据结构

data_struct.py

data_control_set = {
    'dev_code': '0xFFFFFFFFFF',  # type: bytes
    'dev_addr': 0x01,
    'time_gap': 0x01,
    'compressor_delay': 0x1e,
    'set_temp': 4.0,
    'temp_control': 0x02,
}
control_table_status = {
    'dev_code': b'\xFF\xFF\xFF\xFF\xFF',  # 设备ID比特流
    'sys_status': 0x00,  # 二位十六进制数表示一个比特
    'compressor_status': 0x00,
    'temp_set': 0x00,
    'current_temp': 0x00,
    'box_status': b'\x00\x00',
}
control_table_attributes = {
    'dev_code': b'\xFF\xFF\xFF\xFF\xFF',
    'addr': 0x01,
    'time_gap': 0x01,
    'compressor_delay': 0x1E,
    'temp_set': 0x00,
    'temp_control': 0x02,
}
  • 4
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
### 回答1: 大型冷库系统的过程控制框架包括以下几个方面: 1. 冷库控制中心:冷库控制中心是整个冷库系统的大脑,通过对温度、湿度、氧气浓度等参数进行实时监控和调度。控制中心触发传感器检测数据,通过先进的算法计算最优化空调系统运转方式来满足极端气候或外部环境变化对冷库系统的影响。 2. 传感器:控制中心需要实时监控的参数通过传感器进行采集,采集参数包括温度、湿度、氧气浓度以及可能的有害气体浓度等。 3. 数据采集模块:控制中心需要实时监控的参数需要进行采集和传输。控制中心预先设置好了参数范围,并将采集到的数据与参数范围进行比较来确定操作,如果参数不符合范围则控制中心依据不同派生策略出最优化解决措施。 4. 过程控制模块:过程控制模块是整个控制中心的关键组成部分,负责进行空调系统的CONTROL(开+停),以及空调系统的MODE(制冷+制热),针对不同的材质、储物条件、客户需求以及政策体系等因素,控制中心预先设计了空调控制策略来来满足需求,采用遗传算法优化空调控制行为,保障进出库物品的物理及化学特性尽可能被保留和消耗均相。 大型冷库系统的工作原理是:通过一个高度自动化的系统,通过电子设备和传感器来控制冷库内部的环境参数,这些参数涵盖了温度、湿度和有害气体浓度等。通过一个控制中心,利用现代化算法和软件控制冷库设备,来保持恒定的环境条件,同时确保进出库冷却物品空气质量及储物效果的达标与卓越。 这种高度自动化的流程控制系统能够保持恒定的环境参数,保证冷库物品的品质并提高了整个系统的能效。 ### 回答2: 大型冷库系统是用于存储和保鲜食品等物品的重要设备。其过程控制框架包括传感器、控制器和执行器三个主要组件。 首先,传感器是冷库系统感知器,负责收集环境参数和物品信息的数据。常见的传感器包括温度传感器、湿度传感器、二氧化碳传感器等。这些传感器通过无线传输或有线传输等方式将数据传输给控制器。 其次,控制器是冷库系统的大脑,根据传感器采集的数据和预设的控制策略,对冷库的运行状态进行控制和调节。控制器通过处理传感器数据,判断冷库内的温度、湿度等环境因素是否满足设定要求,并发出相应的控制指令。 最后,执行器是冷库系统的执行部分,根据控制器发送的指令来实现控制目标。常见的执行器包括冷却系统、风扇、阀门等。例如,当温度超过设定值时,控制器会发送指令给冷却系统启动,以降低冷库内的温度。 整个大型冷库系统的工作原理如下:传感器不断采集环境参数和物品信息的数据,传输给控制器。控制器根据预设的控制策略,判断当前环境是否符合要求,如果不符合,会发出相应指令给执行器。执行器根据接收到的指令,实现温度调节、湿度调节等操作。控制器会持续监测环境数据和执行器的状态,并根据需要做出调整,直到达到预设的运行目标。 总之,大型冷库系统的过程控制框架包括传感器、控制器和执行器三个部分。传感器用于感知环境参数和物品信息的数据,控制器根据传感器数据和控制策略对冷库系统进行控制和调节,执行器根据控制器指令实现相应的操作。这种框架保证了冷库系统的稳定运行和物品保鲜质量。 ### 回答3: 大型冷库系统的过程控制框架包括传感器、控制器和执行器三个主要组成部分。 首先是传感器,它们用于检测冷库内的温度、湿度、压力等参数。常用的传感器有温度传感器、湿度传感器和压力传感器等。这些传感器会将检测到的数据转化为电信号并传送给控制器。 其次是控制器,它是冷库系统的核心部件。控制器接收传感器发来的信号,并根据预设的控制策略进行分析和判断。控制器根据设定的目标值来控制冷库内的温度、湿度和压力等要素,确保冷库内的环境保持在理想的状态。 最后是执行器,它们负责根据控制器的命令实施相应的动作。常见的执行器有压缩机、风机、阀门等。例如,在控制温度时,控制器会根据传感器数据的反馈,通过控制压缩机的开启和关闭来调节冷库内的温度。 大型冷库系统的工作原理是基于控制器的反馈和执行器的动作来实现的。首先,控制器会根据预设的温度要求和当前温度进行比较,并计算出温度差值。然后,根据这个差值,控制器会决定是否开启或关闭执行器。控制器不断接收传感器发来的信号,同时根据设定的控制策略对执行器进行命令操作,以保持冷库内的温度、湿度和压力等参数在合适的范围内。 总而言之,大型冷库系统的过程控制框架是由传感器、控制器和执行器组成,并通过控制器的分析和判断,结合执行器的动作来实现对冷库内环境的精确控制。这种控制框架可以实现自动化、高效率和稳定性的运行,提高冷库系统的效能。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Cles8it

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值