目前很多便宜的激光雕刻机都是直接使用Arduino板子为主控直接组装的,其实只要往ATmega328芯片烧录网上GRBL的固件即可(同时做好外围供电电路),但本文则是从零开始讲述各个硬件及软件的组建,废话不多说,以下主要讲述4个方面:X、Y轴的硬件平台组成;驱动电路及行程限位;激光模组;主控及软件分析;
1. XY轴硬件组成。
其实很简单,为了尽量节约成本,除激光模块及主控芯片外成本也就4块钱(光驱是从古董电脑里免费拆的)。
两个光驱,把激光部分及其附属电路拆下,就留一个能固定东西的导轨,一个平放做Y轴,一个横着固定在架子上做X轴,固定的架子也很简单,直接利用下面光驱上另一块铁片折弯90°做的,再加上几根扎带固定,图中的中性笔笔芯用来固定X轴的水平度。
弄个坏的手机背盖做平台(Sony Z1后盖),用双面胶粘在Y轴的滑块上,不过注意要保持水平度。
2. 驱动电路及行程开关
驱动芯片采用国产便宜的芯片MD127,低电压驱动芯片(2.7-5.5V均可)
当然淘宝上也有很多类似的芯片价格也就1元左右。电源处必须加10uF电容,少了它将无法工作。但需注意一点:此芯片不支持细分,也就是无法将每步分得更细,只能8步为一周期(相当于1/2细分),因此精度也就每步0.07mm,随之而来的就是相当大的误差,这个必须由程序去弥补,下面会说到。
限位开关采用光电对管,一个红外发射一个红外接收,当其中有东西挡在它们之间时接收管则会因无光而断开回路。
注意挡片要不透光的
原理如上,挡住时(黄色线)输出高(10K上拉电阻),没挡住时输出低。
3. 激光模组
说实话这激光便宜的还真买不得,我这个50多块,100mW 蓝紫激光,不到一个月因激光衰减换过一次激光头,老板说工作温度不得超过50度,于是我加了个大风扇专门吹它,大冬天的人都快冷怕了。可是不到20天后激光模组又无法雕刻了,因为平时调试时都是把激光关掉或用PWM把光调暗,目前只能再去买个了,说实话这个衰减还真跟温度无直接关系,自从上次换过后平时最高温度不超过30度(摸上去冰冷的)。
由于激光模组只有2根线(电源+、电源-),因此在电源-极串加N沟道场效应管SI2306,因为其内部有恒流电路,因此占空比<2%时输出弱光(相当于提供一个达不到恒流芯片工作的电压),频率要求不高,约1kHz左右,电源5V。
固定外面的散热铝块到X轴滑块上,背面贴了双面胶,再用扎带捆住。前面2颗螺丝用来固定激光模组。
4. 主控、主体软件
其实上面3点均不难,怎么做基本都能实现,仅是精度上的问题而已。但软件则不同,错一点可能整幅作品就全废了。
首先是硬件电路图,为了简单明了就没用电路绘图软件了:
电路很简单,整个系统可以在3V电源下正常工作(注意给STM32F103主控芯片的电源搞好点,免得串口读到的数据有误),也就是电池都能轻松带动。整个实物如下,由于未全部整合,主控等目前用杜邦线相连:
接着是软件部分,也是最关键的,首先肯定是如何驱动光驱的步进电机,一般光驱传动轴转一圈前进(后退)3mm,由于是1/2细分,故需40步才能转1圈(不细分时20步走一圈),也就是每步进1mm需要13.33步(脉冲)--13.33 step/mm,每个步进电机需4个IO控制(以下用M1_O1~M1_O4表示,即电机M1的OUT1~4,_H表示输出高,_L表示输出低)
以上两个函数为电机驱动的底层函数,实现的主要目的是输入步数和方向来控制电机的输出。
底层步进电机驱动函数外,软件上主要需解决3个方面问题:1、串口通信部分;2、常用的指令逐个解析及回复;3、CNC插补算法。
● 串口通信,串口一般9600的波特率,虽然速度不快但需对串口数据接收及主程序的执行控制好,一边对串口收到的数据不可漏掉或未读完就提取指令;一边要对输出进行计算同时电机输出也得控制好。本程序里是先给串口接收区划分一个1000字节的缓冲区,同时来再多数据也能不拉下(GRBL有时一次最大发送700字节的指令,故在此不得不设置一个大点的区域),若单片机的寄存器不能设置那么大,其实也可以设置一个环形的缓冲区域:
主程序每200ms判断一次串口是否收到数据,若有数据则收到数据标记位置位(USART_RX_STA的bit7置为1)。
另外在主程序解析串口数据时也要监测串口中是否又来了新的数据,
- H1:
- if(USART_RX_STA&0x01)Wait_Nodata();//若有数据来了则等待接收完
- /………解析指令部分………/
- if(uart_buf_index<USART_RX_NUM && uart_buf_index)goto H1;//本条指令读取结束,看是否读取数据完毕,若还有未读完的则再循环读取. USART_RX_NUM串口总数据长度,uart_buf_index当前解析指令的位置。
- //判断是否还有数据的函数,等待接收完
- u8 Wait_Nodata()//等待串口无数据,有数据时USART_RX_STA的bit0会置1
- {
- do{
- USART_RX_STA &= 0xFE;
- delay_ms_loop(70);//延时70ms
- }while( USART_RX_STA&0x01);
- return 0;
- }
● 指令解析及回复
指令主要有G0、G01、G02、G03、G90、G92、M2、M3、M4、M5,用法及意义如下:
G0 快速定位,如:G00 X10.111 Y3.254 即移动到10.111,3.254的位置
G01 直线插补,不是G0那样最快移动到目的地,如:G01 X10.111 Y3.254 表示从当前坐标位置直线移动到10.111,3.254,经过的路径是一条直线
G02 顺圆插补,顺时针的圆弧插补,如 G02 X1.211 Y3.222 I-1.0 J2.111 ‘X1.211 Y3.222’表示圆弧终点是1.211,3.222,圆弧的圆心是距离当前机器坐标(-1.0,2.111)的位置
G03 与G02类似,只是变为逆时针的圆弧
G90 表示当前的执行参数为绝对尺寸,G91为相对尺寸,例如:G91 G00 X10 Y10且当前位置是(1,1),则最后执行后将停在(11,11),而G90 则是停在(10,10)的位置
G92 强制设定当前的坐标值
M2 表示程序结束。注意在收到此条指令后需发送“Grbl 0.8c ['$' for help]”,即GRBL版本号
M3、M4对于激光雕刻来说意义不大(都是表示开启激光),切割时表示电机的正反转
M5 关闭激光或电机
此外在收到0x18时需返回“Grbl 0.8c ['$' for help]”,收到’$G’时需回复“[G0 G54 G17 G21 G90 G94 M0 M5 M9 T0 F250.000]”,只是从原固件程序模仿的,实际参数意义不大。收到“$$”时需回复$0-$22各参数的配置,目前主要用到的是$0、$1,$0表示x轴的精度step/mm,即1毫米需要多少步才能到,$1表示y轴的 (step/mm)。设置$0则发送$0=13.333即可。
当电脑端发送’?’时,表示请求获取当前机器的状态及工作坐标,此时回复“<Run,MPos:1.234,1.444,0.000,WPos:1.231,1.451,0.000>”,Run表示机器有轴正在运行,Idle表示处于空闲,后面分别则是机器坐标、工作坐标(X Y Z三个轴的坐标)
注意收到的每条指令均是以16进制0x0D为结尾,回复指令时则回复 0x0D 0x0A两字节为结尾。
Arduino有个IO单独监控串口的DTR,当串口被打开时,DTR会产生一个脉冲,此时Arduino的主控会发送“Grbl 0.8c ['$' for help]”来请求连接主机。接着电脑软件会依次发送?、$G、$$三条指令来获取基本信息。
解析这些指令也很简单,首先读取第一字符,判断是属于哪种指令,再解析下一字节的数字代表什么功能,接着提取坐标等数值,最后执行即可。
另外每读取到一条指令后均需要返回’ok’,电脑端软件以此判断队列中还有几条指令未执行,若未执行的指令过多软件就会等待(默认是等待50S),遇到无法解析的指令时则发送error: Expected command 来反馈无法解析此指令。
[ 此帖被ly7317090803在2015-12-31 17:03重新编辑 ]