Данный CODESYS форум содержит архивную копию русской ветви только для чтения.
Для создания сообщений пожалуйста используйте актуальную международную платформу CODESYS Forum.
Close
Где можно более подробно узнать как пользоваться библиотекой SysLibFile. Уж больно скупо описано в документации к библиотеке. Например:
1) непонятно как определить закрылся файл или нет? Где -то проскользнуло, что на самом деле SysFileClose возвращает DWORD, а не BOOL. Но присваиваешь переменной типа DWORD результат этой функции-компилятор ругается.
VA:=enc;
trigger();
IF VA =126 THEN
trigger.CLK:=TRUE;
IF trigger.Q THEN
hf:= SysFileOpen ('k_weight','w');
VAP:=SysFileWrite(hf, ADR(VA), SIZEOF(VA) );
flag:=SysFileClose(hf);
END_IF
ELSE
trigger.CLK:=FALSE;
END_IF
2) функция SysFileDELETE не работает, если переред этим файл не открыть. В документации об этом ни слова. Да и чувство такое, что удаляет только само содержимое, а сам файл.
IF udalit THEN
hf:= SysFileOpen ('k_weight','r');
del:=SysFileDelete ('k_weight');
END_IF ----удаляется дескриптор (вроде так и надо), но del не становится TRUE при этом.
3) функция SysFileRead отрабатывает только при первой инициализации. Т.е. постоянно надо менять имя файла, а не содержимое, только тогда считывает
IF chitat THEN SysFileOpen ('k_weight','r');
r_d:= SysFileRead (hf, ADR(VN), Size );
variab:=VN;
SysFileClose(hf);
END_IF
В общем куча всяких вопросов возникает.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
При работе с файлами лучше использовать принцип state machine, т.е. в 1 цикле программы выполнять только 1 операцию с файлом (пример в аттаче).
По 2 вопросу: SysFileDelete не связана с другими файловыми функциями. Могу предположить, что операционная система ПЛК не даст удалить файл предварительно открытый функцией SysFileOpen. Если есть сомнения, попробуйте вызвать SysFileDelete сразу после старта ПЛК, не вызывая других файловых функций (чтобы не было открытых дескрипторов с предыдущих попыток).
По 3 вопросу: ИМХО проблемы должны уйти при переходе на state machine.
Спасибо. Возникло пару вопросов.
1) ( Initialisieren )
'\disk_mmc\TestDat.bin'; ??? О чём это? Директория файла? Где об этом прочитать?
strMode := 'a'; - ??? почему ' '
2) ADR(Buffer) - указатель на некий Buffer. Этот буфер надо где-то предварительно объявлять или система сама распознает что и зачем?
Спасибо.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
1) прочесть можно в справке по SysFileOpen>Цитата:
SysFileOpen
This function (see Library SysLibFile.lib) of type DWORD serves to open a file, which already exists or which should be created.
The return value is a file number, which will be used in the functions SysFileWrite, SysFileRead, SysFileClose as an input ('File'). In case of an error '0' will be returned resp. (watch out this exception!) '-1' by target CoDeSys SP RTE.
FileName
STRING
File name
Mode
STRING
Access mode:
w write (File will be updated or created newly)
r read (File will only be opened for reading; if the file does not exist, an error will be returned)
rw read and write (File will be updated; if the file does not exist, an error will be returned)
a append (File will be opened like described for 'w', but the written data will be appended at the end of the file)
полный путь к файлу, который открываете
режим 'a' - открытие файла с добавление информации (append); если файла нет, то он будет создан
2) в этом проекте буфер для чтения/записи объявлен глобально```
ОК. Спасибо. Ещё вопрос. Планирую использовать массив из реал.
Buffer : ARRAY[1..4] OF REAL := re,rt,rw,ru; -это коээффициэнты.
Вопрос можно ли их каждый по отдельности записывать/перезаписывать в уже созданном файле не трогая других. Если я правильно понимаю нужно использовать указатель
ADR (ARRAY.3) для переменной с индексом 3, например?
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Постараюсь подробнее. Хочу попробовать различные конфигурационные переменные (коэф. пид-регулятора, данные энкодера, диапазон измерения, длину платформы и т.д). Записать в одном файле. Для меня важно, чтобы оставалась возможность их редактирования при (необходимости) и по отдельности. Но так, чтобы в этом файле перезаписывалась только редактируемая переменная, а не все скопом. А вот считывать их я собираюсь только после каждого включения питания и присваивать их переменным с которыми работает программа процесса. Я знаю про ретайн переменные и что у Овен154 есть батарейка, с помощью которой автоматически происходит запись в файловую систему после пропадания питания (если хватит батареи). Это всё очень просто.Вроде бы это решение проблемы. Но я наслышан про эти аккумуляторы и что-то не охота связываться с ретайн. Хочется чего-то наверняка
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Я у себя делал сохранение уставок объекта в файл, т.е. при включении питания, если есть файл, то уставки загружаются, если нет, то дефолт, при изменении полностью все писал и особо не заморачивался:
Для Avgur:
Пример работы с файлами классный. Спасибо. Но есть три вопроса.
1) Запись работает только в режиме 'w' , в режиме 'a' выдаёт ошибку 100.
2) IF ( dwReturn <> SIZEOF(Buffer[x]) ) THEN необходимо установить знак равенства (=)вместо <>.
3) Так и не ясно , что возвращает xReturn := SysFileClose(dwHandle) в случае ошибки и возвращает ли, что либо ещё кроме FALSE. Мои эксперименты показали, что в случае удачного закрытия файла возвращается FALSE, а не TRUE как в описании, и добиться момента когда произойдёт ошибка мне не удалось...Похоже дело в самой библиотеке.
В общем, всё работает замечательно. Спасибо всем.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Очень рад, что удалось помочь.
1) в примерах тоже могут быть ошибки))
2) и 3) все вопросы по ошибкам и непонятной работе функций из библиотек Sys... лучше задать производителю контроллера. Может быть описанный в справке функционал реализован не в полной мере.
Как вы определяете "удачное" закрытие файла? Если честно, в своих проектах никогда не анализировал результат работы SysFileClose.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Как определил удачно или нет прошло закрытие? Просто попытался прочитать файл сразу после записи и закрытия, предварительно не открывая его функцией SysFileOpen. В расчёте на то. что если он перед этим не закрылся, то должен продолжать оставаться открытым - и у меня не получилось его прочитать. Значит файл закрылся. После того как ввёл функцию открытия прочитать удалось.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Safron писал(а):
Просто попытался прочитать файл сразу после записи и закрытия, предварительно не открывая его функцией SysFileOpen.
Не уловил смысл сего действия...
Обычный вариант работы с файлом: открыли для чтения, считали информацию, закрыли; обработали инфу из файла; при необходимости открыли для записи, записали и закрыли.
Не поленился и скачал ваш проект на сайте Овен. Зачем такой алгоритм работы с файлами в реальном проекте??? Сделайте 2 условия входа в программе: xWrite и xRead. По первому условию только пишем, по второму - только читаем. В программе PLC_PRG оставить только постоянный и безусловный вызов WriteFile, все остальное выкинуть. Дальше в режиме отладки взводить условие xWrite или xRead (или на визуализацию кнопки приделать) и проверять работу.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Если вы имеете в виду проект "энкодер", то от этого варианта давно уже отказался, я за ваш вариант ухватился как за спасительную соломинку..Что касается как я проверял закрывается или нет, то, если ввести четвёртый шаг wStep и удалить выделенную строчку, то считать не получится - значит в третьем шаге файл всё-таки удачно закрылся, а если оставить , то в Buffer2 запишутся значения. В противном случае(если файл не закрылся в третьем шаге) не было бы нужды опять его открывать и всё считалось как обычно.
Возможно я несколько наивно проверил, но другого способа не знаю...
4: (*FileOpen*)strMode:='r';
dwHandle := SysFileOpen(strFileName,strMode);
( Success ??)
IF dwHandle <> 0 THEN
zReturn := SysFileRead(dwHandle,ADR(Buffer2[x]),SIZEOF(Buffer2[x]));
SysFileClose(dwHandle);
xWriteDone := TRUE;
wStep := 0;
ELSE
wStep := 100; ( error without close and out )
END_IF
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Я скачал ваш измененный FileWriteExample.pro и не понял, зачем нужен шаг 4. ОС контроллера может физически не успеть записать информацию в файл и освободить ресурсы для повторного открытия этого же файла через промежуток времени = циклу программы.
Сделайте эту проверку (чтение) по отдельному флагу.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
На основе примера получилось сделать и чтение и запись, и смещение задействовал.
Но не понятно осталось почему если делать это все по циклам программы то выдается ошибка ватчдога, а через конфигуратор задач все нормально.
Кто нибудь может разъяснить?
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Где можно более подробно узнать как пользоваться библиотекой SysLibFile. Уж больно скупо описано в документации к библиотеке. Например:
1) непонятно как определить закрылся файл или нет? Где -то проскользнуло, что на самом деле SysFileClose возвращает DWORD, а не BOOL. Но присваиваешь переменной типа DWORD результат этой функции-компилятор ругается.
VA:=enc;
trigger();
IF VA =126 THEN
trigger.CLK:=TRUE;
IF trigger.Q THEN
hf:= SysFileOpen ('k_weight','w');
VAP:=SysFileWrite(hf, ADR(VA), SIZEOF(VA) );
flag:=SysFileClose(hf);
END_IF
ELSE
trigger.CLK:=FALSE;
END_IF
2) функция SysFileDELETE не работает, если переред этим файл не открыть. В документации об этом ни слова. Да и чувство такое, что удаляет только само содержимое, а сам файл.
IF udalit THEN
hf:= SysFileOpen ('k_weight','r');
del:=SysFileDelete ('k_weight');
END_IF ----удаляется дескриптор (вроде так и надо), но del не становится TRUE при этом.
3) функция SysFileRead отрабатывает только при первой инициализации. Т.е. постоянно надо менять имя файла, а не содержимое, только тогда считывает
IF chitat THEN SysFileOpen ('k_weight','r');
r_d:= SysFileRead (hf, ADR(VN), Size );
variab:=VN;
SysFileClose(hf);
END_IF
В общем куча всяких вопросов возникает.
При работе с файлами лучше использовать принцип state machine, т.е. в 1 цикле программы выполнять только 1 операцию с файлом (пример в аттаче).
По 2 вопросу: SysFileDelete не связана с другими файловыми функциями. Могу предположить, что операционная система ПЛК не даст удалить файл предварительно открытый функцией SysFileOpen. Если есть сомнения, попробуйте вызвать SysFileDelete сразу после старта ПЛК, не вызывая других файловых функций (чтобы не было открытых дескрипторов с предыдущих попыток).
По 3 вопросу: ИМХО проблемы должны уйти при переходе на state machine.
FileWriteExample.rar [6.46 КБ]
Спасибо. Возникло пару вопросов.
1) ( Initialisieren )
'\disk_mmc\TestDat.bin'; ??? О чём это? Директория файла? Где об этом прочитать?
strMode := 'a'; - ??? почему ' '
2) ADR(Buffer) - указатель на некий Buffer. Этот буфер надо где-то предварительно объявлять или система сама распознает что и зачем?
Спасибо.
1) прочесть можно в справке по SysFileOpen>Цитата:
SysFileOpen
This function (see Library SysLibFile.lib) of type DWORD serves to open a file, which already exists or which should be created.
The return value is a file number, which will be used in the functions SysFileWrite, SysFileRead, SysFileClose as an input ('File'). In case of an error '0' will be returned resp. (watch out this exception!) '-1' by target CoDeSys SP RTE.
FileName
STRING
File name
Mode
STRING
Access mode:
w write (File will be updated or created newly)
r read (File will only be opened for reading; if the file does not exist, an error will be returned)
rw read and write (File will be updated; if the file does not exist, an error will be returned)
a append (File will be opened like described for 'w', but the written data will be appended at the end of the file)
полный путь к файлу, который открываете
режим 'a' - открытие файла с добавление информации (append); если файла нет, то он будет создан
2) в этом проекте буфер для чтения/записи объявлен глобально```
VAR_GLOBAL
xWriteDone: BOOL := TRUE;
Buffer : ARRAY[1..20] OF BYTE := 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20;
strFileName : STRING;
strMode: STRING;
END_VAR
```В общем случае, это необязательно. Можно объявить его в своей программе или функц. блоке.
ОК. Спасибо. Ещё вопрос. Планирую использовать массив из реал.
Buffer : ARRAY[1..4] OF REAL := re,rt,rw,ru; -это коээффициэнты.
Вопрос можно ли их каждый по отдельности записывать/перезаписывать в уже созданном файле не трогая других. Если я правильно понимаю нужно использовать указатель
ADR (ARRAY.3) для переменной с индексом 3, например?
Не понял вопроса. Вы в переменную >Цитата:
Buffer : ARRAY[1..4] OF REAL
собираетесь считывать информацию из файла?
Постараюсь подробнее. Хочу попробовать различные конфигурационные переменные (коэф. пид-регулятора, данные энкодера, диапазон измерения, длину платформы и т.д). Записать в одном файле. Для меня важно, чтобы оставалась возможность их редактирования при (необходимости) и по отдельности. Но так, чтобы в этом файле перезаписывалась только редактируемая переменная, а не все скопом. А вот считывать их я собираюсь только после каждого включения питания и присваивать их переменным с которыми работает программа процесса. Я знаю про ретайн переменные и что у Овен154 есть батарейка, с помощью которой автоматически происходит запись в файловую систему после пропадания питания (если хватит батареи). Это всё очень просто.Вроде бы это решение проблемы. Но я наслышан про эти аккумуляторы и что-то не охота связываться с ретайн. Хочется чего-то наверняка
Я у себя делал сохранение уставок объекта в файл, т.е. при включении питания, если есть файл, то уставки загружаются, если нет, то дефолт, при изменении полностью все писал и особо не заморачивался:
Естественно все делал в разных тактах контроллера и пока ОС не вернет значение функции.
Аналогично и сохранение.
Для Avgur:
Пример работы с файлами классный. Спасибо. Но есть три вопроса.
1) Запись работает только в режиме 'w' , в режиме 'a' выдаёт ошибку 100.
2) IF ( dwReturn <> SIZEOF(Buffer[x]) ) THEN необходимо установить знак равенства (=)вместо <>.
3) Так и не ясно , что возвращает xReturn := SysFileClose(dwHandle) в случае ошибки и возвращает ли, что либо ещё кроме FALSE. Мои эксперименты показали, что в случае удачного закрытия файла возвращается FALSE, а не TRUE как в описании, и добиться момента когда произойдёт ошибка мне не удалось...Похоже дело в самой библиотеке.
В общем, всё работает замечательно. Спасибо всем.
Очень рад, что удалось помочь.
1) в примерах тоже могут быть ошибки))
2) и 3) все вопросы по ошибкам и непонятной работе функций из библиотек Sys... лучше задать производителю контроллера. Может быть описанный в справке функционал реализован не в полной мере.
Как вы определяете "удачное" закрытие файла? Если честно, в своих проектах никогда не анализировал результат работы SysFileClose.
Как определил удачно или нет прошло закрытие? Просто попытался прочитать файл сразу после записи и закрытия, предварительно не открывая его функцией SysFileOpen. В расчёте на то. что если он перед этим не закрылся, то должен продолжать оставаться открытым - и у меня не получилось его прочитать. Значит файл закрылся. После того как ввёл функцию открытия прочитать удалось.
Если вы имеете в виду проект "энкодер", то от этого варианта давно уже отказался, я за ваш вариант ухватился как за спасительную соломинку..Что касается как я проверял закрывается или нет, то, если ввести четвёртый шаг wStep и удалить выделенную строчку, то считать не получится - значит в третьем шаге файл всё-таки удачно закрылся, а если оставить , то в Buffer2 запишутся значения. В противном случае(если файл не закрылся в третьем шаге) не было бы нужды опять его открывать и всё считалось как обычно.
Возможно я несколько наивно проверил, но другого способа не знаю...
dwHandle := SysFileOpen(strFileName,strMode);
( Success ??)
IF dwHandle <> 0 THEN
zReturn := SysFileRead(dwHandle,ADR(Buffer2[x]),SIZEOF(Buffer2[x]));
SysFileClose(dwHandle);
xWriteDone := TRUE;
wStep := 0;
ELSE
wStep := 100; ( error without close and out )
END_IF
Я скачал ваш измененный FileWriteExample.pro и не понял, зачем нужен шаг 4. ОС контроллера может физически не успеть записать информацию в файл и освободить ресурсы для повторного открытия этого же файла через промежуток времени = циклу программы.
Сделайте эту проверку (чтение) по отдельному флагу.
А в режиме эмуляции пользоваться этой библиотекой нереально? SysFileOpen возвращает 0.
Нет. Но можно под PLCWinNT (подробнее здесь http://forum-ru.3s-software.com/viewtopic.php?f=1&t=895)
Спасибо, пока помогло
На основе примера получилось сделать и чтение и запись, и смещение задействовал.
Но не понятно осталось почему если делать это все по циклам программы то выдается ошибка ватчдога, а через конфигуратор задач все нормально.
Кто нибудь может разъяснить?