上位机的程序主要是解析图片和生成较好的代码,现在实现的功能有灰度打印,二值打印,轮廓打印,骨骼打印。当然,必不可少的是打印大小的控制。测试了一些图片,总体来说,打印速度依次加快,因为打印的内容依次减少。但是还有一些不太满意的地方,例如用轮廓和骨骼打印来打印文字时,东一块西一块,还没有空闲写行识别之后的排序。其实思路挺简单,膨胀文字或腐蚀背景使一行变为位置相邻的点集,然后在外包矩形内进行按x递增排序就可以了。

上位机总体功能分为三部分:

1、与下位机通讯,这部分建议先写好,才更利于后面的测试。

2、图片处理——灰度、二值、边缘、骨骼。

3、灰度、二值、边缘、骨骼点数组转命令。

一、图片处理

我nuget了一个opencvsharp,所以很多基础代码都不用写了。只需要稍加封装使frm中的代码更简洁易易懂于维护就可以了。这里简单说一下mat类点的颜色设置:

ImgEdge = New Mat(ImgBinary.Size, MatType.CV_8U)
ImgEdge.Set(Of Byte)(p.Y, p.X, 0)

  因为这是二值化的图像,所以用Byte写就可以了,0为黑色。当然,也可以直接操作内存指针:

            For i As Integer = ImgEdge.DataStart To ImgEdge.DataEnd
Marshal.WriteByte(i, 255)
Next

  这是我清理图片背景的代码。这样做很慢,你可以尝试用API函数来完成内存数据置零。

二、点数组转命令

    Private Shared Function Info2Command(ps() As Point) As List(Of Command)
Dim result As New List(Of Command)
Dim dx, dy As Integer
For i As Integer = 1 To ps.Count - 1
dx = ps(i).X - ps(i - 1).X
dy = ps(i).Y - ps(i - 1).Y
If dx = dy Then
result.Add(New Command(Message.c_13Move, dx * 2))
ElseIf dx = -dy Then
result.Add(New Command(Message.c_24Move, dy * 2))
Else
If dx <> 0 Then
result.Add(New Command(Message.c_xMove, dx))
End If
If dy <> 0 Then
result.Add(New Command(Message.c_yMove, dy))
End If
End If
Next
Return result
End Function

  这是我解释一个连续点集的时候使用的代码,代码中将坐标转化为命令。与xy结构不同,除了解释了x,y轴方向移动,还解释了象限角分线方向的动——它们非常容易实现,因为只需转动一个电机。这样做的好处就是仅斜向相连的点不会被解释为两次动作——除非通过更复杂的代码形成更多的指令(关闭并迅速开启激光器或抬起并落下舵机)才能使绘制的图像不比原图多出某些拐角。

三、与下位机通讯

    Private WithEvents mPort As SerialPort

  这就是所使用的核心对象,它有几个很有用的事件,其中DataReceived是我们最关心的:

    Private Sub mPort_DataReceived(sender As Object, e As SerialDataReceivedEventArgs) Handles mPort.DataReceived
Dim inData As String = CType(sender, SerialPort).ReadLine.TrimEnd({CChar(vbCr), CChar(vbLf)})
If inData = (r_RequestData) Then
RaiseEvent RequestData()
ElseIf inData = (r_Ready) Then
RaiseEvent Ready()
ElseIf inData = (r_Interrupt) Then
RaiseEvent Interrupt()
ElseIf inData = r_RerequestData Then
RaiseEvent RerequestData()
ElseIf inData <> String.Empty Then
Debug.Print("收到下位机的未知请求。[" & inData & "]")
End If
End Sub

  这用于解释下位机的不同请求。而发送数据也非常简单:

    Protected Friend Sub SendCommand(cmd As Command)
mPort.BaseStream.Flush()
mPort.Write(cmd.Data, 0, 6)
End Sub

  OK,最后简单说一下获取COM口名称:

    Dim WM_DEVICECHANGE As Integer = &H219
Dim DBT_DEVICEREMOVECOMPLETE As Integer = &H8004
Dim DBT_DEVICEARRIVAL As Integer = &H8000 Protected Overrides Sub WndProc(ByRef m As Message)
MyBase.WndProc(m)
If m.Msg = WM_DEVICECHANGE Then
If m.WParam.ToInt32 = DBT_DEVICEARRIVAL Then 'usb插入
Timer1.Enabled = True
ElseIf m.WParam.ToInt32 = DBT_DEVICEREMOVECOMPLETE Then
Timer1.Enabled = True
End If
End If
End Sub

  实际上应该用单独线程来处理,但是实在是懒得写,就用定时器来处理了。

    Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick
Dim b = New ManagementObjectSearcher("select * from Win32_PnPEntity").Get '检测即插即用设备
Dim lst As New List(Of String)
Try
For Each c In b
Try
If c.GetPropertyValue("Name").ToString.Contains("CH340") Then
lst.Add(c.GetPropertyValue("Name"))
End If
Catch ex As Exception
End Try
Next
Catch ex As Exception
End Try

  用WMI来获取,会得到很多设备名,然后都存在lst里面,剩下就是确定当前使用的是否发生了变化来确定使用哪一个了。

最近几天偷闲完善了一下上位机的程序,界面如下:

红色的部分是已经打印的部分,随着打印进行,红色的部分同步增长,这比进度条看起来更好一些。然后做了一下文字打印,主要是针对在一定的范围内打印一定的行数:

点击确定之后,得到的图像如下:

这就可以方便的打印一些文字咯。。。

"废物利用"也抄袭——“完全”DIY"绘图仪"<三、上位机程序设计>的更多相关文章

  1. "废物利用"也抄袭——“完全”DIY"绘图仪"<二、下位机程序设计>

    就不说怎么组装了吧,一把辛酸泪.说程序,因为这有两把辛酸泪……一把给下位机的C代码一把为了VB.NET的图像处理……不过就上上一篇说的,它们可以正确运行了,并且今天克服了Arduino上电过程中步进电 ...

  2. "废物利用"也抄袭——“完全”DIY"绘图仪"<一、准备工作>

    上一个光驱造已经解体若干天了,因为事情很多arduino也不太熟悉,直到今天才做出了一个可以用的样本.当然,上位机和下位机代码都写好了,可以正常工作,但是由于电路知识还是中学那点没还给老师的,加以各种 ...

  3. "废物利用"也抄袭——废旧喷墨打印机和光驱DIY"绘图仪"

    很长时间没有写博客,因为各种各样的事情占去大块时间,只有零碎时间偶尔在CSDN逛逛也偶尔回几个帖子.很久以前就看到一些光驱DIY雕刻机之类的,很是向往,最近这几天得闲就TB了一套Arduino UNO ...

  4. [No0000CA]什么是“普瑞马法则”?以及 如何利用“普瑞马法则”,三步克服惰性

    一般在学习和生活中,我们都可能有这样的经验,就是当说想要作某件事情的时候,但过了好久发现还是没有做:或者觉得有力气使不出来:或者总觉得生活是灰色和抑郁的等等. 这类情况反映在生活中,就是生活好像总是被 ...

  5. Touch Bar 废物利用系列 | 在触控栏上显示 Dock 应用图标

    都说 Intel 第八代 CPU 对比上代是牙膏不小心挤多了,而配备第八代 CPU 的 MacBook Pro,只有 Touch Bar 版本,虽然贵了一点,但就一个字 -- 买! 收到电脑后,兴冲冲 ...

  6. [自娱自乐] 4、超声波测距模块DIY笔记(四)——终结篇·基于C#上位机软件开发

    前言 上一节我们已经基本上把超声波硬件的发射和接收模块全部做好了,接下来我们着手开发一个软硬结合的基于C#的平面定位软件! 目录 一.整体思路 二.效果提前展示 2-1.软件部分展示 2-2.硬件部分 ...

  7. 实验三 Java基本程序设计(2)

                                             实验三 Java基本程序设计(2)                                           ...

  8. 20145208 实验三 Java面向对象程序设计

    20145208 实验三 Java面向对象程序设计 实验内容 初步掌握单元测试和TDD 理解并掌握面向对象三要素:封装.继承.多态 初步掌握UML建模 熟悉S.O.L.I.D原则 了解设计模式 实验步 ...

  9. 利用lipo编译合并iPhone模拟器和真机通用的静态类

    利用lipo编译合并iPhone模拟器和真机通用的静态类 如何编译静态类库,而且现在网上也有很多的教程,现在问题时我们编译好了的静态类库会时两个版本的.a文件,分别用于模拟器和iPhone真迹,因此M ...

随机推荐

  1. CSS3之嵌入Web字体

    之前如果想在自己的网站使用某些好看的字体,总是迫不得已得在PS里先把字体图片做好.虽然这样做也能达到我们想要的效果,但是这样就增加了HTTP请求(如果在多处使用的话),即使合并所有图片,也不好管理,灵 ...

  2. ubuntu16.04深度学习环境的配置【转】

    本文转载自:https://my.oschina.net/u/3837179/blog/1920756 在ubuntu中配置GPU的深度学习环境相较于win问题要多很多,这几天琢磨了一下Ubuntu下 ...

  3. linux 查看数据库和表

    mysql -h localhost -u 用戶名 -p密碼                //連接數據庫use desk_show;                                 ...

  4. Codeforces Round #404 (Div. 2) A,B,C,D,E 暴力,暴力,二分,范德蒙恒等式,树状数组+分块

    题目链接:http://codeforces.com/contest/785 A. Anton and Polyhedrons time limit per test 2 seconds memory ...

  5. poj 2828 Buy Tickets 树状数组

    Buy Tickets Description Railway tickets were difficult to buy around the Lunar New Year in China, so ...

  6. bzoj1143: [CTSC2008]祭祀river 最长反链

    题意:在遥远的东方,有一个神秘的民族,自称Y族.他们世代居住在水面上,奉龙王为神.每逢重大庆典, Y族都会在水面上举办盛大的祭祀活动.我们可以把Y族居住地水系看成一个由岔口和河道组成的网络.每条河道连 ...

  7. hdu2897找规律

    又是找规律,无语了,说好的博弈呢,搞了半天的sg函数没有一点头绪 当n%(p+q)==0时,先手win,第一次取q个,以后每次,后手取k个,先手就取p+q-k个,最后,后手必取q个 当n=(p+q)* ...

  8. 在页面和请求中分别使用XML Publisher生成PDF报表且自动上传至附件服务器

    两个技术要点: 1.使用TemplateHelper.processTemplate方法生成目标PDF的InputStream流,再使用ftp中上传流的方法将其上传至附件服务器. 2.在请求中调用AM ...

  9. 自定义jQuery的animate动画

    //擦除效果 jQuery.extend(jQuery.easing, { easeOutBack : function(x, t, b, c, d, s) { s = s || 1.3; retur ...

  10. 从客户端中检测到有潜在危险的 Request.Form 值 方法

    由于在.net中,Request时出现有HTML或Javascript等字符串时,系统会认为是危险性值.立马报出“从客户端 中检测到有潜在危险的Request.Form值”这样的错. 解决方案一:   ...