当前位置: 首页 > article >正文

CODESYS 输出日志 Log

目录

1.库SysFile

2.定义声明

3.日志输出实现


1.库SysFile

2.定义声明

定义文件个数,文件行数限制 以及触发变量,每次触发则写一行数据

FUNCTION_BLOCK LogOutput
VAR_INPUT
	//输入文件个数 默认是5 不超过100个
	iFileNum           : INT := 100;
	//路径以及文件名,不含后缀
	sFileName	       : STRING(255) := 'Info';  
	//文本行数  默认是50000 ,不超过50000个
	NumberTextLines    : INT := 50000;
	//上升沿生效
	bEnable            : BOOL;
	//文件操作//写一行数据
	bWriteLine	       : BOOL := FALSE;
	//最新的输出日志文本行     
	logLineText      : STRING;
END_VAR
VAR_OUTPUT
	//创建一定个数的文件完成标志
   	bCreateFileDone    : BOOL;
	//写当前文件数据完成标志
	bWriteFileDone     : BOOL;
END_VAR
VAR
	sFileFolder       : STRING(255) := 'D:\Logs\'; 
    //文件后缀
	suffix             : STRING(255) := '.log';
    //当前文件名路径
    sFileNameMid	   : STRING(255) := '';  
	//字符串数组库
	asCurrentFileName  : ARRAY[1..100] OF STRING(255) ;  
    abFileSingle	   : ARRAY[1..100] OF BOOL ; 
	//文件操作
	iFilesStatus       : INT;
	iWriteDelay        : INT;
	//当前文件序号
	iCurrentFileNum    : INT := 1;
	//当前文件行
	iCurrentTextline   : INT := 0;
	//计数器
	iCounter           : INT;
	//计算器2
	iCounter2          : INT;
	//当前文件计算
	iCurrentCounterFile: INT := 1;
	//创建文件个数标志位
	//iCreateFileNum     : INT;
	//delete 计算器
	iDeleteCounter     : INT;
	//复位文件返回字节数
	lwCopyWord         : LWORD;
	//时间处理
	sLine			   : STRING(255);
	sTime		       : STRING;
    sTimeT1            : STRING;
	//边沿检测
    EnableR_TRTG       : R_TRIG; 
	WriteFilesR_TRIG   : R_TRIG; 
	//Test
    lrCounterDataTest  : LREAL;
	//判断当前文件延时
    iDelayHasFile      : INT;
	Total_Num: INT;
END_VAR

3.日志输出实现

定义文件操作

{attribute 'qualified_only'}
{attribute 'strict'}
TYPE FilesOpStatus :
(
	InitFile := 0,          //初始化文件
	Hasfiles := 10,         //检查文件是否存在
	CreateFiles   := 20,    //创建文件
	ReadFilesData := 30,    //读取文件数据
	WriteFilesData:= 40,    //写入文件数据
	WriteFileReady:= 50,    //写文件准备状态
    CreateFilesError:= 100  //创建文件失败
);
END_TYPE

日志内容输出,可以自行定义日志输出的样式

字符串拼装的方式

//目录拼接当前日期
sFileFolder:=concat('D:\Logs\',LEFT(GetTimeS(),10));
sFileFolder:=concat(sFileFolder,'\');
//启动信号
EnableR_TRTG(CLK:= bEnable, Q=> );
IF EnableR_TRTG.Q THEN
	iFilesStatus := FilesOpStatus.InitFile;
END_IF

//限制
IF iFileNum > 100 THEN
	iFileNum := 100;
END_IF

IF NumberTextLines > 50000 THEN
	NumberTextLines := 50000;
END_IF

IF NOT(bEnable) THEN
	RETURN;
END_IF

//文件操作状态机
CASE iFilesStatus   OF 
	FilesOpStatus.InitFile: //初始化文件
	bCreateFileDone := FALSE;
	iCurrentCounterFile := 1;
				
	//当前文件标志位复位
	FOR iCounter := 1 TO iFileNum BY 1 DO
		abFileSingle[iCounter] := FALSE;
	END_FOR

    iFilesStatus := FilesOpStatus.Hasfiles;
	FilesOpStatus.Hasfiles:
	//文件都存在的情况下
	IF bCreateFileDone THEN
		//删除最早生产的文件
		DeleteFile(asCurrentFileName[1]);
						
		//依次类推,将最新的往前移
		FOR iDeleteCounter := 1 TO (iFileNum - 1) BY 1 DO
			CopyFile(asCurrentFileName[iDeleteCounter],asCurrentFileName[iDeleteCounter + 1],ADR(lwCopyWord));
			//删除
			DeleteFile(asCurrentFileName[iDeleteCounter + 1]);
		END_FOR
				
		 //最后一个默认是最新的文件
		iCurrentCounterFile := iFileNum;
		//字符串处理---最后一个文件为最新的文件
		//目录拼接 
		asCurrentFileName[iCurrentCounterFile] := concat(sFileFolder, sFileName);
		//文件数拼接
		asCurrentFileName[iCurrentCounterFile] := concat(asCurrentFileName[iCurrentCounterFile], INT_TO_STRING(iCurrentCounterFile));
		//后缀拼接
		asCurrentFileName[iCurrentCounterFile] := concat(asCurrentFileName[iCurrentCounterFile],suffix);
					
		//当前文件
		sFileNameMid := asCurrentFileName[iCurrentCounterFile];
		//下一状态机
		iFilesStatus := FilesOpStatus.CreateFiles;
	ELSE
		//字符串处理---最后一个文件为最新的文件
		//目录拼接 
		asCurrentFileName[iCurrentCounterFile] := concat(sFileFolder, sFileName);
		//文件数拼接
		asCurrentFileName[iCurrentCounterFile] := concat(asCurrentFileName[iCurrentCounterFile], INT_TO_STRING(iCurrentCounterFile));			
		//后缀拼接
		asCurrentFileName[iCurrentCounterFile] := concat(asCurrentFileName[iCurrentCounterFile],suffix);		
		//当前文件
		sFileNameMid := asCurrentFileName[iCurrentCounterFile];
		 //当前文件是否存在
		IF HasFile(asCurrentFileName[iCurrentCounterFile]) THEN
			//文件是否存在标志
			IF NOT(abFileSingle[iCurrentCounterFile]) THEN
				abFileSingle[iCurrentCounterFile] := TRUE;
			END_IF
		END_IF
		//延时判断
		iDelayHasFile := iDelayHasFile + 1;
		IF  iDelayHasFile > 15 THEN
			iDelayHasFile := 0;
			IF (abFileSingle[iCurrentCounterFile]) THEN
				iCurrentCounterFile := iCurrentCounterFile + 1;  
				//创建文件完成
				IF iCurrentCounterFile = (iFileNum + 1)  THEN
					bCreateFileDone := TRUE;
				END_IF
			ELSE
				iFilesStatus := FilesOpStatus.CreateFiles;				
			END_IF
		END_IF
	END_IF
    FilesOpStatus.CreateFiles:    //创建文件,并写入相关标题
	//标题六列名称
	sLine := '开始记录日志$r$n';//尾部加换行符
				 
	//创建文件及标题,已经有文件则覆盖
	WriteFile(sFileName:= sFileNameMid, pbyBuffer:= ADR(sLine), ulSize:= len(sLine), WriteMode:= EWriteMode.eWriteCover);
	            
	//延时等待标题写完成
	iWriteDelay := iWriteDelay + 1;
	IF iWriteDelay > 10 THEN
		iWriteDelay := 0;
		iFilesStatus := FilesOpStatus.ReadFilesData;
	END_IF
	FilesOpStatus.ReadFilesData:  //读取文件数据
	//延时计数
	iFilesStatus := FilesOpStatus.WriteFileReady;
	//获取当前文件的行数
	iCurrentTextline :=  0;
	FilesOpStatus.WriteFilesData: //写入文件数据
	//write data
	//'Date,  Total_Num,  OK_Num,  NG_Num,  ErrorScrewID, ErrorID$r$n' 					 //复位
	//获取时间标题
	sTime := GetTimeS();
					 
	sLine := '[';
	sLine := concat(sLine , sTime);
	sLine := concat(sLine , ']');
	//日志行信息
	sLine := concat(sLine,logLineText);					
	//结束符号
	sLine := concat(sLine , '$r$n');
					 
	//向文件尾部写数据
	WriteFile(sFileName:= sFileNameMid, pbyBuffer:= ADR(sLine), ulSize:= len(sLine), WriteMode:= EWriteMode.eWriteAdd);
					
	iCurrentTextline := iCurrentTextline + 1 ; 
	//文件内容填充完成
	IF iCurrentTextline >= NumberTextLines THEN
		iFilesStatus := FilesOpStatus.Hasfiles;
	ELSE
		iFilesStatus := FilesOpStatus.WriteFileReady;
	END_IF
					 
	//写文件内容完成
	bWriteFileDone := TRUE;
	FilesOpStatus.WriteFileReady:
	WriteFilesR_TRIG(CLK:= bWriteLine, Q=> );
	//启动
	IF  WriteFilesR_TRIG.Q THEN 
		//写文件内容完成
		bWriteFileDone := FALSE;
		iFilesStatus := FilesOpStatus.WriteFilesData;
	END_IF         
	FilesOpStatus.CreateFilesError: //写入文件数据
END_CASE


http://www.kler.cn/a/380936.html

相关文章:

  • 搭建Elastic search群集
  • mysql,数据库数据备份
  • Unity3D仿星露谷物语开发5之角色单例模式
  • 题解 洛谷 Luogu P1135 奇怪的电梯 广度优先搜索 BFS C/C++
  • 初学stm32 --- NVIC中断
  • Linux配置ssh登陆
  • Java如何实现企业微信审批流程
  • 《2024中国城市音乐产业发展指数报告》重磅发布
  • Docker入门系列——镜像原理
  • 【数据分析】如何构建指标体系?
  • Cygwin下载及使用
  • MFC POST和Get
  • VSCode 上那些值得推荐的 CSS 插件
  • AIGC时代LaTeX排版的应用、技巧与未来展望
  • 高校大数据实训平台介绍
  • 学习虚幻C++开发日志——定时器
  • ai翻唱部分步骤
  • 3.5 windows xp ReactOS EiAllocatePool()
  • HarmonyOS 移动应用开发
  • C++学习笔记----10、模块、头文件及各种主题(一)---- 模块(4)
  • MFCC特征与Fbank特征在语音识别中的应用
  • Unity3D PCG地图的使用与优化详解
  • npm入门教程2:npm历史
  • AI 写作(一):开启创作新纪元(1/10)
  • Qt 文件目录操作
  • Linux 进程终止 进程等待