基于ModebusRTU通信采集温度湿度项目案例
目录
一、模拟温湿度模拟
【1.1】温湿度仪表参数
【1.1】使用电脑模拟传感器
【1.2】使用Codesys软件模拟传感器
二、自定义控件UI设计
【2.1】自定义控件温度湿度柱状设计
编辑
【2.1.1】设置温度湿度柱状实际显示【属性】
【2.1.2】设置温度湿度柱状的背景颜色【属性】
三、窗体UI设计
四、实现Modbus通讯源码
【4.1】读取保持寄存器读取测试
【4.2】封装读取保持寄存器类
五、窗体UI后端代码
六、测试效果
【6.1】与电脑模拟
【6.2】与Codesys模拟
一、模拟温湿度模拟
【1.1】温湿度仪表参数

【1.1】使用电脑模拟传感器
-
开启虚拟串口

-
通过串口调试助手测试客户端和服务器



走到这里说明这组参数是可以成功的。
【1.2】使用Codesys软件模拟传感器
-
配置Codesys控制器为从站

-
通过串口调试助手测试客户端和服务器,注意:PLC和仪表寄存器定位不同,Codesys需要用0x04功能码读取IW寄存器的值。


二、自定义控件UI设计
【2.1】自定义控件温度湿度柱状设计
第一步:创建类库项目,创建用户控件Windows(窗体)
第二步:创建一个panel控件,用于与图片配合,panel控件的大小需要比被设计图片的大小相等或者大于。panel控件属性设计->BackgroundImage 背景图像:导入图片。Size 调整控件大小尺寸:需要比图片大或者相等。BackgroundImageLayout 背景图像布局:Tile 图像沿控件的矩形工作区平铺。
【2.1.1】设置温度湿度柱状实际显示【属性】
【设计思路】

第一步:拖动Label控件充当白色部分。Label控件属性设计->Name 标识对象名称:lblBarAutoSize 关闭自动调整大小:falseSzie 调整控件合适大小->Width(9)Height(135)BackColor 背景颜色:白色
【控件后台代码】
// 设置温度湿度柱状显示和实际温度湿度显示【属性】
private const float _barHightValue = 135.0F;
private float _barHightMemory = 0.0F;
public float BarHightValue
{get{return _barHightMemory;}set{if(value < 0 || value > 70){MessageBox.Show("温度值或湿度值必须在0~70之间!", "信息提示");}else{// 根据value计算实际(颜色bar)需要的像素显示大小float fRealValue = (_barHightValue / 70) * value;// 求出(白色bar)需要的像素显示大小this.lblBar.Height = Convert.ToInt32(_barHightValue - fRealValue);}_barHightMemory = value;}
}
【Form页测试】

【2.1.2】设置温度湿度柱状的背景颜色【属性】
第一步:在Resources文件夹下添加图片资源。

【控件后台代码】
// 设置温度湿度柱状的背景颜色【属性】
public enum BarColor
{Red,Green
}private BarColor _barImageColor = BarColor.Green;
public BarColor BarImageColor
{get{return _barImageColor;}set{// 设置用户选择的颜色对应图片if (value == BarColor.Red)this.panel.BackgroundImage = Properties.Resources.red_all;else if (value == BarColor.Green)this.panel.BackgroundImage = Properties.Resources.green_all;_barImageColor = value;}
}
【Form页测试】

三、窗体UI设计
第一步:窗体的Text属性->基于ModbusRTU通讯实现温度、湿度实时采集案例
第二步:窗体的Icon属性->选择窗体图标
第三步:窗体的MaxximizeBox 设置false
第四步:窗体的StartPosition 设置CenterScreen
第五步:窗体的FormBorderStyle 设置不可调整大小的工具窗口边框。第六步:自定义的温度湿度柱控件->湿度Name ccMeterH 温度Name ccMeterT第七步:温度湿度字体Label标签->Font 字体设置:华文楷体, 14.25pt, style=Bold第八步:温度湿度数值Label标签->湿度Name lblHumidityValue温度Name lblTemperatureValueFont 字体设置 华文楷体, 14.25pt, style=BoldFontColor 字体颜色设置 LimeAutoSize 设置falseTextAlign 设置MiddleCenter中间位置

第一步:容器控件GroupBox控件->Text 设备连接第二步:端口号 波特率 站地址Label控件->Text 端口号 波特率 站地址Font 微软雅黑, 15.75pt第三步:端口号ComboBox控件->Name cobPort第四步:波特率ComboBox控件->Name cobBaudRate第五步:站地址NumericUpDown->Name nudSlaveAddress第六步:状态Label->Name lalStateText 设置文字●ForeColor 设置字体颜色Gray第七步:打开断开连接Button按钮Name btnOpenAndCloseText 设置文字 打 开 连 接Font 设置字体样式 微软雅黑, 14.25pt, style=BoldFlatStyle 设置按钮样式Flat该控件以平面显示FlatAppearance->BorderSize设置按钮周围的边框的大小0ForeColor 设置文字颜色ButtonFaceBackColor 设备按钮背景颜色Green[Click] 单击事件

// 这里提前脱取组件定时器timer->Name timerModbusReadinterval 设置定时器1000毫秒[Tick] 定时事件
四、实现Modbus通讯源码
【4.1】读取保持寄存器读取测试

// 命名空间
using System.IO.Pipes;/* 程序入口函数 */
static void Main(string[] args)
{// [1] 创建串行端口资源对象SerialPort serialPort = new SerialPort();// [2] 设置协议属性serialPort.PortName = "COM1"; // 设置端口号 COM1serialPort.BaudRate = 9600; // 设置波特率 9600serialPort.Parity = Parity.None; // 设置校验 无校验serialPort.DataBits = 8; // 设置数据位 8serialPort.StopBits = StopBits.One; // 设置停止位 1// [3] 打开串口serialPort.Open();while(true){// 将当前线程挂起等待一定时间Thread.Sleep(1000); // [4] 拼接报文byte[] sendBytes = new byte[]{// 站地址 功能码 起始地址 数据长度 CRC校验0x01, 0x03, 0x00, 0x00, 0x00, 0x02, 0xC4, 0x0B};// [5] 发送报文serialPort.Write(sendBytes, 0, sendBytes.Length);Thread.Sleep(100); // 将当前线程挂起等待一定时间(通讯时间需要延时接收)// [6] 接受报文byte[] recvBytes = new byte[serialPort.BytesToRead]; // BytesToRead获取接收缓冲区字节个数。serialPort.Read(recvBytes, 0, recvBytes.Length);// [7] 解析恢复报文 - 当前寄存器的值是:40001[FE = 254] 40002[AF = 175]if (recvBytes[0] == 0x01 && recvBytes[1] == 0x03){// 解析前分析// 发:// 源报文16进制:01 03 00 00 00 02 C4 0B// 发报文10进制: 1 3 0 0 0 2 196 176// 收:// 源报文16进制:01 03 04 00 FE 00 AF DB BF// 发报文10进制: 1 3 4 0 254 0 175 219 191 // 字节到10进制高低位转换:收报文其中[0 254] = (254/256)=0 (254%256)=254// 收报文其中[0 175] = (175/256)=0 (175%256)=175// 开始解析// 湿度 = 高字节 * 256 + 低字节int iHumidity = recvBytes[3] * 256 + recvBytes[4];// 温度 = 高字节 * 256 + 低字节int iTempperature = recvBytes[5] * 256 + recvBytes[6];Console.WriteLine($"湿度:{iHumidity * 0.1}% 温度:{iTempperature * 0.1}℃");}}
}// 读取的打印结果:
湿度:25.4% 温度:17.5℃
湿度:25.4% 温度:17.5℃
湿度:25.4% 温度:17.5℃
湿度:25.4% 温度:17.5℃
湿度:25.4% 温度:17.5℃
湿度:25.4% 温度:17.5℃
【4.2】封装读取保持寄存器类
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;using System.IO.Ports;
using System.Threading;
namespace Approach.TemperatureHumidity.DAL
{/// <summary>/// ModbusRTU通讯类封装/// </summary>public class ModbusRTU{/// <summary>/// 串口资源对象字段/// </summary>private SerialPort serialPort = null; /// <summary>/// 无参构造方法/// </summary>public ModbusRTU() {}/// <summary>/// 带参构造方法/// </summary>/// <param name="delay"></param>public ModbusRTU(int delay){this.ReceiveDelay = delay; }/// <summary>/// 接收报文延时时间属性/// </summary>private int _receiveDelay = 100;public int ReceiveDelay{get {return _receiveDelay;}set{if(value < 10 || value > 2000)_receiveDelay = 100;else_receiveDelay = value; }}/// <summary>/// 打开串口/// </summary>/// <param name="portName"> 串行端口号 </param>/// <param name="baudRate"> 波特率 </param>/// <param name="parity"> 校验位 </param>/// <param name="dataBits"> 数据位 </param>/// <param name="stopBits"> 停止位 </param>public void Connect(string portName, int baudRate = 9600, Parity parity = Parity.None, int dataBits = 8, StopBits stopBits = StopBits.One){//>实例化串口资源对象serialPort = new SerialPort(portName, baudRate, parity, dataBits, stopBits);//>异常保护try{//>打开串口serialPort.Open();}catch(Exception ex){throw new Exception("ModbusRTU打开串口失败:" + ex.Message);}}/// <summary>/// 关闭串口/// </summary>public void Disconnect() {//>确认串口已打开if(serialPort != null && serialPort.IsOpen){//>关闭串口serialPort.Close();}}/// <summary>/// 读取保持寄存器->功能码0x03/// </summary>/// <param name="slaveId"> 从站地址 </param>/// <param name="startAddress"> 读取起始地址 </param>/// <param name="count"> 读取寄存器数量 </param>/// <returns> </returns>public byte[] ReadHoldingRegister(byte slaveId, int startAddress, int count){// [1] 封装【请求】报文byte[] sendBytes = new byte[8];// 从站地址sendBytes[0] = slaveId;// 功能码sendBytes[1] = 0x03;// 起始寄存器sendBytes[2] = (byte)(startAddress / 256); //>高位sendBytes[3] = (byte)(startAddress % 256); //>低位// 寄存器数量sendBytes[4] = (byte)(count / 256);sendBytes[5] = (byte)(count % 256);// CRC校验码byte[] crcBytes = CRC16(sendBytes, 6);sendBytes[6] = crcBytes[0];sendBytes[7] = crcBytes[1];// 异常处理byte[] recvBytes = null;try{// [2] 发送【请求】报文serialPort.Write(sendBytes, 0, sendBytes.Length);Thread.Sleep(ReceiveDelay);// [3] 接收【应答】报文recvBytes = new byte[serialPort.BytesToRead]; //>BytesToRead: 获取接收缓冲区字节个数。serialPort.Read(recvBytes, 0, recvBytes.Length);}catch(Exception ex){throw new Exception("ModbusRTU发送或接收报文出现问题:" + ex.Message);}// [4] 解析【应答】报文int dataByteLen = 2 * count; //>响应报文数据字节数长度if (recvBytes.Length == 5 + dataByteLen){// CRC校验正确 && 响应报文功能码正确 && 响应报文数据字节正确if (CheckCRC(recvBytes) && recvBytes[1] == 0x03 && recvBytes[2] == dataByteLen){// 截取数据:去掉[从站地址][功能码][字节计数]...[CRC校验]byte[] returnBytes = new byte[dataByteLen];// 数组复制出需要的数据Array.Copy(recvBytes, 3, returnBytes, 0, dataByteLen);return returnBytes;}return null;}return null;}#region CRC校验【查表法 - 速度很快】private static readonly byte[] aucCRCHi = {0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,0x00, 0xC1, 0x81, 0x40};private static readonly byte[] aucCRCLo = {0x00, 0xC0, 0xC1, 0x01, 0xC3, 0x03, 0x02, 0xC2, 0xC6, 0x06, 0x07, 0xC7,0x05, 0xC5, 0xC4, 0x04, 0xCC, 0x0C, 0x0D, 0xCD, 0x0F, 0xCF, 0xCE, 0x0E,0x0A, 0xCA, 0xCB, 0x0B, 0xC9, 0x09, 0x08, 0xC8, 0xD8, 0x18, 0x19, 0xD9,0x1B, 0xDB, 0xDA, 0x1A, 0x1E, 0xDE, 0xDF, 0x1F, 0xDD, 0x1D, 0x1C, 0xDC,0x14, 0xD4, 0xD5, 0x15, 0xD7, 0x17, 0x16, 0xD6, 0xD2, 0x12, 0x13, 0xD3,0x11, 0xD1, 0xD0, 0x10, 0xF0, 0x30, 0x31, 0xF1, 0x33, 0xF3, 0xF2, 0x32,0x36, 0xF6, 0xF7, 0x37, 0xF5, 0x35, 0x34, 0xF4, 0x3C, 0xFC, 0xFD, 0x3D,0xFF, 0x3F, 0x3E, 0xFE, 0xFA, 0x3A, 0x3B, 0xFB, 0x39, 0xF9, 0xF8, 0x38,0x28, 0xE8, 0xE9, 0x29, 0xEB, 0x2B, 0x2A, 0xEA, 0xEE, 0x2E, 0x2F, 0xEF,0x2D, 0xED, 0xEC, 0x2C, 0xE4, 0x24, 0x25, 0xE5, 0x27, 0xE7, 0xE6, 0x26,0x22, 0xE2, 0xE3, 0x23, 0xE1, 0x21, 0x20, 0xE0, 0xA0, 0x60, 0x61, 0xA1,0x63, 0xA3, 0xA2, 0x62, 0x66, 0xA6, 0xA7, 0x67, 0xA5, 0x65, 0x64, 0xA4,0x6C, 0xAC, 0xAD, 0x6D, 0xAF, 0x6F, 0x6E, 0xAE, 0xAA, 0x6A, 0x6B, 0xAB,0x69, 0xA9, 0xA8, 0x68, 0x78, 0xB8, 0xB9, 0x79, 0xBB, 0x7B, 0x7A, 0xBA,0xBE, 0x7E, 0x7F, 0xBF, 0x7D, 0xBD, 0xBC, 0x7C, 0xB4, 0x74, 0x75, 0xB5,0x77, 0xB7, 0xB6, 0x76, 0x72, 0xB2, 0xB3, 0x73, 0xB1, 0x71, 0x70, 0xB0,0x50, 0x90, 0x91, 0x51, 0x93, 0x53, 0x52, 0x92, 0x96, 0x56, 0x57, 0x97,0x55, 0x95, 0x94, 0x54, 0x9C, 0x5C, 0x5D, 0x9D, 0x5F, 0x9F, 0x9E, 0x5E,0x5A, 0x9A, 0x9B, 0x5B, 0x99, 0x59, 0x58, 0x98, 0x88, 0x48, 0x49, 0x89,0x4B, 0x8B, 0x8A, 0x4A, 0x4E, 0x8E, 0x8F, 0x4F, 0x8D, 0x4D, 0x4C, 0x8C,0x44, 0x84, 0x85, 0x45, 0x87, 0x47, 0x46, 0x86, 0x82, 0x42, 0x43, 0x83,0x41, 0x81, 0x80, 0x40};private byte[] CRC16(byte[] pucFrame, int usLen){int i = 0;byte[] res = new byte[2] { 0xFF, 0xFF };ushort iIndex;while (usLen-- > 0){iIndex = (ushort)(res[0] ^ pucFrame[i++]);res[0] = (byte)(res[1] ^ aucCRCHi[iIndex]);res[1] = aucCRCLo[iIndex];}return res;}private bool CheckCRC(byte[] value){if (value == null) return false;if (value.Length <= 2) return false;int length = value.Length;byte[] buf = new byte[length - 2];Array.Copy(value, 0, buf, 0, buf.Length);byte[] CRCbuf = CRC16(buf, buf.Length);if (CRCbuf[0] == value[length - 2] && CRCbuf[1] == value[length - 1])return true;return false;}#endregion}
}
五、窗体UI后端代码
using Approach.TemperatureHumidity.DAL;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO.Ports;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;namespace Approach.TemperatureHumidity.App
{public partial class FrmMain : Form{ModbusRTU modbusRtu = new ModbusRTU();#region [窗体启动初始化功能]public FrmMain(){InitializeComponent();Initialize();}/// <summary>/// 初始化所有控件状态/// </summary>private void Initialize(){// 初始化绑定波特率下拉框列表string[] BaudRuteArr = new string[] { "2400", "4800", "9600", "19200", "38400", "57600", "115200" };this.cobBaudRate.DataSource = BaudRuteArr; //>绑定波特率数据源this.cobBaudRate.SelectedIndex = 2; //>默认波特率9600// 初始化绑定端口号下拉框列表this.cobPort.DataSource = SerialPort.GetPortNames(); //>GetPortNames: 静态方法,可以获取当前电脑所有可用的端口号}#endregion#region [打开连接和关闭连接功能]/// <summary>/// 是否已连接->属性[关联btnOpenAndClose_Click]/// </summary>private bool _isConnected = false;public bool IsConnected{get { return _isConnected; }set { _isConnected = value; //>记忆操作的按钮状态// 更改按钮文字内容this.btnOpenAndClose.Text = value ? "断开连接" : "打开连接";// 更改按钮颜色if(value == true){// 按钮背景颜色为红色this.btnOpenAndClose.BackColor = Color.Red;// 按钮字体颜色为白色this.btnOpenAndClose.ForeColor = Color.White;// 状态指示字体颜色为绿色this.lblState.ForeColor = Color.Green; }else{// 按钮背景颜色为红色绿色this.btnOpenAndClose.BackColor = Color.Green;// 按钮字体颜色为白色this.btnOpenAndClose.ForeColor = Color.White;// 状态指示字体颜色为灰色this.lblState.ForeColor = Color.Gray; }}}/// <summary>/// 打开连接和关闭连接按钮->单击事件/// </summary>private void btnOpenAndClose_Click(object sender, EventArgs e){// 接收UI信息string port = this.cobPort.Text;int baudRate = int.Parse(this.cobBaudRate.Text);if (IsConnected == false){try{// 打开ModbusRTU连接modbusRtu.Connect(port, baudRate);// 更改按钮和指示状态IsConnected = true;// 启动定时器读取this.timerModbusRead.Enabled = true;}catch(Exception ex){MessageBox.Show(ex.Message, "错误提示");}}else{// 停止定时器读取this.timerModbusRead.Stop();// 关闭ModbusRTU连接modbusRtu.Disconnect();// 更改按钮和指示状态IsConnected = false;}}#endregion#region [定时器循环读取Modbus寄存器功能]/// <summary>/// 读取Modbus寄存器定时器->定时事件/// </summary>private void timerModbusRead_Tick(object sender, EventArgs e){// 接收UI信息byte slaveAddress = Convert.ToByte(this.nudSlaveAddress.Value);// 读取数据(2个寄存器,起始地址是0000H[40001][40002])byte[] dataBytes = modbusRtu.ReadHoldingRegister(slaveAddress, 0, 2);if(dataBytes != null && dataBytes.Length == 4){// 字节高低位转换// 湿度 = 高字节 * 256 + 低字节int humidity = dataBytes[0] * 256 + dataBytes[1];// 温度 = 高字节 * 256 + 低字节int temperature = dataBytes[2] * 256 + dataBytes[3];// 数值显示this.lblHumidityValue.Text = (humidity * 0.1F).ToString();this.lblTemperatureValue.Text = (temperature * 0.1F).ToString();// 图形显示this.ccMeterH.BarHightValue = humidity * 0.1F;this.ccMeterT.BarHightValue = temperature * 0.1F;}}#endregion#region [窗体关闭初始化功能]private void FrmMain_FormClosing(object sender, FormClosingEventArgs e){// 停止定时器读取timerModbusRead.Stop();}#endregion}
}
六、测试效果
【6.1】与电脑模拟

【6.2】与Codesys模拟

相关文章:
基于ModebusRTU通信采集温度湿度项目案例
目录 一、模拟温湿度模拟 【1.1】温湿度仪表参数 【1.1】使用电脑模拟传感器 【1.2】使用Codesys软件模拟传感器 二、自定义控件UI设计 【2.1】自定义控件温度湿度柱状设计 编辑 【2.1.1】设置温度湿度柱状实际显示【属性】 【2.1.2】设置温度湿度柱状的背景颜色【属…...
【已解决】关于如何将Doccano标注的文本转换成NER模型可以直接处理的CoNLL 2003格式
笔者要做命名实体识别(NER)的工作,选择了Doccano平台来进行文本标注。 Doccano平台对标注结果的导出格式是JSONL格式,我们导出了NER.jsonl文件。 但是用python语言搭建深度学习模型来实现NER时,一般接收的输入数据格式…...
网络编程day03(UDP中的connect函数、tftp)
今日任务:tftp的文件上传下载(服务端已经准备好) 服务端(已上传) 客户端: 代码: #include <stdio.h> #include <string.h> #include <stdlib.h> #include <sys/types.h…...
flarum 论坛 User Statistics插件修改
此插件在中国使用日期不是很理想,于是决定修改代码 下面是插件信息: User Statistics A Flarum extension. Add some user statistics in flarum posts, this extension require clarkwinkelmann/flarum-ext-likes-received and will be installed au…...
阿里云产品试用系列-容器镜像服务 ACR
阿里云容器镜像服务(简称 ACR)是面向容器镜像、Helm Chart 等符合 OCI 标准的云原生制品安全托管及高效分发平台。 ACR 支持全球同步加速、大规模/大镜像分发加速、多代码源构建加速等全链路提效,与容器服务 ACK 无缝集成,帮助企业…...
Langchain里的“记忆力”,让AI只记住有用的事
今天要讲以下内容: 1.ConversationBufferWindowMemory:基于一个固定长度的滑动窗口的“记忆”功能 2.ConversationSummaryMemory:总结对话“记忆”功能 3.ConversationSummaryBufferMemory:上面两个的结合,超过一定…...
从零开始的LINUX(一)
LINUX本质是一种操作系统,用于对软硬件资源进行管理,其管理的方式是指令。指令是先于图形化界面产生的,相比起图形化界面,指令显然更加难以理解,但两者只是形式上的不同,本质并没有区别。 简单的指令&…...
CH34X-MPHSI高速Master扩展应用—I2C设备调试
一、前言 本文介绍,基于USB2.0高速USB转接芯片CH347,配合厂商提供的USB转MPHSI(Multi Protocol High-Speed Serial Interface)Master总线驱动(CH34X-MPHSI-Master)为系统扩展I2C总线的用法,除…...
记一次正式环境升级docker服务基础进行版本异常
因为服务的httpd和tomcat基础镜像版本比较旧,漏洞多,需要升级至最新版本。在本地环境和测试环境都是直接将dockerfile中的FROM基础镜像升级至最新: httpd:由httpd:2.4.52-alpine升级至httpd:2.4.57 tomcat:由4年前的…...
leetcode面试经典150题第一弹(一)
leetcode面试经典150题第一弹 一、合并俩个有序数组(难度:简单) 题目 给你两个按 非递减顺序 排列的整数数组 nums1 和 nums2,另有两个整数 m 和 n ,分别表示 nums1 和 nums2 中的元素数目。 请你 合并 nums2 到 nums1 中,使合并…...
VME-7807RC-414001 350-93007807-414001 VMIVME-017807-411001 VMIVME-017807-414001
VME-7807RC-414001 350-93007807-414001 VMIVME-017807-411001 VMIVME-017807-414001 由于第12代英特尔酷睿处理器的16核/24线程配置,Nuvo-9000型号与之前的平台相比,性能大幅提升。它们还支持新的DDR5内存标准,以获得更多内存带宽…...
01-Zookeeper特性与节点数据类型详解
上一篇: 在了解Zookeeper之前,需要对分布式相关知识有一定了解,什么是分布式系统呢?通常情况下,单个物理节点很容易达到性能,计算或者容量的瓶颈,所以这个时候就需要多个物理节点来共同完成某项…...
TP6 TP8 使用阿里官方OSS SDK方法
安装 composer require aliyuncs/oss-sdk-php 官网:GitHub - aliyun/aliyun-oss-php-sdk: Aliyun OSS SDK for PHP 二、PHP简单上传 官网教程:如何进行字符串上传和文件上传_对象存储 OSS-阿里云帮助中心 引入 use OSS\OssClient; use OSS\Core\OssE…...
SkyWalking分布式链路追踪学习
为什么要用分布式链路追踪 实际生产中,面对几十个、甚至成百上千个的微服务实例,如果一旦某个实例发生宕机,如果不能快速定位、提交预警,对实际生产造成的损失无疑是巨大的。所以,要对微服务进行监控、预警࿰…...
git revert 撤销之前的提交
git revert 用来撤销之前的提交,它会生成一个新的 commit id 。 输入 git revert --help 可以看到帮忙信息。 git revert commitID 不编辑新的 commit 说明 git log 找到需要撤销的 commitID , 然后执行 git revert commitID ,会提示如下…...
rk3568环境配置和推理报错: RKNN_ERR_MALLOC_FAIL
前言 最近在部署算法在板子侧遇到的一些问题汇总一下: 一、版本问题 经过测试现在将自己环境配置如下: 本地linux安装rknn-toolkit2-1.5.0 本地Linux使用的miniconda新建的一个python虚拟环境(自行网上查找相关方法) 安装好自…...
网络工程师基础笔记(一)
一、接入网 接入网,是指将端系统物理连接到边缘路由器的网络。 (1)家庭接入:数字用户线(DSL)、电缆、光纤到户(FTTH)卫星和拨号接入。 (2)企业(家庭)接入&…...
Postman应用——Headers请求头设置
文章目录 Header设置Header删除或禁用Header批量编辑Header预设添加 一般在接口需要校验签名时,Headers请求头用来携带签名和生成签名需要的参数,在Postman也可以设置请求头在接口请求时携带参数。 Header设置 说明: Key:Header…...
人人都是项目经理-项目管理概述(一)
一、重新认识项目管理 1. 什么是项目 项目(Project),是为提供某项独特的产品(交付物),服务或成果所做的临时性努力。 – PMBOK指南 项目是指一系列独特的、复杂的并相互关联的活动,这些活动有着…...
浅谈基于物联网的医院消防安全管理
安科瑞 华楠 摘 要:医院消防物联网将原本与网络无关的消防设施和网络结合起来,将消防监督管理、防火灭火所需的相关信息进行汇总,可以让医院更加轻松地发现和处理医院的警情信息,降低火灾发生频率。 关键词:物联网技…...
国防科技大学计算机基础课程笔记02信息编码
1.机内码和国标码 国标码就是我们非常熟悉的这个GB2312,但是因为都是16进制,因此这个了16进制的数据既可以翻译成为这个机器码,也可以翻译成为这个国标码,所以这个时候很容易会出现这个歧义的情况; 因此,我们的这个国…...
C++_核心编程_多态案例二-制作饮品
#include <iostream> #include <string> using namespace std;/*制作饮品的大致流程为:煮水 - 冲泡 - 倒入杯中 - 加入辅料 利用多态技术实现本案例,提供抽象制作饮品基类,提供子类制作咖啡和茶叶*//*基类*/ class AbstractDr…...
【入坑系列】TiDB 强制索引在不同库下不生效问题
文章目录 背景SQL 优化情况线上SQL运行情况分析怀疑1:执行计划绑定问题?尝试:SHOW WARNINGS 查看警告探索 TiDB 的 USE_INDEX 写法Hint 不生效问题排查解决参考背景 项目中使用 TiDB 数据库,并对 SQL 进行优化了,添加了强制索引。 UAT 环境已经生效,但 PROD 环境强制索…...
vue3 字体颜色设置的多种方式
在Vue 3中设置字体颜色可以通过多种方式实现,这取决于你是想在组件内部直接设置,还是在CSS/SCSS/LESS等样式文件中定义。以下是几种常见的方法: 1. 内联样式 你可以直接在模板中使用style绑定来设置字体颜色。 <template><div :s…...
06 Deep learning神经网络编程基础 激活函数 --吴恩达
深度学习激活函数详解 一、核心作用 引入非线性:使神经网络可学习复杂模式控制输出范围:如Sigmoid将输出限制在(0,1)梯度传递:影响反向传播的稳定性二、常见类型及数学表达 Sigmoid σ ( x ) = 1 1 +...
全面解析各类VPN技术:GRE、IPsec、L2TP、SSL与MPLS VPN对比
目录 引言 VPN技术概述 GRE VPN 3.1 GRE封装结构 3.2 GRE的应用场景 GRE over IPsec 4.1 GRE over IPsec封装结构 4.2 为什么使用GRE over IPsec? IPsec VPN 5.1 IPsec传输模式(Transport Mode) 5.2 IPsec隧道模式(Tunne…...
华硕a豆14 Air香氛版,美学与科技的馨香融合
在快节奏的现代生活中,我们渴望一个能激发创想、愉悦感官的工作与生活伙伴,它不仅是冰冷的科技工具,更能触动我们内心深处的细腻情感。正是在这样的期许下,华硕a豆14 Air香氛版翩然而至,它以一种前所未有的方式&#x…...
短视频矩阵系统文案创作功能开发实践,定制化开发
在短视频行业迅猛发展的当下,企业和个人创作者为了扩大影响力、提升传播效果,纷纷采用短视频矩阵运营策略,同时管理多个平台、多个账号的内容发布。然而,频繁的文案创作需求让运营者疲于应对,如何高效产出高质量文案成…...
Netty从入门到进阶(二)
二、Netty入门 1. 概述 1.1 Netty是什么 Netty is an asynchronous event-driven network application framework for rapid development of maintainable high performance protocol servers & clients. Netty是一个异步的、基于事件驱动的网络应用框架,用于…...
【WebSocket】SpringBoot项目中使用WebSocket
1. 导入坐标 如果springboot父工程没有加入websocket的起步依赖,添加它的坐标的时候需要带上版本号。 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-websocket</artifactId> </dep…...

