Можно сначала WSTRING перевести в STRING, а потом уже STRING в BYTE.
Вид для печати
Ребят, уменя график XY используется, ему легенду вывести можно нет? не найду такую опцию
Добрый день!
Возник вопрос, возможно ли в визуализацию одного ПЛК210 встроить/отобразить визуализацию другого ПЛК210 находящихся в одной локальной сети ?
Такой опции нет.
Добрый день.
Да, это возможно - с помощью элемента визуализации Web-браузер.
P.S. - вопросы про визуализацию лучше задавать в соответствующей теме:
https://owen.ru/forum/showthread.php?t=22038
Всем здравствуйте, как реализовать такую схему на ST Вложение 56639
Подскажите пожалуйста как найти максимальное значение в массиве?
Вот таким образом будет верно? массивы уменя имеют тип BYTE
реализовал так:Код:OSCAT_BASIC.ARRAY_MAX(pt:=ADR(PLC_PRG.tTrend2), size:= V1max);
OSCAT_BASIC.ARRAY_MAX(pt:=ADR(PLC_PRG.tTrend3), size:= V2max);
OSCAT_BASIC.ARRAY_MAX(pt:=ADR(PLC_PRG.tTrend4), size:= V3max);
OSCAT_BASIC.ARRAY_MAX(pt:=ADR(PLC_PRG.tTrend5), size:= V4max);
Код:FOR I3 := 0 TO 31 BY 1 DO
IF II3<PLC_PRG.tTrend1[I3]
THEN
II3:=PLC_PRG.tTrend1[I3];
END_IF
END_FOR
Мне нужно включение и выключение одной кнопкой, пример брал отсюда https://www.youtube.com/watch?v=TvTOI88ukDE вроде все верно сделал, но увы , не работает
Код:foo := xButton;
IF foo AND NOT bar THEN
OUT := NOT OUT;
END_IF;
bar := foo;
Ребят почему неработает код?
31й там само собой 0, а вот FCONST имеет значение 4
Код:IF NOT Info[31]=Testirovanie.FCONST THEN
FOR I3 := 0 TO 31 BY 1 DO
Info[I3]:=Testirovanie.FCONST;
END_FOR
END_IF
Как переключить визуализацию по переменной?
См. п. 10.3.1 и 10.4.4:
https://ftp.owen.ru/CoDeSys3/11_Docu..._Visu_v2.2.pdf
P.S. - вопросы про визуализацию лучше задавать в соответствующей теме:
https://owen.ru/forum/showthread.php?t=22038
ребят!, проблема нарисовалась, загрузил проект в плк, запускаю, пытаюсь прочитать с базы данных любую запись, не читает, записываю еще одну запись сверху и начинает открывать все, и старые и новые, все до первого перезапуска плк, не пойму где ошибка
Код:fbTrigger(CLK:=xRFile OR xWFile);
LineW:=uiArchEntry-1;
AS1:=StrLenW(ADR(c_sTitle));
// если получен сигнал записи, то взводим соответствующий флаг
IF fbTrigger.Q THEN
xOpenF:=TRUE;
END_IF
CASE eState OF
0: // шаг открытия файла
IF xWFile AND xOpenF //Запись файла
THEN
fbFileOpen(xExecute:=TRUE, sFileName:=sVisuFileName, eFileMode:=FILE.MODE.MAPPD);
// если файл, в который производится запись, не существует, то создадим его и запишем в него заголовок архива
IF fbFileOpen.eError=FILE.ERROR.NOT_EXIST
THEN
fbFileOpen(xExecute:=FALSE);
eState:=1; // шаг создания файла
xTitle := TRUE;
END_IF
// если файл существует и был успешно открыт, то переходим к шагу записи файла
IF fbFileOpen.xDone AND xWFile
THEN
hFile:=fbFileOpen.hFile;
fbFileOpen(xExecute:=FALSE);
eState:=2; // шаг записи в буфер
END_IF
ELSE IF xRFile AND xOpenF //Чтение файла
THEN
fbFileOpen(xExecute:=TRUE, sFileName:=sVisuFileName, eFileMode:=FILE.MODE.MREAD);
// если файл существует и был успешно открыт, то переходим к шагу чтения файла
IF fbFileOpen.xDone AND xRFile
THEN
hFile:=fbFileOpen.hFile;
fbFileOpen(xExecute:=FALSE);
eState:=6; // шаг установки позиции для чтения из файла
END_IF
END_IF
END_IF
1: // шаг создания файла
// в созданном файле еще нет записей
uiArchEntry:=0;
fbFileOpen(xExecute:=TRUE, sFileName:=sVisuFileName, eFileMode:=FILE.MODE.MWRITE);
IF fbFileOpen.xDone THEN
hFile := fbFileOpen.hFile;
fbFileOpen(xExecute:=FALSE);
// после создания файла можно перейти к шагу записи данных
eState:=2;
END_IF
IF fbFileOpen.xError THEN
// обработка ошибок
END_IF
2: // шаг записи в буфер
// если это первая запись в файле - то перед ней запишем заголовок
IF uiArchEntry=0
THEN
// запись строки архива в буфер
fbFileWrite(xExecute:=TRUE, hFile:=hFile, pBuffer:=ADR(c_sTitle), szSize:=StrLenW(ADR(c_sTitle))*2);
ELSE
//Записываемая строка
sArchEntry := WstWst_TO_VLWst.sVeryLongWStr;
// запись строки архива в буфер
fbFileWrite(xExecute:=TRUE, hFile:=hFile, pBuffer:=ADR(sArchEntry), szSize:=(StrLenW(ADR(sArchEntry)))*2); //1978 Байт строка включая символы переноса строки
END_IF
IF fbFileWrite.xDone THEN
fbFileWrite(xExecute:=FALSE);
// после записи число строк в архиве увеличилось на одну
uiArchEntry:=uiArchEntry+1;
// теперь можно перейти к шагу сброса буфера в файл
eState:=3; // шаг сброса буфера в файл
END_IF
IF fbFileWrite.xError THEN
// обработка ошибок
END_IF
3: // шаг сброса буфера в файл
fbFileFlush(xExecute:=TRUE, hFile:=hFile);
IF fbFileFlush.xDone THEN
fbFileFlush(xExecute:=FALSE);
// теперь можно перейти к шагу закрытия файла
eState:=4; // шаг закрытия файла
END_IF
IF fbFileFlush.xError THEN
// обработка ошибок
END_IF
4: // шаг закрытия файла
fbFileClose(xExecute:=TRUE, hFile:=hFile);
IF fbFileClose.xDone THEN
fbFileClose(xExecute:=FALSE);
xOpenF := FALSE;
// теперь можно перейти к шагу определения размера файла
eState:=5; // шаг определения размера файла
END_IF
5: // шаг определения размера файла
fbFileGetSize(xExecute:=TRUE, sFileName:=sVisuFileName);
// определяем размер файла
IF fbFileGetSize.xDone THEN
udiArchSize:=fbFileGetSize.szSize;
fbFileGetSize(xExecute:=FALSE);
// вернемся на шаг открытия файла для ожидания следующего управляющего сигнала
eState:=0; // шаг открытия файла
END_IF
// размер несуществующего файла...
IF fbFileGetSize.eError=FILE.ERROR.NOT_EXIST THEN
// очевидно, можно интерпретировать как ноль
udiArchSize:=0;
fbFileGetSize(xExecute:=FALSE);
// вернемся на шаг открытия файла для ожидания следующего управляющего сигнала
eState:=0;
ELSIF fbFileGetSize.xError THEN
fbFileGetSize(xExecute:=FALSE);
eState:=0; // шаг открытия файла
END_IF
6: // шаг установки позиции для чтения из файла
fbFileSetPos(xExecute:=TRUE, hFile:=hFile, udiPos:=((StrLenW(ADR(sArchEntry)))*2)*SN); //Выбор строки для чтения количество байт на 1 строку умножить на номер строки
IF fbFileSetPos.xDone THEN
fbFileSetPos(xExecute:=FALSE);
// позиция для чтения выбрана, теперь можно перейти к шагу чтения данных
eState :=7;
END_IF
IF fbFileSetPos.xError THEN
// обработка ошибок
END_IF
7: // шаг чтения файла
fbFileRead(xExecute:=TRUE, hFile:=hFile, pBuffer:=ADR(stReadData), szBuffer:=(StrLenW(ADR(sArchEntry)))*2); //Переменная для выгрузки и количество байт без учёта символов переноса строки
IF fbFileRead.xDone THEN
fbFileRead(xExecute:=FALSE);
// теперь можно перейти к шагу закрытия файла
eState :=4;
END_IF
IF fbFileRead.xError THEN
// обработка ошибок
END_IF
END_CASE
Код:// если получен сигнал записи, то взводим соответствующий флаг
IF fbTrigger.Q THEN
xOpenF:=TRUE;
END_IF
Код:...
ELSE IF xRFile AND xOpenF //Чтение файла
THEN
fbFileOpen(xExecute:=TRUE, sFileName:=sVisuFileName, eFileMode:=FILE.MODE.MREAD);
...
я понял, упустил этот момент, но так тоже не работает:
Код:0: // шаг открытия файла
IF xWFile AND xOpenF //Запись файла
THEN
fbFileOpen(xExecute:=TRUE, sFileName:=sVisuFileName, eFileMode:=FILE.MODE.MAPPD);
// если файл, в который производится запись, не существует, то создадим его и запишем в него заголовок архива
IF fbFileOpen.eError=FILE.ERROR.NOT_EXIST
THEN
fbFileOpen(xExecute:=FALSE);
eState:=1; // шаг создания файла
xTitle := TRUE;
END_IF
// если файл существует и был успешно открыт, то переходим к шагу записи файла
IF fbFileOpen.xDone AND xWFile
THEN
hFile:=fbFileOpen.hFile;
fbFileOpen(xExecute:=FALSE);
eState:=2; // шаг записи в буфер
END_IF
END_IF
IF xRFile AND xOpenF //Чтение файла
THEN
fbFileOpen(xExecute:=TRUE, sFileName:=sVisuFileName, eFileMode:=FILE.MODE.MREAD);
// если файл существует и был успешно открыт, то переходим к шагу чтения файла
IF fbFileOpen.xDone AND xRFile
THEN
hFile:=fbFileOpen.hFile;
fbFileOpen(xExecute:=FALSE);
eState:=6; // шаг установки позиции для чтения из файла
END_IF
END_IF
Коллеги, приветствую!!!
К сожалению, не могу пока создавать темы, поэтому пишу здесь.
Подскажите пожалуйста, как работать с таким объектом как "Модуль С-кода"?
Есть ли какой-нибудь букварь на эту тему???
Мне бы очень хотелось все-таки как-то достучаться до файла БД sqlite(архив тренда) средствами CDS.
По ТЗ надо тренды вести и показывать и эти же данные писать на USB накопитель в .csv формате.
Конечно можно все сделать параллельно , что-бы два компонента(Тренд и т.н. OwenArchiver) работали независимо друг от друга, но это как-то архитектурно не кашерно и в какой-то момент начнется рассинхронизация данных.
Я подумал, что может можно попробовать прикрутить С-ную либу для работы с sqlite, сделать к ней интерфейс и поработать с файлом этой БД..!?!
Добрый день.
"Модуль С-кода" не поддерживается нашими контроллерами.
Насчет sqlite - посмотрите пример:
https://youtu.be/4J6WXEwmeco
Я не уверен, что получится работать с файлами, которые создает CODESYS - но можете попробовать.
Ребята, как удалить фаил с ПЛК по срабатыванию переменной?
Коллеги я очень извеняюсь за наглость...но прошу помочь разобраться...
fbTon1(IN :=TRUE, PT := T#5S);//(IN должно становится TRUE после выполнения всего вложеного кода ,НО становится TRUE сразу
fbr_trig(CLK:=fbTon1.Q);
IF fbr_trig.Q THEN
fbTon1(IN :=FALSE);
EnablreadWrite:=TRUE;// отсчитали 5 сек разрешили чтение запись по МОДБУС(пока реализовано только чтение)
END_IF;
IF EnablreadWrite THEN
CASE eState OF
STATE_MB_WR.CHECK:
IF WriteCount = 167 THEN// если прошли все 167 итераций сбрасываем счетчик на ноль ,запрещаем работу по МОДБУС
WriteCount := 0;//но почему то не сбрасывается
EnablreadWrite:=FALSE;
fbTon1(IN :=TRUE);//fbTon1 IN должно становится TRUE только после выполнения 167 интераций ,НО становится TRUE сразу
eState := STATE_MB_WR.CHECK;
END_IF
WriteCount := WriteCount + 1;
eState := STATE_MB_WR.CONNECTING;
STATE_MB_WR.CONNECTING:
fbTon(IN :=TRUE, PT := T#500MS);
fbr_trig1(CLK:=fbTon.Q);
IF fbr_trig1.Q THEN
fbTon(IN :=FALSE);
fbTcpClient
(
xEnable := TRUE ,
tTimeout := T#5S,
sIpAddr := GVL.FancoilControl.IpAdressNom[WriteCount],
uiPort :=502
);
ConnectOk[1]:= fbTcpClient.xActive;
IF fbTcpClient.xActive THEN
fbWriteRequest (xExecute := TRUE);
eState := STATE_MB_WR.WRITE;
ELSIF fbTcpClient.xError THEN
fbTcpClient(xEnable := FALSE);
eState := STATE_MB_WR.CONNECTING;
END_IF
END_IF
STATE_MB_WR.WRITE:
fbWriteRequest
(
xExecute :=TRUE,
tTimeout :=T#1500MS,
usiRetry :=5,
hConnection := fbTcpClient.hConnection,
xIsRtuOverTcpMode :=FALSE,
usiUnitId :=1,
eFuncCode :=OCL.MB_FC.READ_INPUT_REGISTERS,
uiDataAddr:=((GVL.FancoilControl.FanAdr[WriteCount])*32)+15, // Начальный регистр
uiDataCount:=2,// колво регистров в запросе
pData:=ADR (awReadData),
szSize:=SIZEOF (awReadData)
);
ReadError[WriteCount,1]:=awReadData[0];
ReadError[WriteCount,2]:=awReadData[1];
IF fbWriteRequest.xDone OR fbWriteRequest.xError THEN
fbWriteRequest (xExecute := FALSE);
ErrorWr:=fbWriteRequest.eError;
fbTcpClient(xEnable := FALSE);
eState := STATE_MB_WR.CHECK;
END_IF
END_CASE
END_IF
есть кусок кода,который должен раз в пять сек ( пока что для отладки ) производить запись чтение по MODBUS....в итоге ...чтение происходит только после сброса программы ,выполняються все 166 шагов...
таймер fbTon1 начинает считать сразу хотя должен запустится только после 166 интереаций ( пометил в коментах)
Обратите внимание на первую строку вашего фрагмента кода.Цитата:
таймер fbTon1 начинает считать сразу хотя должен запустится только после 166 интереаций ( пометил в коментах)
так ладно...фиг с ним с таймером ,почему не происходит второе выполнения кода после строк IF EnablreadWrite THEN CASE eState OF и почему не срабатывает IF WriteCount = 167 THEN WriteCount := 0; ?