Экспорт массива в CSV в CODESYS

Я принимаю проект с кодом от другого человека. У меня есть ПЛК, который в настоящее время имеет входы от датчиков давления и термопар. Затем он масштабирует эти данные до PSI и температуры в градусах Фаренгейта. Способ настройки данных от каждого из этих датчиков должен быть отформатирован в массив. Таким образом, после масштабирования данных они находятся в массиве, который также находится в списке сетевых переменных программы. Я пытаюсь взять каждое из этих значений из массива, записать значение через определенное время (скажем, 1 запись в секунду для ясности), а затем каждую секунду экспортировать каждую часть данных в файл CSV. Не уверен, куда даже пойти с этим. Это код, с которым я остался, но я чувствую, что он излишне сложен?

//This is the support class for File_Handler
FUNCTION_BLOCK fileWrite
VAR_INPUT
    xWrite : BOOL;
    sData : STRING(200);
    uiLineLength : INT := 200;
    sDirectory : STRING := 'C:\ProgramData\CODESYS\CODESYSHMIWinV3\D5050FE1\PlcLogic\data';
    //sDirectory : STRING := '/home/cds-apps/PlcLogic/data/';
    sFilename : STRING;
END_VAR
VAR_OUTPUT
    BytesWritten : __XWORD;
    BytesWrittenTotal: DWORD;
    xDone: BOOL;
END_VAR
VAR
    hFile_: sysfile.RTS_IEC_HANDLE := sysfile.RTS_INVALID_HANDLE;
    FileWriteResult: sysfile.RTS_IEC_RESULT;
    FileOpenResult: sysfile.RTS_IEC_RESULT;
    state: INT;
    sys_Us_start: SYSTIME;
    sys_Us_end: SYSTIME;
    WriteTimeMS: ULINT;
END_VAR
sFilename := CONCAT(sDirectory, sFilename);
hFile_ := SysFileOpen(szFile:= sFilename, am:= ACCESS_MODE.AM_APPEND_PLUS, pResult:= ADR(FileOpenResult));
SysTimeGetUs(pUsTime:=sys_Us_start );
BytesWritten := SysFileWrite(hFile:= hfile_, pbyBuffer:= ADR(sData), ulSize:= uiLineLength, pResult:= ADR(FileWriteResult));    
BytesWrittenTotal := BytesWrittenTotal + BytesWritten;
SysTimeGetUs(pUsTime:=sys_Us_end );
WriteTimeMS := (sys_Us_end - sys_Us_start)/1000;
SysFileClose(hFile:= hFile_);

Я не уверен, куда идти с этим кодом. Он создает файл CSV, но я хотел создать файл CSV для фрагмента данных каждую секунду? Если у кого-то есть мысли или ресурсы, которые я мог бы проверить, это было бы здорово.


person lt123    schedule 10.06.2020    source источник
comment
Ваш вопрос тогда, как вызывать эту процедуру каждую секунду?   -  person Filippo Boido    schedule 10.06.2020
comment
О, да, я слишком много думал об этом тогда,   -  person lt123    schedule 10.06.2020
comment
Я хотел бы создать ОДИН CSV-файл, но в этом CSV-файле есть точка данных для каждого элемента в массиве в течение определенного периода времени.   -  person lt123    schedule 10.06.2020


Ответы (1)


Базовый пример того, как вызывать эту процедуру каждую секунду, может быть следующим:

1)

Вы создаете FuncBlock, который позаботится о вызове вашего блока логгера. Допустим, вы назвали его LoggerTask.

FUNCTION_BLOCK LoggerTask
VAR_INPUT
     sData : STRING(200);
     sFilename : STRING;
     xExecute : BOOL;
END_VAR

VAR
    fbRepeatTask : TON;
    fbFileWrite : FileWrite;
    uiStep : UINT;
END_VAR

2)

После этого создайте простую цепочку шагов: (Вы, очевидно, можете расширить и настроить ее по своему усмотрению, вы должны добавить обработку ошибок, например, в случае, когда FileWrite не может записать в файл или записывает меньше, чем ожидалось.)

Часть реализации:

fbRepeatTask(PT:=T#1S);
fbFileWrite(sData := sData, sFileName := sFileName);

IF  xExecute 
    AND uiStep = 0
THEN
    uiStep := 10;
ELSIF NOT xExecute 
THEN
    uiStep := 0;
    fbFileWrite.xWrite := FALSE;
    fbRepeatTask.IN := FALSE;
END_IF

CASE uiStep OF

    10:

        fbFileWrite.xWrite := TRUE;
        IF fbFileWrite.xDone
        THEN
            fbFileWrite.xWrite := FALSE;
            uiStep := 20;
        END_IF

    20: 

        fbRepeatTask.IN := TRUE;
        IF fbRepeatTask.Q
        THEN
            fbRepeatTask.IN := FALSE;
            uiStep := 10;
        END_IF

END_CASE

3)

Как видите, этот блок запускается, как только для xExecute установлено значение true. Чтобы сбросить цепочку шагов, установите для xExecute значение false. Просто циклически запускайте этот блок, например, так: fbLoggerTask(xExecute := TRUE); Я не думаю, что вы разместили весь код своего блока FileWrite, потому что xDone не установлен и xWrite нигде не проверяется. Поэтому убедитесь, что для xDone установлено значение true в течение одного цикла после записи строки в файл (если это еще не реализовано).

person Filippo Boido    schedule 10.06.2020
comment
Спасибо за это, опубликованный код был всем для блока fileWrite, который мне дали. - person lt123; 10.06.2020