当前位置: 首页 > news >正文

仿艾莫迅MODBUS调试工具写一个上位机

公司采购了一个夹具,项目负责人想要试探这个夹具的性能,于是想要我这边写一个烤机的程序,小编结合官网资料
https://wiki.amsamotion.com/?title=196&doc=222
在这里插入图片描述
查看其pdf说明文档和调试工具并按照其工具写一个烤机上位机
在这里插入图片描述
根据项目负责人的要求开发了一个小程序
在这里插入图片描述
在这里插入图片描述

using JY_MODBUS_IO8R_IS_Soft.BLL;
using JY_MODBUS_IO8R_IS_Soft.Business;
using JY_MODBUS_IO8R_IS_Soft.JY_MODBUS_IO8R_Controller;
using JY_MODBUS_IO8R_IS_Soft.Model;
using JY_MODBUS_IO8R_IS_Soft.userControl;
using LogManager;
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 JY_MODBUS_IO8R_IS_Soft
{public partial class frmMain : Form{ModbusController controller = new ModbusController();static readonly Modbus_helper Modbus_helper = new Modbus_helper(DeviceBll.Single.SerialPort);public frmMain(){InitializeComponent();//获取电脑上可用的串口号string[] ports = System.IO.Ports.SerialPort.GetPortNames();if (ports.Length != 0){cbb_Com.Items.AddRange(ports);}Modbus_helper.DelResult = DelWriteLog;Modbus_helper.DelTime = DelWriteLog;}private void btnConnect_Click(object sender, EventArgs e){try{LogNetManagment.LogNet.WriteDebug("连接串口");string errMsg = string.Empty;if (!Modbus_helper.Connect(cbb_Com.Text.Trim(), Convert.ToInt32(cbb_ComRate.Text.Trim()), Convert.ToInt32(txtWriteReadTime.Text.Trim()), ref errMsg)){MessageBox.Show(errMsg);}else{UpdateConnectStatus(true);}}catch (Exception ex){LogNetManagment.LogNet.WriteException("连接通信", ex);MessageBox.Show(ex.ToString());}}/// <summary>/// 改变连接状态/// </summary>/// <param name="status"></param>public void UpdateConnectStatus(bool status){if (status){btnConnect.Enabled = false;btnBreak.Enabled = true;}else{btnConnect.Enabled = true;btnBreak.Enabled = false;}}private void btnBreak_Click(object sender, EventArgs e){try{LogNetManagment.LogNet.WriteDebug("断开串口");string errMsg = string.Empty;if (!Modbus_helper.Close(ref errMsg)){MessageBox.Show(errMsg);}else{UpdateConnectStatus(false);}}catch (Exception ex){LogNetManagment.LogNet.WriteException("断开通讯", ex);MessageBox.Show(ex.ToString());}}private void btnTest_Click(object sender, EventArgs e){try{LogNetManagment.LogNet.WriteDebug("开始循环测试,循环次数为"+txtTestTime.ToString());this.btnTest.Enabled = false;int channel = cmbChannel.SelectedIndex;Task.Factory.StartNew(() =>{string errMsg = string.Empty;Modbus_helper.IsTestStatus = true;if (!Modbus_helper.ContinueTest(channel, Convert.ToInt32(txtTestTime.Text),ref errMsg)){this.Invoke(new Action(() =>{MessageBox.Show(errMsg);}));}}).ContinueWith((task) => {this.Invoke(new Action(() => {this.btnTest.Enabled = true;}));});}catch (Exception ex){LogNetManagment.LogNet.WriteException("开始循环测试", ex);MessageBox.Show(ex.ToString());}}private void DelWriteLog(int runtime){this.BeginInvoke(new Action(() =>{DateTime date = DateTime.Now;txtLog.AppendText($"{date.ToString("yyyy-MM-dd HH:mm:ss.fff")} 当前正在执行{runtime}次"+ Environment.NewLine);}));}private void DelWriteLog(ResultModel result){this.BeginInvoke(new Action(() =>{DateTime date = DateTime.Now;if (result.TestResult == (uint)Common.CommonEnum.TestResultType.Success){txtLog.AppendText(date.ToString("yyyy-MM-dd HH:mm:ss.fff") + " " + result.LabelTip + Environment.NewLine);}else if (result.TestResult == (uint)Common.CommonEnum.TestResultType.Fail){txtLog.AppendText(date.ToString("yyyy-MM-dd HH:mm:ss.fff") + " " + result.LabelTip + Environment.NewLine);}else{txtLog.AppendText(date.ToString("yyyy-MM-dd HH:mm:ss.fff") + " " + result.LabelTip + Environment.NewLine);}}));}private void switchButtons1_Btn_Click(object sender, EventArgs e){Button userCtl = sender as Button;string errMsg = string.Empty;if (switchButtons1.Controls.Find($"btn{userCtl.Tag}", true)[0].BackColor == SystemColors.Control){if (!Modbus_helper.TestByChannel(Convert.ToInt32(userCtl.Tag), Common.CommonEnum.OrderType.Control, ref errMsg)){switchButtons1.Controls.Find($"btn{userCtl.Tag}", true)[0].BackColor = SystemColors.Control;}else{switchButtons1.Controls.Find($"btn{userCtl.Tag}", true)[0].BackColor = Color.Red;}}else if (switchButtons1.Controls.Find($"btn{userCtl.Tag}", true)[0].BackColor == Color.Red){if (!Modbus_helper.TestByChannel(Convert.ToInt32(userCtl.Tag), Common.CommonEnum.OrderType.Clearance, ref errMsg)){switchButtons1.Controls.Find($"btn{userCtl.Tag}", true)[0].BackColor = Color.Red;}else{switchButtons1.Controls.Find($"btn{userCtl.Tag}", true)[0].BackColor = SystemColors.Control;}}}private void btnStop_Click(object sender, EventArgs e){LogNetManagment.LogNet.WriteDebug("点击停止");Modbus_helper.IsTestStatus = false;DateTime date = DateTime.Now;txtLog.AppendText(date.ToString("yyyy-MM-dd HH:mm:ss.fff") + " 点击停止"  + Environment.NewLine);}}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;namespace JY_MODBUS_IO8R_IS_Soft.Common
{public class CommonEnum{/// <summary>/// 指令类型/// </summary>public enum OrderType : uint{/// <summary>/// 控制/// </summary>Control = 0,/// <summary>/// 解控/// </summary>Clearance = 1}/// <summary>/// 测试结束各种原因/// </summary>public enum TestResultType : uint{/// <summary>/// 正常成功结束/// </summary>Success = 0,/// <summary>/// 异常结束/// </summary>Fail = 1,/// <summary>/// 倒计时结束/// </summary>FixedSuccess = 2}}
}
using Common;
using JY_MODBUS_IO8R_IS_Soft.Config;
using LogManager;
using System;
using System.Collections.Generic;
using System.IO.Ports;
using System.Linq;
using System.Text;
using System.Threading.Tasks;namespace JY_MODBUS_IO8R_IS_Soft.Business
{public class DeviceBll{private static DeviceBll bDeviceSingle = null;public static DeviceBll Single{get{if (bDeviceSingle == null) bDeviceSingle = new DeviceBll();return bDeviceSingle;}}//不允许外部New操作private DeviceBll() { }/// <summary>/// 硬件配置文件路径/// </summary>public string ChoosesetPath = AppDomain.CurrentDomain.BaseDirectory + "\\Chooseset.ini";/// <summary>/// 保存数据的路径/// </summary>public string SaveDataPath = string.Empty;/// <summary>/// 是否保存数据/// </summary>public bool IsSaveData = true;/// <summary>/// 保存数据最大的行数 到达之后重新创建文件/// </summary>public int ExportDataLines = 0;/// <summary>/// 通道数/// </summary>public int ChannelNum = 12;/// <summary>/// 设备通讯连接状态 true已连接 false未连接/// </summary>public bool IsLink = false;/// <summary>/// 锁对象/// </summary>public readonly object LockFileObj = new object();/// <summary>/// 配置文件/// </summary>public mainSet MainConfigSet = new mainSet();///// <summary>///// 设备接口对象///// </summary>//public I_MUX _ifun;public delegate void DelUpdateConfig();/// <summary>/// 用户切换响应事件/// </summary>public static event DelUpdateConfig EventUpdateConfig;/// <summary>/// 串口对象/// </summary>public SerialPort SerialPort;/// <summary>/// 用户切换/// </summary>public static void UpdateConfig(){if (EventUpdateConfig != null){EventUpdateConfig();}}public delegate void DelUpdateBtnStartAll();public static event DelUpdateBtnStartAll EventUpdateBtnStartAll;public static void UpdateBtnStartAll(){if (EventUpdateBtnStartAll != null){EventUpdateBtnStartAll();}}/// <summary>///系统硬件初始化/// </summary>public void Init(){try{DeviceInit();int delayTime = Convert.ToInt32(IniFileHelper.IniReadValue(DeviceBll.Single.ChoosesetPath, "DelayTime", "DelayTime_ms", ""));ChannelNum = Convert.ToInt32(IniFileHelper.IniReadValue(DeviceBll.Single.ChoosesetPath, "Channel", "ChannelNum", ""));LogManager.LogNetManagment.LogNet.WriteInfo("获取参数保护文件参数");}catch (Exception ex){LogNetManagment.LogNet.WriteException("Init", ex);}}/// <summary>/// 设备初始化加载/// </summary>public void DeviceInit(){SerialPort = new SerialPort();//串口对象}}
}
using JY_MODBUS_IO8R_IS_Soft.Model;
using LogManager;
using System;
using System.Collections.Generic;
using System.IO.Ports;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;namespace JY_MODBUS_IO8R_IS_Soft.BLL
{public class Modbus_helper{/// <summary>/// 串口对象/// </summary>public SerialPort SerialPort { get; set; }/// <summary>/// 发送结果数据/// </summary>public Action<ResultModel> DelResult { get; set; }/// <summary>/// 发送执行的次数/// </summary>public Action<int> DelTime { get; set; }/// <summary>/// 获取结果类/// </summary>public ResultModel Result { get; set; }/// <summary>/// 测试状态/// </summary>public bool IsTestStatus { get; set; }public int WriteReadTime { get; set; }/// <summary>/// 锁对象/// </summary>private readonly object _lockWr = new object();public Modbus_helper(SerialPort serialPort){this.SerialPort = serialPort;this.Result = new ResultModel();IsTestStatus = false;}/// <summary>/// 连接串口/// </summary>/// <param name="comName">串口号</param>/// <param name="comRate">串口速率</param>/// <param name="errMsg">错误信息</param>/// <returns></returns>public bool Connect(string comName, int comRate, int time, ref string errMsg){try{SerialPort.BaudRate = comRate;SerialPort.StopBits = StopBits.One;SerialPort.PortName = comName;SerialPort.NewLine = "\r\n";SerialPort.ReadTimeout = 10000;SerialPort.WriteTimeout = 1000;SerialPort.Open();if (SerialPort.IsOpen.Equals(false)){//串口连接失败!errMsg = "连接串口失败";return false;}else{WriteReadTime = time;return true;}}catch (Exception ex){LogNetManagment.LogNet.WriteException(nameof(Modbus_helper) + "_" + nameof(Connect), ex);errMsg = ex.ToString();return false;}}public bool Close(ref string errMsg){try{if (SerialPort.IsOpen){SerialPort.Close();}if (!SerialPort.IsOpen){return true;}return true;}catch (Exception ex){LogNetManagment.LogNet.WriteException(nameof(Modbus_helper) + "_" + nameof(Close), ex);errMsg = ex.ToString();return false;}}public bool ContinueTest(int channel, int time, ref string errMsg){try{for (int i=0;i<time;i++){if (!IsTestStatus){return true;}int testtime = i + 1;DelTime(testtime);byte[] controlBytes = GetControlBytes(channel, Common.CommonEnum.OrderType.Control);//控制if (!WriteRead(controlBytes, ref errMsg)){Result.TestResult = 1;Result.LabelTip = "当前正在执行" + testtime + "次吸合失败";DelResult(Result);return false;}byte[] clearanceBytes = GetControlBytes(channel, Common.CommonEnum.OrderType.Clearance);//解控if (!WriteRead(clearanceBytes, ref errMsg)){Result.TestResult = 1;Result.LabelTip = "当前正在执行" + testtime + "次断开失败";DelResult(Result);return false;}Result.TestResult = 0;Result.LabelTip = "执行成功";DelResult(Result);}Result.LabelTip = "执行完毕";Result.TestResult = 2;DelResult(Result);return true;}catch (Exception ex){LogNetManagment.LogNet.WriteException(nameof(Modbus_helper) + "_" + nameof(ContinueTest), ex);errMsg = ex.ToString();return false;}}public bool TestByChannel(int channel, Common.CommonEnum.OrderType orderType, ref string errMsg){try{if (orderType == Common.CommonEnum.OrderType.Control){byte[] controlBytes = GetControlBytes(channel, Common.CommonEnum.OrderType.Control);//控制if (!WriteRead(controlBytes, ref errMsg)){Result.TestResult = 1;Result.LabelTip = $"当前正在执行channel{channel}吸合失败";DelResult(Result);return false;}else{Result.TestResult = 0;Result.LabelTip = $"当前正在执行channel{channel}吸合成功";DelResult(Result);return true;}}else if (orderType == Common.CommonEnum.OrderType.Clearance){byte[] clearanceBytes = GetControlBytes(channel, Common.CommonEnum.OrderType.Clearance);//解控if (!WriteRead(clearanceBytes, ref errMsg)){Result.TestResult = 1;Result.LabelTip = $"当前正在执行channel{channel}断开失败";DelResult(Result);return false;}else{Result.TestResult = 0;Result.LabelTip = $"当前正在执行channel{channel}断开成功";DelResult(Result);return true;}}return true;}catch (Exception ex){LogNetManagment.LogNet.WriteException(nameof(Modbus_helper) + "_" + nameof(TestByChannel), ex);errMsg = ex.ToString();return false;}}public bool WriteRead(byte[] strWrite, ref string errMsg){try{SerialPort.DiscardInBuffer();//丢弃缓冲区数据SerialPort.DiscardOutBuffer();//丢弃缓冲区数据SerialPort.DiscardInBuffer();//丢弃缓冲区数据SerialPort.DiscardOutBuffer();//丢弃缓冲区数据SerialPort.Write(strWrite, 0, 8);Thread.Sleep(WriteReadTime);SerialPort.ReadExisting();return true;}catch (Exception ex){LogNetManagment.LogNet.WriteException(nameof(Modbus_helper) + "_" + nameof(WriteRead), ex);errMsg = ex.ToString();return false;}}public byte[] GetControlBytes(int channel, Common.CommonEnum.OrderType OrderType){byte[] bytes = new byte[8];//01 05 00 00 FF 00 8C 3A   控制if (OrderType == Common.CommonEnum.OrderType.Control){//bytes[0] = 01;//bytes[1] = 05;//bytes[2] = 00;//bytes[3] = 00;//bytes[4] = 0xFF;//bytes[5] = 00;//bytes[6] = 0x8C;//bytes[7] = 0x3A;//return bytes;byte address = Convert.ToByte(channel);byte[] cmd = GenerateCommand(0x01, address, true);return cmd;}else if (OrderType == Common.CommonEnum.OrderType.Clearance){//01 05 00 00 00 00 CD CA//bytes[0] = 01;//bytes[1] = 05;//bytes[2] = 00;//bytes[3] = 00;//bytes[4] = 00;//bytes[5] = 00;//bytes[6] = 0xCD;//bytes[7] = 0xCA;//return bytes;byte address = Convert.ToByte(channel);byte[] cmd = GenerateOffCommand(0x01, address);return cmd;}return bytes;}// CRC16校验计算核心方法public static ushort CalculateCrc(byte[] data){ushort crc = 0xFFFF;foreach (byte b in data){crc ^= b;for (int i = 0; i < 8; i++){bool lsb = (crc & 1) == 1;crc >>= 1;if (lsb) crc ^= 0xA001;}}return crc;}// 生成完整Modbus指令(包含CRC)public static byte[] GenerateCommand(byte deviceId, ushort address, bool state){byte[] cmd = new byte[6];cmd[0] = deviceId;cmd[1] = 0x05; // 功能码cmd[2] = (byte)(address >> 8); // 地址高字节cmd[3] = (byte)(address & 0xFF); // 地址低字节cmd[4] = state ? (byte)0xFF : (byte)0x00; // 状态值cmd[5] = 0x00; // 固定填充ushort crc = CalculateCrc(cmd);byte[] fullCmd = new byte[8];Array.Copy(cmd, fullCmd, 6);fullCmd[6] = (byte)(crc & 0xFF); // CRC低字节在前fullCmd[7] = (byte)(crc >> 8);return fullCmd;}// 生成断开继电器指令public static byte[] GenerateOffCommand(byte deviceId, ushort address){byte[] cmd = new byte[6];cmd[0] = deviceId;cmd[1] = 0x05; // 功能码cmd[2] = (byte)(address >> 8); // 地址高字节cmd[3] = (byte)(address & 0xFF); // 地址低字节cmd[4] = 0x00; // 断开继电器cmd[5] = 0x00; // 固定填充ushort crc = CalculateCrc(cmd);byte[] fullCmd = new byte[8];Array.Copy(cmd, fullCmd, 6);fullCmd[6] = (byte)(crc & 0xFF); // CRC 低字节在前fullCmd[7] = (byte)(crc >> 8);return fullCmd;}}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;namespace JY_MODBUS_IO8R_IS_Soft.Config
{// 通过此类可以处理设置类的特定事件: //  在更改某个设置的值之前将引发 SettingChanging 事件。//  在更改某个设置的值之后将引发 PropertyChanged 事件。//  在加载设置值之后将引发 SettingsLoaded 事件。//  在保存设置值之前将引发 SettingsSaving 事件。public sealed partial class mainSet{public mainSet(){// // 若要为保存和更改设置添加事件处理程序,请取消注释下列行: //// this.SettingChanging += this.SettingChangingEventHandler;//// this.SettingsSaving += this.SettingsSavingEventHandler;//}private void SettingChangingEventHandler(object sender, System.Configuration.SettingChangingEventArgs e){// 在此处添加用于处理 SettingChangingEvent 事件的代码。}private void SettingsSavingEventHandler(object sender, System.ComponentModel.CancelEventArgs e){// 在此处添加用于处理 SettingsSaving 事件的代码。}}
}
//------------------------------------------------------------------------------
// <auto-generated>
//     此代码由工具生成。
//     运行时版本:4.0.30319.42000
//
//     对此文件的更改可能会导致不正确的行为,并且如果
//     重新生成代码,这些更改将会丢失。
// </auto-generated>
//------------------------------------------------------------------------------namespace JY_MODBUS_IO8R_IS_Soft.Config {[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()][global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "14.0.0.0")]public sealed partial class mainSet : global::System.Configuration.ApplicationSettingsBase {private static mainSet defaultInstance = ((mainSet)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new mainSet())));public static mainSet Default {get {return defaultInstance;}}[global::System.Configuration.UserScopedSettingAttribute()][global::System.Diagnostics.DebuggerNonUserCodeAttribute()][global::System.Configuration.DefaultSettingValueAttribute("COM1")]public string ComName {get {return ((string)(this["ComName"]));}set {this["ComName"] = value;}}[global::System.Configuration.UserScopedSettingAttribute()][global::System.Diagnostics.DebuggerNonUserCodeAttribute()][global::System.Configuration.DefaultSettingValueAttribute("115200")]public string ComRate {get {return ((string)(this["ComRate"]));}set {this["ComRate"] = value;}}[global::System.Configuration.UserScopedSettingAttribute()][global::System.Diagnostics.DebuggerNonUserCodeAttribute()][global::System.Configuration.DefaultSettingValueAttribute("Q.0")]public string Channel {get {return ((string)(this["Channel"]));}set {this["Channel"] = value;}}[global::System.Configuration.UserScopedSettingAttribute()][global::System.Diagnostics.DebuggerNonUserCodeAttribute()][global::System.Configuration.DefaultSettingValueAttribute("10")]public int TestTime {get {return ((int)(this["TestTime"]));}set {this["TestTime"] = value;}}}
}
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;namespace JY_MODBUS_IO8R_IS_Soft.userControl
{public partial class SwitchButtons : UserControl{public SwitchButtons(){InitializeComponent();InitializeTableLayout();}private void InitializeTableLayout(){// 设置TableLayoutPanel的行和列tableLayoutPanel1.RowCount = 2; // 例如,3行tableLayoutPanel1.ColumnCount = 9; // 1列,可以根据需要调整tableLayoutPanel1.RowStyles.Add(new RowStyle(SizeType.Absolute, 30F)); // 标题行占20%高度tableLayoutPanel1.RowStyles.Add(new RowStyle(SizeType.Absolute, 30F)); // 按钮行占60%高度}private void SwitchButtons_Load(object sender, EventArgs e){Label labelcol = new Label();labelcol.Text = $"Do0"; // 按钮的文本从"按钮2"开始计数labelcol.AutoSize = false;labelcol.TextAlign = ContentAlignment.MiddleCenter;labelcol.Dock = DockStyle.Fill; // 使按钮填充整个单元格tableLayoutPanel1.Controls.Add(labelcol, 0, 1); // 添加到相应的行,第一列for (int i = 1; i < 9; i++) // 假设你想添加4个按钮,从第二行开始(索引为1){this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 60F));Label label = new Label();label.Text = $"Q.{i-1}"; // 按钮的文本从"按钮2"开始计数label.AutoSize = false;label.TextAlign = ContentAlignment.MiddleCenter;label.Dock = DockStyle.Fill; // 使按钮填充整个单元格Button button = new Button();button.Dock = DockStyle.Fill;button.Tag = (i - 1).ToString();button.Name = $"btn{(i-1)}";button.Click += new EventHandler(this.btn_click);tableLayoutPanel1.Controls.Add(label, i, 0); // 添加到相应的行,第一列tableLayoutPanel1.Controls.Add(button, i, 1); // 添加到相应的行,第一列}}//public void btn_click(Object sender, System.EventArgs e)//{//    string id = ((Button)sender).Tag.ToString();//    MessageBox.Show(id);//}/// <summary>/// 点击事件/// </summary>[Browsable(true), Category("自定义事件"), Description("点击事件")]public event EventHandler Btn_Click;private void btn_click(object sender, EventArgs e){if (Btn_Click != null){Btn_Click(sender, e);}}}
}
using JY_MODBUS_IO8R_IS_Soft.Business;
using JY_MODBUS_IO8R_IS_Soft.frms;
using LogManager;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Forms;namespace JY_MODBUS_IO8R_IS_Soft
{static class Program{/// <summary>/// 应用程序的主入口点。/// </summary>[STAThread]static void Main(){Application.EnableVisualStyles();Application.SetCompatibleTextRenderingDefault(false);#region 日志构建//初始化日志string logPath = Application.StartupPath + "\\Log"; //日志路径LogManager.GenerateMode LogSaveMode = LogManager.GenerateMode.ByEveryDay; //日志存储方式 按天LogNetManagment.LogNet = new LogManager.LogNetDateTime(logPath, LogSaveMode);LogNetManagment.LogNet.WriteDebug("启动程序");#endregionDeviceBll.Single.Init();Application.Run(new frmMain());}}
}
http://www.lryc.cn/news/607299.html

相关文章:

  • 基于springboot的快递分拣管理系统
  • 【智能协同云图库】第七期:基于AI调用阿里云百炼大模型,实现AI图片编辑功能
  • 【AI 加持下的 Python 编程实战 2_12】第九章:繁琐任务的自动化(上)——自动清理电子邮件文本
  • 【Linux学习|黑马笔记|Day1】Linux初识、安装VMware Workstation、安装CentOS7、远程连接、虚拟机快照
  • Baumer工业相机堡盟工业相机如何通过YoloV8深度学习模型实现围栏羊驼的检测识别(C#代码,UI界面版)
  • 标准项目-----网页五子棋(4)-----游戏大厅+匹配+房间代码
  • AJAX快速入门 - 四个核心步骤
  • HTML无尽射击小游戏包含源码,纯HTML+CSS+JS
  • 【Flutter】内存泄漏总结
  • 【数据可视化-78】2025年上半年广东省各市GDP排名深度解析与可视化:Python + Pyecharts 深度洞察(含完整数据、代码)
  • OpenVLA: 论文阅读 -- 开源视觉-语言-行动模型
  • ZKmall开源商城微服务架构电商平台:服务注册与配置中心设计
  • Spring Boot 整合量子密钥分发(QKD)实验方案
  • Linux---make和makefile
  • 分布在背侧海马体CA1区域的位置细胞(place cells)对NLP中的深层语义分析的积极影响和启示
  • 面试题:怎么理解 OSI 参考模型(开放式系统互联参考模型) 和 TCP/IP 模型(传输控制协议 / 网际协议模型 )
  • 【vue】Vue 项目创建工具对比:vue create 与 create-vue 的核心区别
  • RAGFLOW~knowledge graph
  • k8s部署mysql
  • 【数论】P8954 「VUSC」Math Game|普及+
  • SpringBoot3.x入门到精通系列:1.5 配置文件详解
  • QT6 源,十章绘图(2)画刷 QBrush:刷子只涉及填充颜色,线型,填充图片,以及变换矩阵这几个属性,附源代码带注释。
  • 京东零售在智能供应链领域的前沿探索与技术实践
  • 【Kubernetes 指南】基础入门——Kubernetes 集群(二)
  • Java抽象类与接口深度解析:核心区别与应用场景全指南
  • 四类屏幕录制方案的技术选型指南
  • 神经网络学习笔记
  • 流式编程的中间操作
  • 带root权限_中国移动创维DT541_S905L3融合机器改机顶盒刷机教程 当贝纯净版安卓9.0系统线刷包 刷机包
  • Rockchip RK3568J +FPGA边缘智能系统及储能网关