继电器介绍及qt操作继电器实战

一.继电器基础介绍

32路继电器通常用于自动化控制系统中,能够同时控制多达32个不同的电气设备。以下是对32路继电器的一些详细介绍:

1. 基本概念

  • 继电器:一种电气控制装置,当输入信号(通常是电流或电压)达到一定标准时,继电器会启动并控制电路的打开或关闭。
  • 路数:指可控制的通道数量,32路继电器意味着该设备可以独立控制32个负载。

2. 工作原理

  • 电气原理:当继电器的线圈通电时,内部的机械开关闭合(或断开),从而控制负载的电流流通。
  • 控制信号:通常采用微控制器、PLC、计算机等控制设备来发送控制信号。

3. 构成部分

  • 继电器模块:包括多个继电器和电路的集成,通常设计为插拔式或模块化,便于扩展和维护。
  • 控制接口:可以是USB、串口、GPIO等,用于与控制系统进行通信。
  • 电源供应:需要提供适当的工作电压(如5V、12V、24V等),以保证继电器正常工作。

4. 应用领域

  • 工业自动化:用于机器设备的控制,如电机启停、灯光控制等。
  • 家居自动化:用于智能家居系统中,控制家居设备如灯光、空调等。
  • 安防系统:用于监控设备或警报系统的控制。
  • 实验室设备:在实验过程中实现对不同设备的精准控制。
    5. 优缺点
  1. 优点:
  • 同时控制多个设备,提高工作效率。
  • 提供远程控制和自动化功能。
  • 适应性强,模块化设计便于扩展。
  1. 缺点:
  • 可能需要额外的电源管理。
  • 对电路的要求较高,确保不出现故障。
  • 如果控制信号不稳定,可能导致误动作。

6. 注意事项

  • 在选择和使用32路继电器时,需要注意电气参数(如负载电压和电流),确保其适用性和安全性。
  • 适当的散热必须考虑,尤其在同时控制多个高功率负载时。
  • 有些继电器需要额外的保护电路(如瞬时保护、延时启动等)。

7. 协议

二.项目相关展示

1. 继电器的选择

  • 这里的继电器选择的是32路继电器
  • 对应继电器的通信不需要进行引入多余的库,使用本地的 QSerialPort 模块就行,不过如果有modbus当然更建议使用modbus库。

三.项目代码

  • 我这个代码写的很粗糙,仅供参考。
cpp 复制代码
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include<Windows.h>


MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    Init();
}

MainWindow::~MainWindow()
{
    if (serial.isOpen()) {
        serial.close();
    }
    delete ui;
}

void MainWindow::Init()
{

    // 对串口进行初始化
    serial.setPortName("COM3");
    serial.setBaudRate(QSerialPort::Baud9600); // 设置波特率
    serial.setDataBits(QSerialPort::Data8);    // 设置数据位
    serial.setParity(QSerialPort::NoParity);    // 设置奇偶校验
    serial.setStopBits(QSerialPort::OneStop);    // 设置停止位
    serial.setFlowControl(QSerialPort::NoFlowControl); // 设置流控制
    if (serial.open(QIODevice::ReadWrite)) {
        qDebug() << "Serial port opened successfully.";
    } else {
        qDebug() << "Failed to open serial port.";
    }
    //          01                69
    // 命令:55 %1 13 00 00 00 00 %2
    //55 01 13 00 00 00 00 69
}


void MainWindow::on_pushButton_open_clicked()
{
    // 将和转换为十六进制字符串
    //QString hexString = QString::number(sum, 16).toUpper();

    int last=0x88;// 打开 继电器 前面 指令 字节 数 之和
    // 计算 最后一个 数
    last+=ui->spinBox_open->value();
    QString hexString = QString::number(last, 16).toUpper();

    // 组装 指令
    QString commend="55 01 32 00 00 00";
    if(ui->spinBox_open->value()>0&&ui->spinBox_open->value()<10)
    {
        // 添加 零
        commend+=" ";
        commend+=("0"+QString::number(ui->spinBox_open->value()));
        commend+=" ";
        commend+=hexString;

        ui->textEdit->append("open commend = "+commend);
    } else
    {
        // 不 添加0
        commend+=" ";
        if(ui->spinBox_open->value()>=10&&ui->spinBox_open->value()<16)
        {
            commend+="0";
        }
        commend+=(QString::number(ui->spinBox_open->value(),16).toUpper());
        commend+=" ";
        commend+=hexString;
        ui->textEdit->append("open commend = "+commend);
    }
    serial.write(QByteArray::fromHex(commend.toLatin1().data())); // 发送指令打开继电器


}

void MainWindow::on_pushButton_close_clicked()
{
    // 将和转换为十六进制字符串
    //QString hexString = QString::number(sum, 16).toUpper();

    int last=0x87;// 打开 继电器 前面 指令 字节 数 之和
    // 计算 最后一个 数
    last+=ui->spinBox_close->value();
    QString hexString = QString::number(last, 16).toUpper();

    // 组装 指令
    QString commend="55 01 31 00 00 00";
    if(ui->spinBox_close->value()>0&&ui->spinBox_close->value()<10)
    {
        // 添加 零
        commend+=" ";
        commend+=("0"+QString::number(ui->spinBox_close->value()));
        commend+=" ";
        commend+=hexString;

        ui->textEdit->append("close commend = "+commend);
    } else
    {
        // 不 添加0
        commend+=" ";
        if(ui->spinBox_close->value()>=10&&ui->spinBox_close->value()<16)
        {
            commend+="0";
        }
        commend+=(QString::number(ui->spinBox_close->value(),16).toUpper());
        commend+=" ";
        commend+=hexString;
        ui->textEdit->append("open commend = "+commend);
    }
    serial.write(QByteArray::fromHex(commend.toLatin1().data())); // 发送指令打开继电器

}




void MainWindow::on_pushButton_req_clicked()
{
//    serial.write("1");
//    ui->textEdit->append("继电器请求状态");
    serial.write("?");
    ui->textEdit->append("request");
    if (serial.waitForReadyRead(1000))
    {
         QByteArray responseData = serial.readAll();
         while (serial.waitForReadyRead(100))
         {
             responseData += serial.readAll();
         }
         qDebug() << "接收到响应: " << responseData;
    } else
    {
         qDebug() << "没有接收到数据!";
    }

}

void MainWindow::on_pushButton_read_clicked()
{
    QByteArray data = serial.readAll();
    if (!data.isEmpty())
    {
        ui->textEdit->append(data);
    } else
    {
        ui->textEdit->append("读取信息为空");
    }
}

void MainWindow::on_pushButton_send_clicked()
{
    //QString command=ui->lineEdit_send->text();
    QString _qstrData=ui->lineEdit_send->text();


    //QByteArray commandBytes = command.toUtf8();
    serial.write(QByteArray::fromHex(_qstrData.toLatin1().data()));
    if (serial.waitForBytesWritten(1000))
    {
        ui->textEdit->append("send:"+_qstrData);
    }

    // 全部闭合 55 01 33 FF FF FF FF 85
    // 全部断开 55 01 33 00 00 00 00 89

}

四.协议详细分析

1. 55 01 32 00 00 00 01 89

  • 32路每一路代表一位,这里01代表的十六进制,总共是有8位。

  • 这里高位字节在前,低位字节在后。

  • 前面的01代表的是 0000 0001,低位的这一个字节以表示所有的位。0x32这个功能码代表闭合某一路。

2. 55 01 35 00 00 00 15 A0(同时打开1,3,5)‬

  • 假如我要打开135路的开关,这里要使用功能码0x35,则低位部分为0001 0101,此时组合成16进制为0x15,所以打开135命令为55 01 35 00 00 00 15 A0
  • 对于校验位:是前面几位十六进制的和A0
  • 0000 0000

3. 大端序(Big-Endian)和 小端序(Little-Endian)

在十六进制表示中,通常高位和低位的顺序取决于具体的上下文,特别是数据的存储格式(例如大端序和小端序)。

  • 大端序(Big-Endian): 最高有效位(高位)在前面,最低有效位(低位)在后面。
  • 小端序(Little-Endian): 最高有效位(高位)在后面,最低有效位(低位)在前面。

对于你的例子 00 00 00 01:

  1. 大端序存储 :
    • 表示为:00 00 00 01
    • 高位在前,低位在后。
    • 高位是 00,低位是 01
  2. 小端序存储 :
    • 表示为:01 00 00 00
    • 高位在后,低位在前。
    • 高位是 01,低位是 00
  • 结论

如果没有特定的上下文来指明是使用大端还是小端,单独看 00 00 00 01 这个序列,一般可以认为第一个 00 是高位(在大端序的情况下),而 01 是低位。若用于存储或传输,需确认具体的字节序以便正确解析。

相关推荐
XiaoLeisj2 小时前
【JavaEE初阶 — 多线程】单例模式 & 指令重排序问题
java·开发语言·java-ee
励志成为嵌入式工程师3 小时前
c语言简单编程练习9
c语言·开发语言·算法·vim
捕鲸叉3 小时前
创建线程时传递参数给线程
开发语言·c++·算法
A charmer3 小时前
【C++】vector 类深度解析:探索动态数组的奥秘
开发语言·c++·算法
Peter_chq3 小时前
【操作系统】基于环形队列的生产消费模型
linux·c语言·开发语言·c++·后端
记录成长java5 小时前
ServletContext,Cookie,HttpSession的使用
java·开发语言·servlet
前端青山5 小时前
Node.js-增强 API 安全性和性能优化
开发语言·前端·javascript·性能优化·前端框架·node.js
睡觉谁叫~~~5 小时前
一文解秘Rust如何与Java互操作
java·开发语言·后端·rust
音徽编程5 小时前
Rust异步运行时框架tokio保姆级教程
开发语言·网络·rust
观音山保我别报错5 小时前
C语言扫雷小游戏
c语言·开发语言·算法