贝加莱PLC。写入后计算新偏移量或如何将数据写入新行
Posted
技术标签:
【中文标题】贝加莱PLC。写入后计算新偏移量或如何将数据写入新行【英文标题】:B&R PLC. Calculate new offset after write or how to write data to new line 【发布时间】:2019-07-17 22:04:25 【问题描述】:我有这个程序可以在 U 盘上创建文件。问题是它只保存一行(重写同一行)。我需要在每个周期后将数据写入新行。我认为它必须与偏移量有关,我需要计算偏移量,因此它不会每次都从 0 开始。这是部分代码
10: DevLink_0.enable := TRUE;
DevLink_0.pDevice := ADR('Disk');
DevLink_0.pParam := ADR(cesta_k_USB);
DevLink_0();
IF DevLink_0.status =0 THEN
step :=20;
END_IF
20: FileCreate_0.enable := TRUE;
FileCreate_0.pDevice := ADR('Disk');
FileCreate_0.pFile := ADR('results.csv');
FileCreate_0();
IF FileCreate_0.status = 0 THEN
identification_file := FileCreate_0.ident;
offset :=0;
step :=30;
END_IF
IF FileCreate_0.status = fiERR_EXIST THEN
step :=25;
END_IF
25: FileOpen_0.enable := TRUE;
FileOpen_0.pDevice := ADR('Disk');
FileOpen_0.pFile := ADR('results.csv');
FileOpen_0.mode := FILE_W;
FileOpen_0();
IF FileOpen_0.status = 0 THEN
identification_file := FileOpen_0.ident;
offset := FileOpen_0.filelen;
step := 30;
END_IF
30: data:=INT_TO_STRING(y);
data:=INSERT(data,'$r$n',LEN(data));
FileWrite_0.enable := TRUE;
FileWrite_0.ident := identification_file;
FileWrite_0.pSrc := ADR(data);
FileWrite_0.len := LEN(data);
FileWrite_0.offset := offset;
FileWrite_0();
IF FileWrite_0.status = 0 THEN
step :=40;
END_IF
40: FileClose_0.enable := TRUE;
FileClose_0.ident := identification_file;
FileClose_0();
IF FileClose_0.status =0 THEN
IF save = FALSE THEN
step :=50;
ELSE
step := 25;
END_IF
END_IF
50: DevUnlink_0.enable := TRUE;
DevUnlink_0.handle := DevLink_0.handle;
DevUnlink_0();
IF DevUnlink_0.status =0 THEN
stav:= 0;
END_IF
【问题讨论】:
您必须读取文件或获取文件大小,或者在单独的变量中记住大小。 【参考方案1】:正如评论中已经提到的,您需要在 FileWrite FUB 中相应地设置偏移量。
我通常使用 AS 帮助中的 FileInfo FUB Guid 6eaf42f0-4ce5-44b7-95cb-275ae1c2fac5 来执行此操作。它会告诉你文件是否已经存在以及它的大小。
如果存在,下一步将是 FileOpen,否则是 FileCreate。
最近我在 GitLab 上创建了一个小项目,除此之外,它还在文件中附加了一行:https://gitlab.com/kirni/bur_robotic_sample/blob/master/bur_robotic_sample/Logical/Libraries/TeachLib/Teach.c
代码是 C 语言,但我相信你明白了。
case stTEACH_INFO:
/*setup fub*/
this->fbInfo.enable = 1;
this->fbInfo.pDevice = (UDINT)inst->szDevice;
this->fbInfo.pName = (UDINT)inst->szFile;
this->fbInfo.pInfo = &this->Info;
//call fub
FileInfo(&this->fbInfo);
//fub is done..
if(this->fbInfo.status != ERR_FUB_BUSY)
//file exists -> open it and append code
if(this->fbInfo.status == ERR_OK)
//start writing to the end of the file
this->Offset = this->Info.size;
//open existing file
this->Step = stTEACH_OPEN;
//file does not exist -> create it and insert code
else if(this->fbInfo.status == fiERR_FILE_NOT_FOUND)
//start writing at the beginning of the file
this->Offset = this->Info.size;
//crete new file
this->Step = stTEACH_CREATE;
//error
else
//set error status and goto error state
inst->Status = this->fbInfo.status;
this->Step = stTEACH_ERROR;
//disable fub
this->fbInfo.enable = 0;
FileInfo(&this->fbInfo);
break;
case stTEACH_CREATE:
/*setup fub*/
this->fbCreate.enable = 1;
this->fbCreate.pDevice = (UDINT)inst->szDevice;
this->fbCreate.pFile = (UDINT)inst->szFile;
//call fub
FileCreate(&this->fbCreate);
//fub is done..
if(this->fbCreate.status != ERR_FUB_BUSY)
//success
if(this->fbCreate.status == ERR_OK)
this->Ident = this->fbCreate.ident;
//open existing file
this->Step = stTEACH_WRITE;
//error
else
//set error status and goto error state
inst->Status = this->fbCreate.status;
this->Step = stTEACH_ERROR;
//disable fub
this->fbCreate.enable = 0;
FileCreate(&this->fbCreate);
break;
case stTEACH_OPEN:
/*setup fub*/
this->fbOpen.enable = 1;
this->fbOpen.pDevice = (UDINT)inst->szDevice;
this->fbOpen.pFile = (UDINT)inst->szFile;
this->fbOpen.mode = fiREAD_WRITE;
//call fub
FileOpen(&this->fbOpen);
//fub is done..
if(this->fbOpen.status != ERR_FUB_BUSY)
//success
if(this->fbOpen.status == ERR_OK)
this->Ident = this->fbOpen.ident;
//open existing file
this->Step = stTEACH_WRITE;
//error
else
//set error status and goto error state
inst->Status = this->fbOpen.status;
this->Step = stTEACH_ERROR;
//disable fub
this->fbOpen.enable = 0;
FileOpen(&this->fbOpen);
break;
case stTEACH_WRITE:
/*setup fub*/
this->fbWrite.enable = 1;
this->fbWrite.ident = this->Ident;
this->fbWrite.offset = this->Offset;
this->fbWrite.pSrc = this->szLine;
this->fbWrite.len = this->Lenght;
//call fub
FileWrite(&this->fbWrite);
//fub is done..
if(this->fbWrite.status != ERR_FUB_BUSY)
//success
if(this->fbWrite.status == ERR_OK)
this->Ident = this->fbWrite.ident;
//Write existing file
this->Step = stTEACH_CLOSE;
//error
else
//set error status and goto error state
inst->Status = this->fbWrite.status;
this->Step = stTEACH_ERROR;
//disable fub
this->fbWrite.enable = 0;
FileWrite(&this->fbWrite);
break;
但是,这也应该与 FileOpen FUB 的 filelen 输出一起使用 - 就像您所做的那样。我建议您在写入之前设置一个刹车点,并检查 FUB 上是否正确设置了偏移量。
我还建议您在完成后调用每个 FUB,再次使用 enable:=0(就像我在示例中所做的那样),即禁用它。一些 FUB 仅在 enable、execute、start 等输入命令的上升沿更新其输入参数。
我希望这会有所帮助!
【讨论】:
以上是关于贝加莱PLC。写入后计算新偏移量或如何将数据写入新行的主要内容,如果未能解决你的问题,请参考以下文章