dp 的笔记
上位机、机器视觉、工业通讯,还有考研和建站路上算过一遍的事。
最新文章
2 核 2G 的服务器上怎么放下三个站
主站、博客全静态,英语站一个 Node 进程,前面一个 Caddy。带宽只有 3 Mbps,所以字体和图片都要省。
工业通讯RS-232、RS-422、RS-485 详解
三种串口标准各自解决了什么问题、电平和距离速率怎么比、DB9 引脚和接线怎么接。补充现场最常见的问题:A/B 线反了、终端电阻乱加、星形接线,以及 485 半双工的收发切换。
C# 语言C# 结构和类的区别
struct 是值类型、class 是引用类型,由此带来的复制语义、继承、构造和回收上的差异,以及项目里什么时候该用 struct。补充了「值类型一定在栈上」这个常见误解。
工业通讯WinForm 里的简单 HTTP 服务器与客户端
同事说「用 WebApi、Get、Post 传数据」,其实就是 HTTP。用 HttpListener 写一个带路由的小服务器、用 HttpClient 写客户端,和 AGV 调度系统交换 JSON。顺带纠正几个关于 HTTP 的常见误解:连接、超时、权限。
C# 语言C# 委托与事件
委托是可以存方法的类型,事件是只允许外部订阅、只允许自己触发的委托。多播委托的返回值、GetInvocationList、防止重复订阅,以及 Action/Func 和 EventHandler 的标准写法。
C# 语言C# 多线程(四):异步调用容易踩的坑
for 循环里 Task.Run 捕获循环变量,打印出来的全是错的;原因是闭包捕获的是变量本身而不是值。顺带补上另外几个常见的坑:界面线程上 .Result 死锁、async void 吞异常、忘记 await。
机器视觉相机取图后转成视觉库的图像
用相机厂家的 SDK 取图,拿到的是一块像素缓冲区,要转成 Halcon、VisionPro 能用的图像。以大华相机为例转 HImage,修正原代码里 fixed 用错的隐患,补充行填充、彩色和 Bayer 格式的处理。
机器视觉Halcon 在 C# 里的数据类型转换
封装 Halcon 代码时常用的转换:HObject 转 HImage、HRegion,HTuple 和 int、double、string、数组互转,HImage 和 Bitmap 互转。重点是 Bitmap 的行对齐(Stride)和对象的释放。
C# 语言C# 多线程(二):Thread
Thread 的前台与后台、启动、线程状态、Join 等待,以及为什么不该再用 Abort:.NET 5 以后它直接抛异常。改用 CancellationToken 或标志位让线程自己退出。
C# 语言C# 多线程(三):Thread 和 Task 怎么选
从创建管理、异步编程、返回值、异常、线程复用五个方面比较 Thread 和 Task,最后给一张上位机开发里的选型表。
C# 语言C# 多线程(一):Task
Task 的五种用法:后台执行、await 等待、WhenAll 并行、异常处理、CancellationToken 取消。顺带纠正原文里 new Task 包 async 方法导致 WhenAll 等不到的真正原因。
WinForm用 LiveCharts 画实时时序图
用 LiveCharts 的 StepLineSeries 画 E84 信号的实时步进图:时间轴、枚举标签、实时追加数据,以及悬停时线越来越粗的问题和改源码的办法。补充数据量控制和更适合高频数据的图表库。
机器视觉Halcon:在 HWindow 上显示文字
视觉项目里要在图像窗口上叠加检测结果:DispText 和 WriteString 两种方式的用法和区别;部署到别的电脑报 #5123、#5137 的原因是缺了 hcanvas.dll,以及它对字体格式的影响;字被盖掉和刷新闪烁的处理。
运维踩坑浏览器提示「你的连接不是专用连接」
Edge、Chrome 打开内网设备的 HTTPS 页面被拦住,而且没有「继续访问」按钮。临时办法是在页面上直接敲 thisisunsafe;根本的办法是弄明白证书为什么不被信任:时间不对、自签名、域名不匹配,各有各的修法。
工业通讯VS2019 发布和调用 WebService,以及 IIS 的坑
对接工厂 MES 时用到的 WebService:新建 ASMX 服务、发布到 IIS、客户端添加服务引用调用。把三篇踩坑记录合在一起:没有 IIS 管理器、HTTP 403.14、测试页只能本机访问等。
机器视觉相机标定(二):九点标定和旋转中心
相机固定时引导模组或机械手定位的两种情况:只需要 XY 定位时,九点标定加示教基准;需要纠正角度时,再标定旋转中心,用旋转公式算出补偿量。补充眼在手上的做法和精度要点。
机器视觉相机标定(一):世界、相机、图像、像素四个坐标系
标定要解决的是「图像里的一个像素对应现实中的哪个位置」。理清四个坐标系的含义,以及它们之间一步步的转换:旋转平移、透视投影、单位换算,最后合成内参和外参矩阵。
机器视觉HDevelop 的语法:变量、元组、判断和循环
HDevelop 脚本和 C# 不太一样的地方:变量不用声明、赋值用 :=、数组是元组、下标从 0 开始、if 和 for 要用 endif、endfor 结尾。附一张和 C# 的对照表。
机器视觉Halcon:HWindow 以鼠标为中心缩放和拖动
HWindowControl 的缩放和平移都靠 SetPart:显示图像的一部分就是放大,移动这部分就是平移。推导以鼠标为中心缩放的公式,实现滚轮缩放、左键拖动和双击还原,并解决拖动时的闪烁。
机器视觉Halcon 入门:XL 版本、算子签名和第一个程序
Halcon 和 Halcon XL 有什么区别;算子签名里那三个冒号是什么意思;dev_open_window、read_image 这几个最先用到的算子。五篇入门短笔记合在一起。
运维踩坑Windows 局域网共享文件夹
现场 U 盘被禁用、网络受限时,用局域网共享在两台电脑之间传文件:打开网络发现和文件共享、设置共享和 NTFS 权限、用 \\IP 访问。补充访问不了时的排查,以及别把整个盘共享给 Everyone。
WinFormWinForm 常用控件:TreeView 与 DateTimePicker
TreeView 的节点增删、图标、选中事件和 FullPath;DateTimePicker 的显示格式、自定义格式和取值。补充:大量节点时的 BeginUpdate,以及只选日期、选时间段的写法。
机器视觉VisionPro 脚本:调试与调用自己的 DLL
VisionPro 的 C# 脚本看不到内部运行,用 VS 附加进程断点调试;脚本里引用自己封装的 DLL,要放对目录、带上依赖。补充 GroupRun 返回值的含义和脚本里写文件的注意事项。
C# 语言什么对象会被 .NET 垃圾回收
对象不再被任何根引用时就成了垃圾。原文只记了两种情况,这次补上 GC 的根、分代、什么时候回收,以及上位机里最常见的「其实没被回收」的内存泄漏。
工业通讯西门子 PLC 通讯(四):C# 用 S7.Net 读写 1500
用开源库 S7.Net 读写 S7-1500 的 DB 块:连接、按地址读、按类型读、写入,Bit 到 LReal 的常用类型和 String、WString 的特殊处理。补充:批量读取、断线重连和线程安全。
工业通讯西门子 PLC 通讯(三):用 NetToPLCsim 连普通 PLCSIM
博图自带的 PLCSIM 外部程序连不上,NetToPLCsim 把它转发到本机网卡的 102 端口,上位机就能像连真 PLC 一样连它。比 PLCSIM Advanced 轻量,五步配好。
工业通讯倍福 PLC:C# 用 ADS 读写变量和结构体
TwinCAT 的 ADS 通讯:按变量名拿句柄、读写基本类型和字符串,重点是结构体和结构体数组怎么在 C# 里定义才能和 PLC 的内存对上(pack_mode 与 Pack、MarshalAs)。补充:变量通知代替轮询、端口和路由。
WinFormC# 实现一个虚拟键盘
触摸屏工控机没有实体键盘,用 keybd_event 模拟按键做一个屏幕键盘:单键、组合键、中文输入。补充:按钮不能抢焦点、更推荐的 SendInput,以及直接调用系统触摸键盘。
WinFormWinForm 加载界面卡死:UI 线程被堵住了
在 Main 里先 Show 一个加载窗体再做初始化,进度条和文字都不动。原因是消息循环还没跑起来。解决办法是让加载窗体在自己的线程里 Application.Run;同类问题「Show 之后窗体显示不全」也一并说清楚。
运维踩坑Windows 远程桌面:账户没有密码也能连
工控机的账户通常没设密码,而 Windows 默认不允许空密码账户远程登录。改一条组策略就能连,但这等于给局域网开了一扇不上锁的门。更推荐的做法是设个密码、让工控机自动登录。
运维踩坑MySQL:information_schema 与特殊列名
按天分表的数据要定期清理,先用 information_schema.TABLES 查出某个库里的表名;LIKE 里的下划线是通配符要转义;列名里有冒号、横杠这种字符时用反引号括起来。补充:比按天分表更好的分区表。
运维踩坑MySQL:安装时启动超时,以及更换数据目录
MySQL 5.7 安装到 Start the Server 一直失败,原因是计算机名是中文;把数据目录从 C 盘挪到 D 盘的完整步骤,以及改完 my.ini 服务起不来(文件编码、残留进程、目录权限)的排查。
运维踩坑上位机写数据库中文乱码
C# 读写 MySQL,中文列名读出来是乱码、插入中文报错。在连接字符串里加上字符集就好了。再把乱码可能出现的四个环节理一遍:表的字符集、连接的字符集、客户端显示,以及为什么要用 utf8mb4。
计算机基础字符编码:ASCII、GBK 与 Unicode
字符、字符集、编码方式三个概念分清楚;中文字符集的包含关系;UTF-8、UTF-16、UTF-32 的编码规则;大端小端和 BOM。乱码问题基本都能从这里找到原因。
工业通讯西门子 PLC 通讯(一):数据在 DB 块里怎么存
上位机按地址读写 PLC 之前,得先知道每种类型占几个字节、怎么排列:String 和 WString 的头部、Bool 的位地址、大端字节序、偶数对齐,以及为什么要关掉「优化的块访问」。
工业通讯西门子 PLC 通讯(二):博图 V16 与 PLCSIM Advanced 仿真
没有真 PLC 时,用 PLCSIM Advanced 仿真一台 S7-1500,让上位机通过网络连上它:AMD 电脑的兼容性坑、软件安装、博图项目必须打开的几个选项、启动仿真实例和下载程序。
运维踩坑工控机通电自动开机,并自动启动软件
设备一上电,工控机自动开机、自动登录、自动打开上位机软件。BIOS 里设置来电开机,Windows 设置自动登录,再用启动文件夹或任务计划程序启动软件。两篇合在一起,补上自动登录和管理员权限的问题。
C# 语言JSON 与 XML 速查
JSON 的语法规则和一个嵌套示例,XML 的五个转义字符,以及高并发读写 XML 文件时「文件被占用」的真正原因和处理办法。最后补上 C# 里序列化 JSON 和 XML 的现代写法。
WinFormWinForm 窗体闪烁怎么办
关闭 ShowDialog 弹出的窗体时主窗体一闪,原因是在 Close 之后又 Dispose 了自己。顺带整理 WinForm 里其他几种常见闪烁的原因和办法:双缓冲、WS_EX_COMPOSITED、SuspendLayout。
WinFormWinForm 的颜色与画刷
控件颜色的三种来源(自定义、Web、系统)在代码里分别怎么写,Color.FromArgb 的几个重载和 32 位 ARGB;再加上 GDI+ 五种画刷的用法和效果图。
C# 语言C# 自定义特性与反射
写一个自定义特性贴到类、属性、字段、方法上,再用反射把它们读出来。最后讲讲这套组合在实际项目里能做什么:配置映射、PLC 点表、表格列名。
C# 语言C# 里的各种问号
可空类型 int?、三元运算符、空条件运算符 ?.、空合并运算符 ?? 和 ??=,还有 C# 8 的可空引用类型。一张表把 C# 里所有的问号理清楚。
C# 语言C# 扩展方法
不改原类型、不继承,也能给 string、DataTable 或自己的类「加」方法。扩展方法的三个要素、调用优先级,以及它的本质:编译成静态方法调用。
WinFormWinForm 窗体句柄什么时候创建,事件按什么顺序
new 一个窗体并不会创建窗口句柄,Show 或 Application.Run 时才会;这就是对刚 new 出来的窗体调用 Invoke 会报错的原因。附窗体显示和关闭的完整事件顺序。
运维踩坑VS 缺组件:SignTool.exe 与 .NET Framework 目标包
项目从 VS2019 拿到 VS2015 上发布,报「未找到 SignTool.exe」;换电脑打开老项目,报找不到 .NET Framework 的引用程序集。两个都是缺组件,分别说清楚原因和装什么。
运维踩坑VS 里中文乱码:源文件的编码
同一份代码,一台电脑上正常,换台电脑编译后中文字符串变成乱码。原因是源文件存成了 GB2312 且没有 BOM,编译器按另一台机器的默认编码去读。把源文件统一存成带 BOM 的 UTF-8,再用 .editorconfig 固定下来。
WinFormWinForm 小坑合集
窗体图标、边框样式、启动位置;ComboBox 清空后怎么设 SelectedIndex;窗体隐藏时停止刷新;无边框窗体最大化遮住任务栏;只允许运行一个实例。五篇短笔记合在一起。
计算机基础在 VS 内存窗口里看 C# 变量
用 unsafe 指针拿到变量地址,在 VS 的内存窗口里看它的字节,顺便验证小端序;再用指针改其中两个字节,看值怎么变。
C# 语言C# 迭代器(一):IEnumerable 与 IEnumerator
foreach 背后是 IEnumerable 和 IEnumerator 两个接口:一个负责「给出迭代器」,一个负责「一个个往下走」。手写一个能被 foreach 遍历的集合,再把 foreach 自己展开一遍。
C# 语言C# 迭代器(二):yield
yield return 让编译器替你写迭代器:方法在每个 yield 处「暂停」,下次 MoveNext 时从原地继续。用一个手写链表演示执行顺序、yield break,以及 yield 的限制和延迟执行的坑。
C# 语言C# 字符串拼接:+、String.Format 与 $
用 ILDASM 看三种拼接方式编译后变成了什么:+ 变成 String.Concat,$ 在老编译器里变成 String.Format。再补上 C# 10 以后插值字符串的变化和 StringBuilder 的使用时机。
C# 语言读懂 .NET IL 代码
C# 先编译成 IL,再由 JIT 编译成机器码。把 ILDasm 加进 VS 的外部工具,逐条读懂一个 for 循环的 IL 指令:计算栈、局部变量表、装箱和跳转。
计算机基础浮点数在内存里长什么样
IEEE 754 把小数拆成符号位、阶码、尾数三段。以 float 的 -5.1 为例一步步算出它在内存里的 32 位,也就明白了浮点数为什么会有误差。
计算机基础原码、反码、补码,以及负数取模
计算机为什么用补码存负数,补码怎么算、为什么取反加一就对了,顺带讲清楚负数取模在不同语言里的结果为什么不一样。
计算机基础进制:从数苹果到互相转换
十进制、二进制、八进制、十六进制是怎么来的,它们之间怎么手算转换,以及二进制和八、十六进制之间的分组小技巧。
C# 语言C# 计算代码运行时间
Stopwatch 和 DateTime 相减两种办法,为什么测性能该用 Stopwatch,以及想认真比较两段代码快慢时该用 BenchmarkDotNet。
C# 语言C# 基础:命名空间与访问修饰符
命名空间就像文件夹,两种引用方式和重名时怎么办;六种访问修饰符的范围,以及类、接口、枚举、结构体各自的默认修饰符。