在上一篇文章我们完成了一次只读取一个字节的函数zf_read
那现在需要了解打印文件(后缀为gcode的文件)的指令。
不做详细的介绍,建议百度G代码或者gcode
粗略的介绍一下,现在只识别这两个指令
指令 | 功能 |
---|---|
G0 | 快速定位 |
G1 | 直线插补 |
打印文件截图,如下所示
其实G0与G1可以当成一样的
X、Y、Z后为对应的坐标,E为挤出头运行距离
F为速度(还未能实现)
注意现在设定只识别这两个指令
那现在我们需要了解一下,c++的一些函数
在string.h库中,我们在解析指令需要以下函数
函数的功能就不详细说了,在这个网站有详细的介绍
链接为:https://www.runoob.com/cprogramming/c-function-strchr.html
函数 | 功能 |
---|---|
strchr | 查找 |
strcpy | 复制 |
strtod | 转换识别字符后的字节 |
第一个函数为识别该文件是否打印完,即打印文件是否读取完毕
u8 card_eof(void)
{
if((file)->fptr == (file)->fsize)
return 1;
else return 0;
}
第二个函数为解析指令,是否存在指令
u8 code_cmdseen(char code) ///解析指令,检测是否有该指令、code为搜索的指令(G、X、Y、Z、E、F),检测出存在指令则返回1
{
if(code=='F') ///如果检测F指令
{
Fbuf=strchr(cmdbuffer[readindex],code);//扫描cmdbuffer是否有F
if(Fbuf==NULL) return 0;
if(*(Fbuf+1)>'9'||*(Fbuf+1)<'0') return 0; //若检测到F后为非数字,则返回为未检测出指令
return 1;
}
strchr_pointer = strchr(cmdbuffer[readindex],code);
if(strchr_pointer==NULL) return 0;
else
{
strcpy(cmdbuffer[readindex],strchr(cmdbuffer[readindex],code));
printf("解析指令",cmdbuffer[readindex]);//此行可省略
if (*(cmdbuffer[readindex] + 1) > '9' || *(cmdbuffer[readindex] + 1) < '0')
return 0;
return 1;
}
}
第三个函数为解析指令后的数值(前提识别出有指令)
float code_numseen(void) ///½âÎö»ñµÃÖ¸ÁîºóµÄÊýÖµ
{
cmdswitchbuf_num=(strtod(cmdbuffer[readindex]+1,&cmdswitchbuf));//获取指令后的数据,之所以加1,是因为跳过自身指令(G、X、Y、Z、E、F)后读取数值。
strcpy(cmdbuffer[readindex],cmdswitchbuf);//获取指令后的数值,那么把刚才识别的指令及数值跳过,及重新给cmdbuffer赋值
printf("获取解析指令后的数值",cmdswitchbuf_num);//可省略
return cmdswitchbuf_num;
}
第四个函数为解析指令F后的数值(前提识别出有指令)
之所以要写多一个,是因为在打印文件中,XYZ是固定的位置,而F不是
int code_numseen_feed(void)
{
cmdswitchbuf_num=(strtod(Fbuf+1,NULL));
// strcpy(cmdbuffer[readindex],cmdswitchbuf);//F不需要,位置不为固定的
// printf("获取解析指令后的数值f",cmdswitchbuf_num);
return cmdswitchbuf_num;
}
第五个函数为解析函数,整合上述函数
u8 get_command(void)
{
u8 res=0;
u16 t;
if(block_num<BLOCK_BUFFER_SIZE-1)
{
if(!SDPRINT||serial_count!=0)
return error;
while(1)
{
serial_char=zf_read();
cmdbuffer[zindew1][zindew2]=serial_char;
zindew2++;
if(serial_char==0x0a)
{
printf("获得数据为ª:%s,cmdbuffer[%d]=%s\n\r\n\r",cmdbuffer[zindew1],zindew1,cmdbuffer[zindew1]);
zindew1=((zindew1+1)%BUFSIZE);
zindew2=0;
buflen++;
break;
}
}
process_commands();
if(card_eof())
{
printf("finsh print\n\r\n\r");
serial_count=1;
return ok;
}
}
return ok;
}
void process_commands(void)
{
u8 i,q;
buflen = (buflen-1);
if(zindew1==0)
readindex=7;
else
readindex=(zindew1-1);
if((code_cmdseen('G')))//&&(strstr(cmdbuffer[bufindr], "M701") == NULL)&&(strstr(cmdbuffer[bufindw], "M702") == NULL))
{
switch(i=(int)code_numseen())
{
case 0:////只添加了0与1,所以这里只识别G0与G1
{
}
case 1:
{
printf("执行转换\n\r\n\r");
get_coordinates();
return;
}
}
}
else
{
printf("解析失败,读取的数据为%sreadindex=%d\n\r\n\r",cmdbuffer[readindex],readindex);
}
}
void get_coordinates(void)
{
u8 i=0;
if(block_num<BLOCK_BUFFER_SIZE-1)
{
if(code_cmdseen('F'))
{
feedrate=(int)code_numseen_feed();
printf("feedrate = %f\r\n",feedrate);
}
for(i=0;i<=(NUM_AXIS-1);i++)
{
if(code_cmdseen(axis_codes[i]))
{
destination[i] = (float)code_numseen();
printf("destination[%d] = %f\r\n",i,destination[i]);
}
else
{
destination[i]=current_position[i];
}
}
prepare_move();
}
}
void prepare_move(void)
{
u8 i;
plan_buffer_line(destination[X_AXIS], destination[Y_AXIS], destination[Z_AXIS], destination[E_AXIS], feedrate/60, active_extruder);
for(i=0; i < NUM_AXIS; i++)
{
current_position[i] = destination[i];
}
}
plan_buffer_line(const float x, const float y, const float z, const float e, float feed_rate, const uint8_t extruder)
这个函数很复杂,比上面的还要长,下次再更新了
这个函数在下一篇文章更新
我们创建了两个文件,名为:command.c与command.h
command.c文件如下所示
在这里插入代码片