运动控制系统上位机C#源码,可用于雕刻机,切割机,写字机,点胶机。 功能描述: 1.自动解析Gcode。 2.图形还原显示。 3.显示g代码坐标文件 4.回原点控制。 5.手动控制3轴运动。 6.支持图形缩放,鼠标拖动
//Gcode解析器核心代码 public void ParseGcode(string filePath) { var lines = File.ReadAllLines(filePath); foreach(var line in lines) { //用正则干掉注释和空白 string cleanLine = Regex.Replace(line.Split(';')[0], @"\s+", " ").Trim(); if(!string.IsNullOrEmpty(cleanLine)) { var cmd = new GcodeCommand(); var segments = cleanLine.Split(' '); foreach(var seg in segments) { char prefix = seg[0]; double value = double.Parse(seg.Substring(1)); switch(char.ToUpper(prefix)) { case 'G': cmd.GType = (int)value; break; case 'X': cmd.X = value; break; case 'Y': cmd.Y = value; break; case 'Z': cmd.Z = value; break; //...其他参数处理 } } commandQueue.Enqueue(cmd); } } }这坨代码干了三件事:洗数据、拆零件、装对象。注意那个正则表达式,处理注释和多余空格相当暴力。不过实际项目里得加try-catch,不然遇到"X3.14.15"这种流氓数据直接崩给你看。
图形渲染这块有点门道,PictureBox+双缓冲是基本操作:
//图形绘制核心片段 private void pictureBox_Paint(object sender, PaintEventArgs e) { using(var g = Graphics.FromImage(canvas)) { g.Clear(Color.White); var scaleMatrix = new Matrix(); scaleMatrix.Scale(currentZoom, currentZoom); g.Transform = scaleMatrix; foreach(var path in gcodePaths) { using(var pen = new Pen(Color.Blue, 0.1f / currentZoom)) { g.DrawPath(pen, path); } } } e.Graphics.DrawImage(canvas, new Point(offsetX, offsetY)); }这里有个骚操作——笔刷粗细随缩放自动调整。currentZoom小于1的时候,线条反而变粗,避免缩放后线条消失。矩阵变换用得飞起,比手动算坐标清爽多了。
手动控制三轴的代码最有机械感:
//手动运动控制 private async void btnXPlus_Click(object sender, EventArgs e) { if(!isHoming) { await serialPort.WriteLineAsync("$J=G91 X0.1 F500"); UpdatePositionIndicator(); } }看见那个G91没?这是相对运动指令。每次点击走0.1mm,F500是进给速度。注意这里用了async/await,不然界面卡成狗。不过串口通信要加超时处理,否则卡死的时候用户能把你祖坟骂裂开。
运动控制系统上位机C#源码,可用于雕刻机,切割机,写字机,点胶机。 功能描述: 1.自动解析Gcode。 2.图形还原显示。 3.显示g代码坐标文件 4.回原点控制。 5.手动控制3轴运动。 6.支持图形缩放,鼠标拖动
回原点逻辑比想象中复杂:
List<string> homingCommands = new List<string>(){ "$HX", //X轴回零 "$HY", //Y轴回零 "$HZ" //Z轴回零 }; foreach(var cmd in homingCommands) { serialPort.WriteLine(cmd); while(!serialPort.ReadLine().Contains("ok")) { await Task.Delay(100); } }这里用了阻塞式等待,新手容易踩坑——一定要开子线程跑,不然界面直接无响应。我见过有人在这里套了三个BeginInvoke,代码写得跟千层饼似的。
缩放拖拽处理鼠标事件才是真考验:
private void pictureBox_MouseWheel(object sender, MouseEventArgs e) { float zoomFactor = e.Delta > 0 ? 1.1f : 0.9f; currentZoom *= zoomFactor; pictureBox.Invalidate(); } private void pictureBox_MouseMove(object sender, MouseEventArgs e) { if(e.Button == MouseButtons.Left) { offsetX += e.X - lastMouseX; offsetY += e.Y - lastMouseY; pictureBox.Invalidate(); } lastMouseX = e.X; lastMouseY = e.Y; }这里有个隐藏bug:没限制最小缩放值,放大到1000倍时坐标计算会溢出。解决方案是给currentZoom加个阈值限制,别问我怎么知道的——曾经把图形缩成纳米级找不回来,只能重启程序。
这套代码最牛逼的是坐标系转换,把Gcode的绝对坐标转成屏幕相对坐标,还要考虑机械限位。有个老哥在GitHub上魔改了三个月,最后把旋转雕刻功能加进去了,果然开源项目的尽头是魔改。