简介:EZCAD 2.7全套资源是一套面向激光打标设备开发者的完整工具包,内含可运行的上位机打标控制软件(需配合打标卡使用,否则提示无狗)以及32位、64位驱动,支持WIN7系统,适合需要集成激光打标控制、开发定制界面或扩展功能的工程师、设备厂商及技术支持人员。资源共113个文件,压缩包大小约12.33MB,其中38个动态链接库构成核心函数库,以MarkEzd.dll二次开发接口为主,并附带导入库、头文件、PDF开发手册及Word说明文档;另有插件文件、参数文件、配置文件、界面位图资源、系统驱动和接线说明等,层次清晰、便于按需调用。目前已有2599人学习下载,热度较高。包内不仅提供二次开发全套基础,还包含安装说明、接线定义和操作说明书,可帮助具备C/C++编程基础的读者较快上手打标软件定制;仅供研究学习使用。
1. EZCAD 2.7到底是什么:激光打标自动化绕不开的那层接口
产线上十几台激光打标机同时开工,上位机要从MES系统接序列号和日期码,按工件类型决定打标位置和功率。如果你只会把手上的EZCAD 2.7当桌面工具用,手动拖对象、点打标,那走到自动接收指令、自动回传结果这一步,就会撞上EZCAD 2.7没有脚本入口这堵墙。厂商留给自动化集成的出口,是那套随软件分发的二次开发函数库,版本2.5,它是一组可以被C/C++、C#、VB等语言调用的DLL接口,把打开文件、加载图形、下发参数、启动打标、查询状态全部变成普通函数调用。
接下来要讲的这套方案,全落在二次开发函数2.5上:先讲清楚它是什么、能解决什么,再给一个能跑通的最小Demo,接着拆核心API的参数含义,最后用五条踩坑记录告诉你哪些地方容易翻车。适合三类读者:做激光打标自动化集成的上位机工程师、要对接MES系统的设备软件开发者,以及想给打标机加视觉定位联动的人。读到后半部分时,你手上最好已经有一台能开机的打标机,因为所有结论都必须用实机验证。
2. 环境搭建与DLL加载:先让二次开发函数2.5跑起来
2.1 "全套"通常包含什么:主程序、加密狗与开发包的边界
先说清楚"全套"这两个字的水分。设备厂分发的EZCAD 2.7全套,通常包含四样东西:主程序安装包、加密狗驱动、二次开发函数库(版本2.5)以及配套的示例工程和接口文档。很多设备厂还会额外放进控制卡底层驱动和一台出厂调好的场镜校正文件。这里最容易被忽略的是版本匹配:主程序2.7配的是二次开发函数2.5,这个组合是出厂验证过的;但如果你手里的加密狗来自设备厂的定制渠道,二次开发库必须跟着设备厂走,不能自己从网上找一个同版本号的DLL就塞进去,否则会出现控制卡能识别、API却连不上的怪问题。
加密狗是整套授权体系的核心。打标控制卡通常插着一枚USB加密狗,EZCAD主程序启动时要读取它,二次开发函数库连接控制卡时也要经过它。我见过不少刚开始做二次开发的人,装完主程序能开、能手动打标,一调连接函数就返回失败,查了半天发现加密狗驱动版本太老,只兼容了旧版组件,开发库调的是新接口。所以环境搭建的第一步是:把加密狗驱动装到位,先用EZCAD主程序正常识别一次设备,再做任何代码层面的验证。
开发包的目录结构各家略有差异,但常见布局是一个根目录下分Bin、Include、Samples三个子目录。Bin里放二次开发DLL及其依赖项,Include里放C/C++头文件,Samples里有各语言的示例工程。建议把Bin目录整个拷到工程目录下,而不是只拷主接口DLL,因为依赖项缺失的报错非常难查,往往会误导你怀疑调用方式。一个更省心的做法是把二次开发DLL放到和EXE同级的目录,并让工程输出目录指向那里,避免运行时找不到DLL。
2.2 DLL位数与运行时依赖:为什么C#工程要设x86
二次开发函数2.5的DLL绝大多数是按32位编译的,原因很简单:激光打标控制卡的驱动和固件链路从设计之初就是32位体系,厂商没有动力去迁移64位。这意味着如果你的上位机是C#写的,工程平台目标必须设为x86而不是AnyCPU。我见过一个翻车案例:某开发者把平台目标设成x64,编译运行都不报错,一调DLL里的函数就抛入口点异常,查了半天才意识到进程是64位的,加载不了32位DLL。把"首选32位"勾掉、平台目标改x86,问题立刻消失。
除了位数,运行时依赖是另一个隐形雷区。二次开发DLL内部依赖VC运行库和加密狗通信组件,这两样如果没装,DllImport加载时其实已经失败了,但C#侧抛出的异常往往含糊不清。我的排查习惯是先用一个控制台程序做最小加载测试:写一个DllImport声明,只调用连接函数,看返回值和异常。如果异常信息指向"找不到指定的模块",优先检查依赖项而不是检查函数名。
一个被很多人忽略的点:杀毒软件拦截。加密狗通信组件在Windows上经常会被识别为可疑驱动或注入组件,导致服务起不来。配置杀毒白名单时,要把EZCAD安装目录、二次开发DLL目录、程序工作目录三个位置全部加进去,缺一个都可能造成"时好时坏"。这类问题最折磨人,因为它在你的开发机上可能从不出事,一部署到产线工控机就随机失败。
2.3 最小连接示例:C#版Connect/Disconnect
理论铺垫完了,直接进入第一个能跑通最小示例。开发库的调用套路和大多数硬件SDK一致:先用DllImport声明原生接口,再包一层C#方法,让上层代码只跟你的包装类打交道。下面这段代码声明连接和断开两个接口,并在控制台打印结果:
using System; using System.Runtime.InteropServices; public class EzCad2Wrapper { // 二次开发函数库:连接/断开控制卡 [DllImport("EzCad2Api.dll", CallingConvention = CallingConvention.StdCall)] public static extern int EzCad2_Connect(); [DllImport("EzCad2Api.dll", CallingConvention = CallingConvention.StdCall)] public static extern void EzCad2_Disconnect(); /// <summary>连接控制卡,返回1表示成功</summary> public int Connect() { int ret = EzCad2_Connect(); if (ret == 1) { Console.WriteLine("[EZCAD] 控制卡连接成功"); } else { Console.WriteLine("[EZCAD] 连接失败,返回码: " + ret); } return ret; } /// <summary>释放控制卡,进程退出前必须调用</summary> public void Disconnect() { EzCad2_Disconnect(); Console.WriteLine("[EZCAD] 控制卡已释放"); } }这里有个参数说明:连接函数返回1表示成功,0或负数表示失败,具体错误码枚举在各个版本里略有差异,要以配套头文件为准。我见过有的版本失败时返回-1,有的版本返回0,写死判断条件会导致明明没连上也误判成成功。CallingConvention.StdCall是必须的,因为这套接口按C声明导出,用默认的Winapi调用约定在某些系统上也能工作,但遇到断断续续的失败时,第一步就是核对调用约定。
调用这个包装类很简单。一个标准流程是:程序启动时Connect一次,做完整打标操作,退出时Disconnect。不要在主程序里反复Connect/Disconnect,因为每次连接都会重新初始化控制卡,频繁开关在部分版本上会导致控制卡驱动状态错乱。如果业务上确实需要热重连,见第5章的故障恢复设计。
提示:如果连接函数第一次调用就返回失败,不要急着查代码,先确认EZCAD主程序能不能正常识别设备。主程序都连不上时,DLL也不可能凭空连上控制卡。
把上面这个最小示例跑通,意味着环境没问题、DLL加载没问题、加密狗授权没问题。这之后才进入真正的开发逻辑:往文档里加对象、下发参数、执行打标。
3. 核心API分组与参数:打标流程是怎么被代码驱动的
3.1 文档操作与图形创建:两种路线,动态对象是数据驱动的关键
搞定了连接,接下来要回答的问题是:打标内容从哪来?行业里实践下来有两条路线。路线A:拿EZCAD 2.7界面把固定版式排好,存成.ezd工程文件,二次开发时直接加载这个文件,然后只改需要变的那部分对象。路线B:完全靠代码动态建对象——每次任务都是清空文档,加一个流水号文本,加一个Logo位图,再设置参数、执行打标。实际产线方案往往是A+B混合:先加载一个模板,里面已经画好了固定框、Logo、笔参数,然后用DeleteAll删掉旧的变量对象,再动态生成新的文本或条码对象。
这两种路线的选择直接决定你的代码复杂度和维护成本。固定版式多的场景,优先路线A,因为EZCAD界面里的文字排列、对齐、旋转都比代码直观,可维护性好。数据驱动的场景,比如每件打的序列号不同、工件孔径不同导致打标位置不同,路线B才值得用。一个常见误用是:明明只是流水号变化,却每天让操作员用界面改文字,然后代码去加载改过的文件,这等于放弃了自动化的意义,还引入了文件版本混乱的风险。
下面的代码声明了文档操作最常见的三个接口:新建文档、加载模板文件、清空对象,以及一个用于动态加文本的接口:
[DllImport("EzCad2Api.dll", CallingConvention = CallingConvention.StdCall)] public static extern int EzCad2_NewFile(); [DllImport("EzCad2Api.dll", CallingConvention = CallingConvention.StdCall)] public static extern int EzCad2_LoadFromFile(byte[] fileName); [DllImport("EzCad2Api.dll", CallingConvention = CallingConvention.StdCall)] public static extern int EzCad2_DeleteAll(); // 添加文本对象:penNo 指定笔号,text 为内容,posX/posY 是基准点坐标, // textType 是字体类型,height 是字符高度,rotation 是旋转角度 [DllImport("EzCad2Api.dll", CallingConvention = CallingConvention.StdCall)] public static extern int EzCad2_AddText(int penNo, byte[] text, double posX, double posY, int textType, double height, double rotation);这段DllImport声明里,NewFile在新建空文档时用,LoadFromFile加载.ezd模板,DeleteAll清空当前文档所有对象。这里有个细节:DeleteAll并不是把文档恢复到初始状态,它只删除图形对象,笔参数、打标配置还会保留。所以"先DeleteAll再AddText"是一个安全习惯,能确保每次任务不会在上一轮残留对象上叠加内容。
AddText的七个参数值得逐个说清楚。penNo是笔号,每个对象绑定一支笔,笔的加工参数(速度、功率、频率)在打标参数设置里定义,这里是引用关系不是直接传值。text是文本内容,这里用byte[]是为了兼容中文编码,直接用string会因为字符集转换产生乱码,这个坑在第4章细化。posX/posY是文本左下角基准点的坐标,单位毫米,注意EZCAD的坐标系原点在文档工作区左下角,不是视觉中心。textType常见取值0表示单线字体,1表示TrueType字体,不同版本的枚举含义可能不同,但0和1的分工基本一致。height是字符高度,单位毫米,指的通常是字符大写字高,不是整个文本框的高度。rotation是旋转角度,单位是度,逆时针为正。
3.2 打标参数设置:速度、功率、频率和它们的作用域
把对象加到文档里之后,打标效果由笔参数决定。核心接口通常是参数设置函数,一次调用把某支笔的全部加工参数下发。参数多,含义杂,我把最常见的归纳成一张表:
| 参数 | 单位 | 含义 | 常见取值范围 | 注意 |
|---|---|---|---|---|
| nPenNum | 无 | 笔号 | 1~50 | 必须与AddText时的penNo对应 |
| dSpeed | mm/s | 打标速度 | 100~1000 | 速度过快会丢笔画,尤其是精细文字 |
| dPower | % | 激光平均功率百分比 | 10~100 | 实际功率受激光器类型和电流上限影响 |
| dFreq | kHz | Q开关频率 | 20~200 | 光纤激光器常用40~100,CO2常用20~50 |
| dJumpSpeed | mm/s | 空跳速度 | 1000~5000 | 跳转太快会振镜过冲 |
| 各项延时 | ms | 开光/关光/拐角/跳转延时 | 0~1000 | 需要结合打样实测,尤其激光器响应慢时 |
这个表里的数值不能直接抄,因为打标效果高度依赖激光器型号和打标材料。比如不锈钢打黑和铝材打白,功率和频率的窗口完全不同。我在项目里的习惯是:先用EZCAD界面手动打样,把每种材质调到最佳效果,记录参数,再固化到代码或配置模板里,不要用代码去猜最佳参数。
一个容易踩的作用域问题是:参数设置函数设定的是某支笔的参数,而不是当前选中对象的参数。如果你AddText时指定penNo=2,但参数设置只设置了笔1的参数,那打标时对象2会沿用文档里笔2的旧参数,效果可能和预期完全不符。另一个问题是:加载文档时自带的笔参数会和代码里设置的值互相覆盖,如果你想用代码控制参数,必须在打标前重新设置一次,而且要确保没有其他代码路径又把旧参数写回去。
// 设置2号笔的加工参数:速度800mm/s,功率75%,频率60kHz,空跳速度500mm/s // 其余延时参数先用0,正式生产前必须根据激光器实测微调 EzCad2_SetMarkParam(2, 800, 75, 60, 0, 0, 0, 0, 0, 0, 0, 0, 500);这段代码是最朴素的调用方式。前四个数字是笔号、速度、功率、频率,紧接着的八个是各类延时和开关标志,最后一位是跳转速度。我在新项目里一律把延时参数先置0,等第一轮打样测试再逐个调。值得注意的是,频率参数在某些开发包版本里并不是直接传kHz,而是传一个内部计数值,需要查阅头文件里的换算宏。如果你的代码里频率改了半天功率没变化,先怀疑这个换算,别急着调功率。
3.3 执行打标与状态回调:异步流程里怎么等结果
参数设置完毕,终于可以执行打标了。核心接口是打标执行函数,传入-1表示打标当前文档里的所有可见对象,传具体笔号则只打该笔关联的对象。这个接口是异步的:它下发指令后立刻返回,实际加工在控制卡的实时系统里完成。如果代码在调用后马上断开连接或关闭进程,打标会中断,这是新手最容易犯的错误——以为返回1就是打完了。
要可靠地知道打标进度,必须注册状态回调。常见做法是在DLL里声明一个回调接口,当打标开始、逐笔完成、全部结束时由DLL内部线程触发。打标执行和参数设置的DllImport声明与前面Connect的写法一致,这里直接用包装类方法。下面这个完整流程把加载模板、清空对象、加动态文本、设参数、执行、等待结束串起来:
private static AutoResetEvent _markDone = new AutoResetEvent(false); // 状态回调:nState为0表示全部打标结束 private static void MarkStateCallback(int nState) { if (nState == 0) { _markDone.Set(); } else if (nState == 1) { Console.WriteLine("[EZCAD] 打标开始"); } } public bool ExecuteMark(string ezdPath, string serialNo) { // 1. 加载模板文件,里面包含固定图形和笔参数 if (!LoadFile(ezdPath)) return false; // 2. 清空旧对象,避免上一轮残留污染本次加工 EzCad2_DeleteAll(); // 3. 添加动态文本:内容为流水号,位置(25,10)单位毫米 // 包装类内部会把string编码成GBK字节 AddText(2, serialNo, 25.0, 10.0, 5.0, 0); // 4. 设置2号笔参数 EzCad2_SetMarkParam(2, 800, 75, 60, 0, 0, 0, 0, 0, 0, 0, 0, 500); // 5. 执行打标(异步),等待结束或超时 EzCad2_Mark(-1); if (_markDone.WaitOne(TimeSpan.FromSeconds(30))) { Console.WriteLine("[EZCAD] 打标完成"); return true; } Console.WriteLine("[EZCAD] 打标超时"); return false; }这段代码是二次开发最核心的骨架。状态回调函数运行在DLL内部线程,所以不能在里面直接操作UI控件,我用AutoResetEvent把异步事件转成同步等待,主线程在WaitOne处阻塞直到打标结束或30秒超时。超时机制一定要有,因为激光器异常、振镜卡死、保护开关被触发都会让打标永远不结束,没有超时就会让上位机进程挂死。
回调的状态值含义在不同版本库里略有差异,这里的0和1是常见定义。拿到开发包后第一步应该建一个测试工程,把所有回调状态打印出来,确认完含义再写业务逻辑,不要凭别人的博客猜。另一个细节:回调触发后,DLL内部可能还有收尾工作,比如关光延时、机构IO复位,严谨的做法是在收到结束状态后再等一小段时间,或者轮询状态查询接口,直到状态完全空闲。这个等待时间一般几十毫秒到几百毫秒,具体以激光器关光特性为准。
4. EZCAD 2.7二次开发避坑指南:加密狗、线程与坐标偏移
4.1 加密狗驱动冲突导致DLL加载失败
现象:主程序EZCAD 2.7能打开,手动打标也正常,但用二次开发函数库写出来的程序一调连接函数就返回失败,有的版本直接抛DLL加载异常。
原因:主程序和开发库虽然共用加密狗,但加载加密狗驱动的入口不同。设备厂提供的驱动组件可能被杀毒软件拦掉了,或者系统里残留了旧版本组件,版本冲突导致开发库拿不到授权句柄。另一种常见情况是设备厂在出厂时换过加密狗批次,配套的授权组件在系统服务里没启动。
解决:先杀毒软件白名单把EZCAD安装目录和工程目录都加进去,重装一遍加密狗驱动;然后用系统服务管理检查相关的授权服务是否在运行;还不行的话把Windows事件查看器里关于DLL加载的错误日志捞出来看具体失败模块。这套排查流程走完,八成问题能定位。
4.2 回调线程不能直接碰UI
现象:在状态回调函数里写了一句文本框赋值代码,程序直接崩溃,或者界面卡死几秒后恢复,但偶发闪退。
原因:回调函数运行在DLL创建的工作线程,不是UI线程。Windows的WinForm/WPF规定UI控件只能由创建它的线程访问,跨线程操作是非法访问。这个问题不是每次必现,被打标进度的时序影响,看起来特别像随机崩溃,容易误导你往内存方向查。
解决:回调里只做一件事——把状态塞进线程安全队列或调用BeginInvoke。WinForm里推荐Control.BeginInvoke,它会异步地把更新动作投递到UI线程,不会阻塞打标流程。控制台程序则用ConcurrentQueue收集状态,主线程每50毫秒轮询一次。记住血泪教训:永远不要在回调线程里加Sleep、弹窗或写数据库,这类操作会让打标中断。
4.3 坐标单位:毫米、像素和振镜场镜的三角关系
现象:通过代码设置位置(10,10),打出来的位置在工件上偏出去好几毫米;或者旋转角度设置90度,实际旋转方向和界面预览相反。
原因:EZCAD二次开发的用户坐标系默认是毫米,但底层振镜控制走的是16位DAC坐标,中间靠场镜校正文件做映射。部分开发库接口里混用了两种坐标体系,比如有些版本的位置参数是DAC值而不是毫米。像素就更麻烦了,从相机拍照定位来的像素坐标,必须先标定出每毫米像素数,再转换,反着用必偏。
解决:拿到开发包先把头文件里带位置和尺寸的参数注释读一遍,分清哪些是毫米、哪些是DAC值。如果一个接口文档里写的是逻辑单位,那多半已经过了一层换算,直接传毫米即可;写的是计数或脉冲数,就需要你自己做换算。调试时用红光预览接口把轨迹先射出来,位置对了再开光,能省下大量报废工件。
4.4 中文路径与文本编码乱码
现象:加载模板文件传入中文路径返回失败;传入的文本是"零件A-01",打出来变成"零件?-01"。
原因:二次开发函数2.5的很多接口按ANSI字符串设计,C#里的string默认是Unicode,DllImport加了CharSet.Ansi后运行时按系统代码页转换。系统代码页在中文Windows里是GBK,但如果你把工程文件放到纯英文路径、而打标内容本身含中文,内部处理时仍然可能走错误的多字节转换。
解决:统一的稳妥做法是把路径和文本先编码成GBK字节数组再传,不要依赖DllImport的字符串封送。编码时要考虑非中文字符,用Encoding.GetEncoding(936)。另外工程文件路径尽量用英文,模板文件名、Logo位图路径全部避免中文。我在一个实际产线上见过因为工件批次号里带了一个"号"字,导致序列号打出来错位的案例,排查到最后就是编码不一致。
4.5 重复连接与文档句柄泄漏
现象:服务程序跑一天后,调打标函数越来越慢,最后控制卡无响应,重启程序又正常;或者动态创建文本调用几百次后内存持续上升。
原因:一条是连接泄漏——代码里连接之后没有配对的断开,更常见的是异常分支提前return跳过了断开。另一条是文档对象泄漏——每次打标前创建了对象,但打标后没有清空,对象不断堆积在文档里,控制卡需要维护的图元列表越来越长。
解决:把连接和文档生命周期写进try-catch-finally,断开操作放finally里,确保异常时也释放。每次打标任务在结束后立即清空对象,需要保留的模板对象从模板文件重新加载,而不是靠内存里残留。可以做一个内存监控:任务循环里每100次输出一次进程工作集,如果持续上升,基本可以断定有句柄或对象泄漏。这个检查要放在打标压力测试阶段,别等上线后半夜被产线电话叫醒。
5. 从Demo到产线:把二次开发封装成稳定打标服务
5.1 任务队列与单实例互斥
Demo能打标只是起点,产线环境最大的区别是并发。一台打标机往往有多个上游触发源:扫码枪触发、PLC信号、MES网络下发、人工按钮。如果每个触发源都直接调DLL里的函数,二次开发库不是线程安全的,两个线程同时调用动态加文本或打标函数,轻则打标内容错乱,重则控制卡崩掉。
我一般会把所有DLL调用收敛到一个工作线程里,外部请求只进队列。C#里用BlockingCollection做生产者消费者模型是最顺手的方案:
BlockingCollection<MarkTask> _taskQueue = new BlockingCollection<MarkTask>(); // 生产者:任何地方往队列丢任务,不直接碰DLL public void Enqueue(string content) { _taskQueue.Add(new MarkTask { Content = content, Sn = Guid.NewGuid().ToString() }); } // 唯一的工作线程 private void WorkerLoop() { foreach (var task in _taskQueue.GetConsumingEnumerable()) { // 完整流程:加载模板->清空对象->加文本->设参数->打标->等待结束 var ok = ExecuteMark(_templatePath, task.Content); // 上报MES或写日志 } }这个模式的要点是"所有DLL调用只发生在WorkerLoop一个线程里",流程外任何地方不得出现二次开发库开头的函数。这样序列号生成、工件切换、参数修改都变成队列里的一个任务,不会出现半路插入打标的情况。跨进程的单实例互斥用命名Mutex实现,确保上位机即使被重复拉起也不会出现两个进程抢同一个控制卡,这是产线部署的底线。
5.2 故障恢复与日志设计
产线环境不死机不现实,但程序要在故障后自己站起来。基于二次开发库的特性,我推荐一个简单的状态机:正常态、打标中、故障态。打标超时或连接失败就进入故障态,先断开再连接重置,重置成功后回到正常态。不要试图在故障态继续下发打标指令,那样往往会把控制卡彻底卡死。
日志设计是另一个容易做浅的地方。单个任务日志至少记录四件事:任务入队时间、开始打标时间、结束回调时间、最终结果。有了这三个时间戳,你才能判断是队列堆积导致延迟,还是打标本身超时。参数异常在产线上一旦发生往往批量出现,所以每次打标前把当前对象数、笔参数摘要写进日志,排查时对照着看就能快速锁定是配置错了还是硬件漂移。我见过一个工厂排查"每批第17件都打重影",最后就是从日志里发现第17件的打标速度比正常值低,定位到是参数模板的索引越界。
5.3 进阶技巧:参数模板驱动不同工件
当工件类型超过五种,代码里就别再写死参数了。把"工件类型→打标内容→笔参数"抽象成模板,程序只解释模板不修改参数,是让整个打标服务具备可维护性的关键一步。常见的做法是用JSON做模板映射:
{ "jobId": "AL6061_BATCH_A", "textTemplate": "SN:{sn}", "pen": 2, "speed": 800, "power": 75, "frequency": 60, "position": { "x": 25.0, "y": 10.0 }, "height": 5.0, "rotation": 0 }这里textTemplate里的{sn}由代码在入队时替换成真实序列号,position和pen对应动态加文本参数,speed/power/frequency对应参数设置函数。这样一个新工件上线时,只需要在配置中心加一条模板,不用改代码、不用停止服务。我参与过的某自动化项目里,产线有四十多种工件,靠这套模板机制把开发量从每个工件改一次代码压缩到只配一次JSON,打标程序本身半年没动过。
6. 验证二次开发成果:三个必须做的稳定性压测
6.1 连续打标压力测试
闭环跑通之后,第一件事是连续打标500次,中间不放任何异常场景。每50次记录一次进程工作集和打标耗时,如果内存持续增长或耗时逐渐拉长,说明对象清理或连接管理有泄漏。这个测试能暴露大多数隐性bug,而且在你还没堆业务代码时定位成本最低。
6.2 异常断电与重连测试
在打标进行到一半时直接断开控制卡电源或拨掉USB线,模拟产线断电,然后重新上电,看程序能否在任务超时后自动进入故障恢复流程。这一步能验证你的状态机到底管不管用。多数二次开发库在异常断连后,直接再次连接是失败的,必须先断开再连接,这个规律要在压测里确认。
6.3 与EZCAD主程序共用设备时的冲突测试
产线操作员偶尔会在这台工控机上打开EZCAD 2.7界面手动调工件,这会让你的自动打标服务面临设备抢占的问题。测试方法:你的程序在跑任务时,手动双击打开EZCAD界面,观察会不会踢掉你程序的连接,或在界面上操作保存时会不会把你正在加载的文档覆盖。如果冲突,约定互斥方案——要么物理上约定手动调试时停掉服务,要么主程序和你的服务通过一个共享锁文件协调。
我自己做这类项目有一条教训:二次开发第一周不要写任何业务代码,先把连接—加载—打标—断开这个闭环稳定跑50遍,跑通了再考虑封装和并发。测试时暴露的小问题,永远比上线后半夜报修来得便宜。这套思路不仅适用于EZCAD,凡是带硬件控制卡的自动化集成项目都差不多。希望帮到你。
本文还有配套的精品资源,点击获取