【打印虎】RepRap3D打印机G-code命令专家详解玩过一段时间3D打印机的朋友,都会接触到G-code文件。所谓G-code文件,指的是3D模型在进入3D打印机实际打印之前,必须要经过切片器处理而成的一种中间格式文件。这种中间格式文件的内容,实际上每一行都是3D打印机固件所能理解的命令。而这些命令,也被称为G-code命令,是3D打印机和电脑之间最重要的命令交互界面。上面的图,虽然是简化后的线框图,但清晰地表示了G-code命令所处的重要位置。事实上所有从计算机发送到3D打印机的内容,全部都是G-code命令,没有任何例外。不论计算机和3D打印机之间是如何连接的,用常见的USB线也好,用SD卡作为G-code文件介质也好,或是用比较新式的TCP/IP连接也可以,这个连接通道中的所有信息,都是G-code命令。这个特征非常重要,牢牢记住这个特征,可以在我们分析、解决很多3D打印机问题的时候,提供强有力的支撑。既然所有3D打印机都使用G-code作为对外联系的唯一信息交互方式,那么这种“语言”的标准就很重要了。不幸的是,虽然所有的3D打印机,都使用G-code作为与计算机的交互语言,但实际上每种3D打印机“说出”的G-code,都多多少少有些不同。这也可以说,每种3D打印机都有自己的“方言”。我们要研究G-code,就要从一种最常见的“方言”,也可以说是“普通话”开始,先了解一种,然后再学习其他类似的语言,相互对比,就很容易了。我们这篇文章,专门研究的是Repetier公司出品的Repetier-firmware固件所使用的G-code语法。如果这正是你需要的,那么就很方便了。如果你想研究的是其他3D打印机固件,比如marlin之类,那就不太巧了,有些内容可能不完全一致。不过,文章中提到的方法,仍然适用,你可以以这篇文章为基础,自己搞定对marlin的研究。这篇文章主要面向具有一定技术水平的朋友,从第一节开始,我们就开始分门别类解释每一条G-code命令,这对于已经了解如何使用G-code的朋友会比较方便。但如果你还是初学者,不知道怎么使用G-code,甚至都没有见过“活的”G-code,也没有关系,在这篇文章最后面的第十五节和第十六节,我们会详细讲解如何在Repetier-host软件中单条执行G-code命令,以及如何观察、编辑、修改一个切片器切片之后的简单的G-code文件,满足初学者的学习要求。在正式开始之前,我先给打印虎做一个小广告。日前,打印虎正式推出了自主研发的下一代3D打印机主板Salai,这个主板采用了32位ARM体系结构,CPU运行速度是传统8位主板的5倍,可以有效提高3D打印的质量,同时支持双挤出头,自带3.5英寸的TFT全彩触摸屏,配合大幅改进的Repetier-firmware固件,拥有丰富的操作功能和良好的用户界面。这个产品的固件不仅功能丰富,还是开源的,可以满足深入学习的需求!这个产品不光性能高、颜值高,核心代码开源,价格还特别低,有兴趣的朋友,可以到打印虎的产品页面,看看更详细的信息,这里就不多说了。第一节,基础运动既然G-code是计算机指挥3D打印机干活用的一套语言,那么其中最重要的就是运动类的指令。G0/G1直线移动虽然从名字上看,G0叫做“快速直线移动”,而G1叫做“直线移动”,但实际上在Repetier-firmware里面,G0和G1指令是完全等价的,没有任何区别。移动是否快速,完全是靠参数F来决定的(下面会详细介绍)。这条指令的作用也很简单,就是将挤出头线性移动到一个特定的位置。这条指令带有不少参数,完整的形式是这样的:G0XnnnYnnnZnnnEnnnFnnnSnnn或者G1XnnnYnnnZnnnEnnnFnnnSnnn使用时,不需要所有的参数全部存在,但至少要有一个参数。其中,Xnnn表示X轴的移动位置;Ynnn表示Y轴的移动位置;Znnn表示Z轴的移动位置;Ennn表示E轴(挤出头步进电机)的移动位置;Fnnn表示速度,单位是毫米/每分钟;Snnn表示是否检查限位开关,S0不检查,S1检查,缺省值是S0;举例来说,G1F1500G1X50Y25.3E22.4这样两行G-code,表示了首先将速度设置为1500mm/min,也就是25mm/s,然后将挤出头移动至x=50mm,y=25.3mm的位置上,z轴高度不变,并且将挤出头步进电机移动至22.4mm的位置上。这里,速度、xyz位置都比较好理解,但挤出头步进电机的位置怎么理解呢?移动至22.4mm处,代表着挤出了多少耗材呢?实际上,这里挤出头的具体动作,要根据之前挤出头步进电机所在的状态(也就是位置)而定。比如在这两条语句之前,挤出头步进电机已经处于20mm的位置处,那么这里挤出头步进电机只要再前进2.4mm就可以了。仔细想想,其实挤出头步进电机的工作方式,与xyz轴完全一样。xyz轴之所以比较好理解,是因为我们清楚的知道原点(0,0,0)的位置在哪里。而对于e轴来说原点的位置也会在打印开始处被初始化到0的位置。知道了原点的位置,就可以正确理解挤出头步进电机的工作方式了。实际上,挤出头步进电机仍然是以原点为基础,只不过是在整个打印过程中持续增加的。(思考:切片器的挤出头回抽动作,对应了什么样的G-code代码?)再举一例,G1F1500G1X50Y25.3E22.4F3000这个例子与上面的例子非常类似,唯一的区别,就是F参数了。而这两条语句的意义,除了对XYZE的移动之外,还会将打印速度,从语句执行开始时的1500mm/min,提高到语句执行结束时的3000mm/min。这里有两点需要注意。第一点,F参数与XYZE参数一样,在语句执行的过程中线性插值;第二点,在预先知道第一点的前提下,F参数使得计算机对3D打印机的控制更加深入和精准了。计算得当的情况下,切片器可以精确控制3D打印机的加速和减速过程,使得整个3D打印过程更加顺滑。G2/G3圆弧移动这两条命令中,G2是顺时针圆弧移动,G3是逆时针圆弧移动。命令的完整形式是:G2XnnnYnnnInnnJnnnRnnnEnnnFnnn或者G3XnnnYnnnInnnJnnnRnnnEnnnFnnn其中,Xnnn表示移动目标点的X坐标;Ynnn表示移动目标点的Y坐标;Innn表示圆心位置,值是圆心距离当前位置的X分量;Jnnn表示圆心位置,值是圆心距离当前位置的Y分量;Rnnn表示圆形的半径长度;Ennn表示E轴(挤出头步进电机)的移动位置;Fnnn表示速度,单位是毫米/每分钟;根据勾股定理,R2=I2+J2。因此,如果提供了圆心位置参数,就不需要提供半径参数了。反之,如果提供了半径参数,也可以根据当前点和目标点计算出圆心位置,就不需要提供I/J参数了。其他几个的参数用法,与G0/G1是完全一样的。G2/G3命令面临的最尴尬的问题,是常用的上位机切片器软件,包括Slic3r以及Curaengine,并不会生成这两条指令。所有3D模型中的圆弧,在STL文件中已经被转化为使用大量小线段拟合而成的曲线。这样,切片器自然也不会把这些小线段当做圆弧处理。最终的G-code输出结果,也只会存在G0/G1指令,而不会存在G2/G3指令。当然,据打印虎所知,如果你使用的是比较小众的上位机软件,比如artCAM等,因为这些软件的输入并不是STL文件,因此它们的输出G-code是很有可能出现G2/G3命令的。如果确定了你的3D打印机只会接收到G0/G1直线移动命令,那么我们完全可以在3D打印机固件配置中,定义#defineARC_SUPPORT0这样,所有与G2/G3指令相关的代码,就都不会编译,也不会包含在最终的固件代码中了。可以节省一些固件的空间,同时并不会影响任何3D打印机的功能。还有一个问题留给大家思考:在上位机切片软件输出G2/G3命令的情况下,相比于上位机切片软件输出G0/G1命令的情况,是否3D打印机打印圆形物体时会更圆呢?(答案是不会。)那么其中的原理是什么?G4暂停移动这条命令让挤出机在当前位置停止一段时间。可能的参数包括:Pnnn表示停止移动的时间,以毫秒为单位,1000毫秒等于1秒。Snnn也表示停止移动的时间,以秒为单位。因此,G4P2000命令与G4S2命令是完全等价的。G10/G11回抽/反回抽这两条命令使挤出头执行一个回抽(G10)或者相反的动作(G11)。所谓回抽,就是让E轴步进电机反转一小段。而反回抽则让E轴步进电机正转一小段。参数只有一个:Snnn表示回抽的距离。S1表示长回抽,S0表示短回抽。实际上,目前的切片器并不太依赖于G10/G11指令执行回抽动作,而是利用G1Ennn命令直接命令挤出头步进电机前进或倒退到某一个位置。因此,与G2/G3命令类似,G10/G11命令基本上是个摆设,除非未来有专门的切片器可以生成这两条指令,否则完全可以将这两条指令关闭,节省内存空间。在固件配置中,定义#defineFEATURE_RETRACTION0可以关闭G10/G11功能,在编译期去除这段相关的代码。G20/G21设置距离单位这两条命令非常简单,用于设置当前距离单位为英寸(G20)或者毫米(G21)。没有参数。未设置时缺省值是毫米。G28归零这条命令使3D打印机XYZ轴以及挤出头E轴归零。参数包括:X表示使X轴归零Y表示使Y轴归零Z表示使Z轴归零E表示重置E轴的位置为0,与XYZ轴不同的是,如果使用了E参数,E轴步进电机并不运动,而是将当前的E轴位置直接设置为0,这样下面对E轴的运动指令,都会解释为相对0点的运动。如果使用时没有任何参数,直接使用G28,等价于G28XYZ命令。这时并不会对E轴进行重置为0的操作。XYZ轴归零的顺序,由固件配置HOMEING_ORDER决定,比如定义为#defineHOMING_ORDERHOME_ORDER_XYZ就代表着先归零X轴,然后是Y轴,最后是Z轴。T设置当前挤出头对于拥有多个挤出头的3D打印机来说,需要使用T命令选择当前工作的挤出头。这条命令有一个无名参数,参数值直接跟在T后面。例如:T0表示选择第一个挤出头;T1表示选择第二个挤出头;参数是T命令最特殊的一点。这与其他所有的G-code命令都不相同。第二节,Z轴高度测试与自动调平三角洲类型的3D打印机,由于其打印速度更快,受到很多3D打印用户的欢迎。与XYZ式3D打印机最大的一个不同,在于三角洲类型3D打印机的运动计算更加复杂,很难依赖人工调平达到较好的打印效果。因此,对Z轴的自动高度测试,以及自动调平相关的功能,就显得更加重要了。以下G-code命令,是Repetier-firmware对这方面进行支持的一组命令。当然,这些功能并不仅限于三角洲类型的3D打印机。如果是包含了Z轴高度测试微动开关的XYZ式3D打印机,也同样可以使用这些功能。G29Z轴高度三点测试这条命令测试打印平面上三个点的Z轴高度,并在串口上输出结果。参数包括:Snnn测试结果的处理方式。S1表示更新内存中的Z轴高度值(重置系统会丢失),S2表示更新内存以及EEPROM中的Z轴高度值(重置系统不会丢失)。无参数时,G29命令表示只从串口上输出结果,不更新内存或EEPROM中的Z轴高度值。一般来说,只有使用高位限位开关(也就是说,Z轴的限位开关位于Z轴坐标最大处),且在挤出头上附带有Z轴高度测试微动开关的机型,适合使用G29命令测试Z轴高度。其他机械配置的机型,不适合使用G29命令。G29命令由固件配置#defineFEATURE_Z_PROBE1决定是否开启。如果这个配置项定义为0,则编译时会去除对G29命令的支持,节省内存的使用。命令执行时,打印平面上的三个点,其XY坐标由以下固件配置参数决定:#defineZ_PROBE_X1-52#defineZ_PROBE_Y1-30#defineZ_PROBE_X252#defineZ_PROBE_Y2-30#defineZ_PROBE_X30#defineZ_PROBE_Y360命令执行的开始和结束,分别会执行一段预定义的G-code。缺省