1. Обязательно представиться на русском языке кириллицей (заполнить поле "Имя").
  2. Фиктивные имена мы не приветствуем. Ивановых и Пупкиных здесь уже достаточно.
  3. Не писать свой вопрос в первую попавшуюся тему - вместо этого создать новую тему.
  4. За поиск, предложение и обсуждение пиратского ПО и средств взлома - бан без предупреждения.
  5. Рекламу и частные объявления "куплю/продам/есть халтура" мы не размещаем ни на каких условиях.
  6. Перед тем как что-то написать - читать здесь и здесь, а студентам - обязательно здесь.
  7. Не надо писать в ЛС администраторам свои технические вопросы. Администраторы форума отлично знают как работает форум, а не все-все контроллеры, о которых тут пишут.

Язык ST, расширение string

PLC, прочие контроллеры, промышленные компьютеры, операторские панели
Ответить
Аватара пользователя

Автор темы
irrWN
здесь недавно
здесь недавно
Сообщения: 26
Зарегистрирован: 26 фев 2019, 12:12
Имя: Андрей
Благодарил (а): 5 раз

Язык ST, расширение string

Сообщение irrWN »

Всем доброго времени суток.

Может кто-то подсказать по языку ST, обойти ограничение типа string в 255 символов? Мне просто по интерфейсу приходят данные больше 255 символов и они не вмещаются.

leon78
эксперт
эксперт
Сообщения: 1031
Зарегистрирован: 25 июл 2008, 10:06
Имя: Леонид
Страна: РФ
Благодарил (а): 34 раза
Поблагодарили: 110 раз

Язык ST, расширение string

Сообщение leon78 »

Это зависит от среды программирования, ПЛК, и от того, куда вы хотите "вместить" данные.
Хард - это то, что можно швырнуть об стенку, а софт - это то, что можно лишь обматерить.
Аватара пользователя

vodav
освоился
освоился
Сообщения: 277
Зарегистрирован: 28 авг 2014, 09:30
Имя: Воднев Александр Васильевич
Страна: РФ
город/регион: Томск
Благодарил (а): 22 раза
Поблагодарили: 28 раз

Язык ST, расширение string

Сообщение vodav »

Массив стрингов?
Аватара пользователя

Автор темы
irrWN
здесь недавно
здесь недавно
Сообщения: 26
Зарегистрирован: 26 фев 2019, 12:12
Имя: Андрей
Благодарил (а): 5 раз

Язык ST, расширение string

Сообщение irrWN »

vodav писал(а): 11 дек 2019, 17:34 Это зависит от среды программирования, ПЛК, и от того, куда вы хотите "вместить" данные.
Среда программирования Codesys, данные приходят по RS485 интерфейсу в строку, т.к. данных слишком много, они соответственно не помещаются в строку string 255. Мне собственно не нужны все данные, мне нужны только те данные что в конце. Возможно есть способ инвертировать строку? Что бы считались последние 255 символов что приходят, а не первые 255?
vodav писал(а): 11 дек 2019, 17:34 Массив стрингов?
Я в этом деле очень новичек, можно ссылку на учебник или статью где описано как это делается в языке ST?

Почему я не могу просто использовать ARRAY [0...1000] OF STRING;?

Ryzhij
почётный участник форума
почётный участник форума
Сообщения: 5633
Зарегистрирован: 07 окт 2011, 09:12
Имя: Гаско Вячеслав Эриевич
Страна: Россия
город/регион: Рязань
Благодарил (а): 600 раз
Поблагодарили: 758 раз

Язык ST, расширение string

Сообщение Ryzhij »

irrWN писал(а): 12 дек 2019, 09:11 Почему я не могу просто использовать ARRAY [0...1000] OF STRING;?
Наверное сначала надо объявить элементы массива, потом массив, и только потом использовать всё это дело в теле программы.
При объявлении следует учитывать зарезервированные в IDE слова и правила синтаксиса.

Отправлено спустя 5 минут 17 секунд:
irrWN писал(а): 12 дек 2019, 09:11 Я в этом деле очень новичек, можно ссылку на учебник или статью где описано как это делается в языке ST?
Вот тут есть - https://owen.ru/forum/showthread.php?t=26428
---------------------------------------------------
«У человека в душе дыра размером с Бога, и каждый заполняет её как может.» (Жан-Поль Сартр)
"Ту пустоту, которая остаётся в душе, когда в ней нет Бога, и весь мир не может заполнить." (святитель Николай Сербский)
Аватара пользователя

Автор темы
irrWN
здесь недавно
здесь недавно
Сообщения: 26
Зарегистрирован: 26 фев 2019, 12:12
Имя: Андрей
Благодарил (а): 5 раз

Язык ST, расширение string

Сообщение irrWN »

На самом деле я не правильно думал. Судя по тому что я описал, я хотел обрабатывать и без того уже обрезанную строку. И вообще нужно работать не с ней, а с буфером.В буфере мне приходит полная строка, а потом она обрезается. Не знаю по какому принципу она обрезается и от чего это зависит, потому что каждый раз по разному.

Но суть заключается в том, что нужно обрезать постоянно, а главное на нужном моменте.

Вопрос, как получить полную длину строки (еще не порезанную) из буфера?
Аватара пользователя

Serex
эксперт
эксперт
Сообщения: 2091
Зарегистрирован: 15 авг 2011, 21:36
Имя: Пупков Сергей Викторович
Страна: Россия
город/регион: Москва
Благодарил (а): 135 раз
Поблагодарили: 174 раза

Язык ST, расширение string

Сообщение Serex »

По логике нужно просто читать N (строго заданное число символов) с определенной периодичностью. Должен быть какой-то тригер, который при накоплении в буфере определенного числа символов дает исключение.
Аватара пользователя

Автор темы
irrWN
здесь недавно
здесь недавно
Сообщения: 26
Зарегистрирован: 26 фев 2019, 12:12
Имя: Андрей
Благодарил (а): 5 раз

Язык ST, расширение string

Сообщение irrWN »

Есть идея получше, и попроще.

У меня есть строка, с названием переменной CROS, в неё приходит из буфера вставляется строка целиком. Но так как в буфере находится больше символов чем позволяет вместить string, то строка смещается до тех пор пока в буфере не закончатся символы.

Пока эта строка там крутится, смещается, как вытащить из неё только нужные мне данные?

Скажем условно, мне известен фрагмент данных, он называется kWh. В идеале, перед началом этой строки будет условное обозначение например 1.8.1, оно там точно есть, только я не знаю точно под каким номером оно описано. И тогда было бы идеально сделать FIND 1.8.1 в строке, затем MID на 10 символов, и вообще было бы все прекрасно.

Вопрос:
Как во время смещения строки отловить все совпадения с kWh и считать все что слева от них на 10 символов?
Аватара пользователя

aranea
знаток Eplan
знаток Eplan
Сообщения: 1136
Зарегистрирован: 21 сен 2012, 22:45
Имя: aranea
Благодарил (а): 30 раз
Поблагодарили: 165 раз

Язык ST, расширение string

Сообщение aranea »

раз STRING состоит из CHAR, а CHAR судя по всему нет в кодесисе, но есть BYTE, может тогда использовать масcив BYTE?
каким способом вы читаете данные по RS485 и с какого устройства? протокол какой?
больше 255 символов это вам на один запрос приходит?
Изображение
Аватара пользователя

Автор темы
irrWN
здесь недавно
здесь недавно
Сообщения: 26
Зарегистрирован: 26 фев 2019, 12:12
Имя: Андрей
Благодарил (а): 5 раз

Язык ST, расширение string

Сообщение irrWN »

В моем случае, считывание происходит со счетчика Landis+Gyr, данные читаются по RS485, с помощью библиотеки Serial_Interface_01.lib

Вот так выглядит вся процедура получения данных

Код: Выделить всё

CASE aState OF
10:
		IF i=1 THEN
			STR:='/?******!$0D$0A';
		ELSE
			STR:='/?***********!$0D$0A';
		END_IF
			xOpen:=TRUE;
			xStart:=TRUE;
			aState:=20;
20:
		S_COUNT := LEN(STR);
		RCV := ADR (R_BUF.Data);
		R_STR := LEFT(RCV^, R_BUF.Index);
		aState:=30;
30:
		IF RIGHT(R_STR, 1)='$N' THEN
			Record:='$06$30$35$30$0D$0A';
			xStart:=TRUE;
			aState:=40;
		ELSE
			aState:=20;
		END_IF
40:
		S_COUNT := LEN(STR);
		RCV := ADR (R_BUF.Data);
		 R_STR := RIGHT(RCV^, R_BUF.Index);
		aState:=50;
50:
		IF R_BUF.Index>200 THEN
			R_STR1:=RIGHT(RCV^, R_BUF.Index);
				IF i=1 THEN
					OBIS:=MID(R_STR1,10, 230);
					i:=2;
				ELSE
					OBIS2:=MID(R_STR1,100, 30);
				END_IF
			R_STR1:='';
			R_STR:='';
			aState:=60;
		END_IF
60:
		IF SERIAL.Receive_aktiv=FALSE THEN
			R_BUF.Index := 0;
			aState:=0;
		END_IF
		ELSE
		xOpen:=FALSE;
		xStart:=FALSE;
END_CASE
В ответ приходит вот это, но это только начало строки, мне нужно еще дальше посмотреть что там.
scrn.png
У вас нет необходимых прав для просмотра вложений в этом сообщении.
Аватара пользователя

Автор темы
irrWN
здесь недавно
здесь недавно
Сообщения: 26
Зарегистрирован: 26 фев 2019, 12:12
Имя: Андрей
Благодарил (а): 5 раз

Язык ST, расширение string

Сообщение irrWN »

Долго и нудно я мурыжил все это дело, ничего у меня не получилось. Но появилась другая идея. Поскольку ответ приходит частями, то по сути каждую часть можно записать куда-то в файл а потом оттуда прочитать.

Может кто-то подсказать как можно записывать поступающий ответ в файл?
Аватара пользователя

Serex
эксперт
эксперт
Сообщения: 2091
Зарегистрирован: 15 авг 2011, 21:36
Имя: Пупков Сергей Викторович
Страна: Россия
город/регион: Москва
Благодарил (а): 135 раз
Поблагодарили: 174 раза

Язык ST, расширение string

Сообщение Serex »

Работа с COM-портом почти аналогична работе с файлом - это поток. Работа с файлом - другой поток. В любом случае, если использовать стандартные функции, то надо сначала буфер записать в переменную, в переменную в файл. Так что это не выход.
В чем проблема прочитать N символов из буфера, обработать их, потом еще прочитать? Буфер Com-порта, это как файл тот же. Вычитывать можно сначала, с середины, с конца. Входящие телеграммы всегда пишуться в конец и буфер сдвигается если переполнен. Хотя наверное можно настроить исключения. Но это все с точки зрения API под Windows.
Аватара пользователя

Автор темы
irrWN
здесь недавно
здесь недавно
Сообщения: 26
Зарегистрирован: 26 фев 2019, 12:12
Имя: Андрей
Благодарил (а): 5 раз

Язык ST, расширение string

Сообщение irrWN »

Serex писал(а): 18 дек 2019, 23:03 Работа с COM-портом почти аналогична работе с файлом - это поток. Работа с файлом - другой поток. В любом случае, если использовать стандартные функции, то надо сначала буфер записать в переменную, в переменную в файл. Так что это не выход.
В чем проблема прочитать N символов из буфера, обработать их, потом еще прочитать? Буфер Com-порта, это как файл тот же. Вычитывать можно сначала, с середины, с конца. Входящие телеграммы всегда пишуться в конец и буфер сдвигается если переполнен. Хотя наверное можно настроить исключения. Но это все с точки зрения API под Windows.
Я бы рад так сделать, но я даже примеров реальных на данную тему найти не могу.
Аватара пользователя

vodav
освоился
освоился
Сообщения: 277
Зарегистрирован: 28 авг 2014, 09:30
Имя: Воднев Александр Васильевич
Страна: РФ
город/регион: Томск
Благодарил (а): 22 раза
Поблагодарили: 28 раз

Язык ST, расширение string

Сообщение vodav »

Блин, чем больше пытаюсь вникнуть, тем больше не могу понять Вашу проблему.
У вас есть приемный модуль содержащий внутри себя выходную структуру состоящую из счетчика и строки в 255 байт.
В чем проблема проблема считать из этого буфера 255 байт в одну строку, затем по мере заполнения буфера занести это в следующую строку и т.д.?
В DOC-е кода-нибудь работали? Хорошая была система, многих уму-разуму научила.
Аватара пользователя

Автор темы
irrWN
здесь недавно
здесь недавно
Сообщения: 26
Зарегистрирован: 26 фев 2019, 12:12
Имя: Андрей
Благодарил (а): 5 раз

Язык ST, расширение string

Сообщение irrWN »

vodav писал(а): 19 дек 2019, 16:31 Блин, чем больше пытаюсь вникнуть, тем больше не могу понять Вашу проблему.
У вас есть приемный модуль содержащий внутри себя выходную структуру состоящую из счетчика и строки в 255 байт.
В чем проблема проблема считать из этого буфера 255 байт в одну строку, затем по мере заполнения буфера занести это в следующую строку и т.д.?
У меня не совсем проблема, я не могу понять как это сделать. Я пытался разбивать вывод на строки, но у меня почему-то в каждой строке одно и тоже заносится.
vodav писал(а): 19 дек 2019, 16:31 В DOC-е кода-нибудь работали? Хорошая была система, многих уму-разуму научила.
Я к сожалению с ПЛК и CoDeSyS вообще впервые сталкиваюсь.

Вот как мне подсказали попробовать, но не помогло

Код: Выделить всё

 
 S_COUNT := LEN(STR);
        RCV := ADR (R_BUF.Data);
	MAX_LEN := R_BUF.Index; 
	RCV_M := RCV;			
        R_STR := LEFT(RCV^, R_BUF.Index);
 

 IF R_BUF.Index>200 AND i=1 THEN
			STR1 := '';
			STR2:= '';
			STR3 := '';
			STR4 := '';
			IF MAX_LEN <256 THEN  
				R_STR1:=LEFT(RCV_M^, R_BUF.Index);
				MAX_LEN := MAX_LEN - 255;
			ELSE								
				R_STR1:=LEFT(RCV_M^, 255);	
				MAX_LEN := MAX_LEN - 255;
				RCV_M := RCV_M + 255;
			END_IF
			IF MAX_LEN > 0 THEN
				IF MAX_LEN <256 THEN
					R_STR2:=LEFT(RCV_M^, R_BUF.Index);
					MAX_LEN := MAX_LEN - 255;
				ELSE
					R_STR2:=LEFT(RCV_M^, 255);
					MAX_LEN := MAX_LEN - 255;
					RCV_M := RCV_M + 255;
				END_IF
			END_IF
			IF MAX_LEN > 0 THEN
				IF MAX_LEN <256 THEN
					R_STR3:=LEFT(RCV_M^, R_BUF.Index);
					MAX_LEN := MAX_LEN - 255;
				ELSE
					R_STR3:=LEFT(RCV_M^, 255);
					MAX_LEN := MAX_LEN - 255;
					RCV_M := RCV_M + 255;
				END_IF
			END_IF
			IF MAX_LEN > 0 THEN
				IF MAX_LEN <256 THEN
					R_STR4:=LEFT(RCV_M^, R_BUF.Index);
					MAX_LEN := MAX_LEN - 255;
				ELSE
					R_STR4:=LEFT(RCV_M^, 255);
					MAX_LEN := MAX_LEN - 255;
				END_IF
			END_IF
И не работает =( по другому у меня голова не додумывается
Аватара пользователя

Автор темы
irrWN
здесь недавно
здесь недавно
Сообщения: 26
Зарегистрирован: 26 фев 2019, 12:12
Имя: Андрей
Благодарил (а): 5 раз

Язык ST, расширение string

Сообщение irrWN »

Попробовал поэскпериментировать и сделать массив, что бы все приходящие данные записывались в несколько строчек.
Но когда пытась указать несколько индексов массива, например на той же переменной RCV[0,1,2] , R_STR1[0,1,2] мне выдает ошибку "Слишком много индексом массива". А если оставить только ОДИН индекс то нормально и в первую строчку все пишется.

С чем это связано?
Аватара пользователя

keysansa
эксперт
эксперт
Сообщения: 2333
Зарегистрирован: 20 дек 2018, 04:45
Имя: Сергей
Страна: РБ/РФ
город/регион: РФ Сергиев Посад
Благодарил (а): 1990 раз
Поблагодарили: 176 раз

Язык ST, расширение string

Сообщение keysansa »

Еще раз прочитайте посты Serex, потом загуглите "работа с потоками С"

ЗЫ.Спойлеры. Поток бесконечен. Но Modbus вполне работает
ЗЫЫ. Перед этим прочитать про адресацию массивов.
ЗЫЫЫ. А еще мешать из примеров индексацию массивов с доступом по указателю - совсем дурной тон. Выбирайте одно.
В трансформаторной будке живет трансформаторная собака (с) Прозрачный гонщик.
Аватара пользователя

Автор темы
irrWN
здесь недавно
здесь недавно
Сообщения: 26
Зарегистрирован: 26 фев 2019, 12:12
Имя: Андрей
Благодарил (а): 5 раз

Язык ST, расширение string

Сообщение irrWN »

keysansa писал(а): 24 дек 2019, 21:45 Еще раз прочитайте посты Serex, потом загуглите "работа с потоками С"

ЗЫ.Спойлеры. Поток бесконечен. Но Modbus вполне работает
ЗЫЫ. Перед этим прочитать про адресацию массивов.
ЗЫЫЫ. А еще мешать из примеров индексацию массивов с доступом по указателю - совсем дурной тон. Выбирайте одно.
Судя из того что я нагуглил, получается нужно сделать структуру данных.

Вот единственный пример из интернета что я нашел:

Код: Выделить всё

VAR
    aA: ARRAY [1..2] OF StructureName;
    stMyName1: POINTER TO StructureName;
    stMyName2: POINTER TO StructureName;
    xInit: BOOL;
END_VAR

ACTION actMap
    stMyName1 := ADR(aA[1]);
    stMyName2 := ADR(aA[2]);
END_ACTION

IF NOT xInit THEN
    actMap();
    xInit := TRUE;
END_IF
Ну вот допустим я сделал ее

Код: Выделить всё

TYPE xStreamer :
STRUCT
	xString: ARRAY [0..10] OF STRING(180);
	xStream:BOOL;
	xAdressacia: ARRAY [0..255] OF POINTER TO INT;
END_STRUCT
END_TYPE
Затем в самой нужно объявить тип данных
получается

Код: Выделить всё

R_STR1: ARRAY [1..10] OF xStreamer;
и потом в коде использовать

Код: Выделить всё

R_STR1[1]:=LEFT(RCV^, R_BUF.Index);
Аватара пользователя

vodav
освоился
освоился
Сообщения: 277
Зарегистрирован: 28 авг 2014, 09:30
Имя: Воднев Александр Васильевич
Страна: РФ
город/регион: Томск
Благодарил (а): 22 раза
Поблагодарили: 28 раз

Язык ST, расширение string

Сообщение vodav »

Код: Выделить всё

VAR
	data: ARRAY [0..255,0..255] OF BYTE; //Здесь будет полный ответ порта при появлении флага End
	i: INT; //Счетчик_1
	j:INT; //Счетчик_2
	End: BOOL; //Флаг окончания сеанса чтения
	Max_Num: INT; //Ожидаемая длина ответа
END_VAR

WHILE utRECEIVE.Index>0 AND NOT End DO
	utRECEIVE.Index:=utRECEIVE.Index-1;
	data[j,i]:=utRECEIVE.Data[utRECEIVE.Index];
	IF i<255 THEN
		i:=i+1;
	ELSE
		i:=0;
		IF j<255 THEN
			j:=j+1;
		ELSE
			j:=0;
			End:=TRUE;
		END_IF
	END_IF
	IF Max_Num>255*j+i THEN
		End:=TRUE;
		i:=0;
		j:=0;
	END_IF
END_WHILE
Аватара пользователя

keysansa
эксперт
эксперт
Сообщения: 2333
Зарегистрирован: 20 дек 2018, 04:45
Имя: Сергей
Страна: РБ/РФ
город/регион: РФ Сергиев Посад
Благодарил (а): 1990 раз
Поблагодарили: 176 раз

Язык ST, расширение string

Сообщение keysansa »

irrWN писал(а): 25 дек 2019, 14:50 Судя из того что я нагуглил, получается нужно сделать структуру данных.
Что бы использовать чужой код - в нем надо разобраться, а не лепить его к своему проекту.
vodav, посимвольно - для изучения отлично, но это медленный способ.
Обычно изучают протокол, выясняют максимальную длину управляющей последовательности (УП, команды/ответа), формируем внутренний буфер, размером в 1.5-2 раза больший.
И дальше, если просто:
1. Считываем буфер последовательного порта в наш буфер,
2. Пробегаемся по нашему буферу, ищем начало УП, если нашли, ищем конец УП.
3. Если все нашли, разбираем её, выполняем требуемое, оправляем ответ, очищаем буфер, переходим на 1.
4. Если не нашли начало - сбрасываем буфер, идем на 1
5. Если не нашли конец - очищаем начало нашего буфера и переносим все, начиная с начала УП в начало нашего буфера. Оставшееся место вновь дочитываем из буфера последовательного порта. Идем на 2.

Отправлено спустя 7 минут 9 секунд:
Serex писал(а): 18 дек 2019, 23:03 Работа с COM-портом почти аналогична работе с файлом - это поток. Работа с файлом - другой поток.
Хочу уточнить. Файл отличается только возможностью позиционирования на необходимое смещение от начала. Но обычно, если необходимо часто позиционироваться, лучше использовать отображение файла в память. Это во-первых уменьшает число используемых алгоритмов (с портами работаем как с потоками, с файлами работаем так же как с памятью), во-вторых - используем кэширование файла операционной системой, что увеличивает скорость работы.
В трансформаторной будке живет трансформаторная собака (с) Прозрачный гонщик.
Аватара пользователя

Автор темы
irrWN
здесь недавно
здесь недавно
Сообщения: 26
Зарегистрирован: 26 фев 2019, 12:12
Имя: Андрей
Благодарил (а): 5 раз

Язык ST, расширение string

Сообщение irrWN »

Всех благодарю за ответы, Вы помогли мне сделать то что я хотел. Не так профессионально как хотелось бы но, не в этом суть. Суть в том что я все таки смог сделать запись ответа в массив string.

Выглядит это все очень просто, аж вот так.

Код: Выделить всё

VAR
R_STR: ARRAY [0..15] OF STRING(255);       #сам массив собственно
END_VAR

Код: Выделить всё

RCV := ADR(R_BUF.Data);
	R_STR[j] := LEFT(RCV^, R_BUF.Index);
	IF LEN(R_STR[j])>253 THEN
		j:=j+1;
END_IF
Вот в этом то собственно и вся фишка была. Однако есть одно но. Вверху, в во время считывания, я наблюдаю как постепенно в течении нескольких секунд заполняется массив данными. Однако я заметил одну проблему. Некоторые строчки когда заполнились, стираются и записывается следующая. т.е. получается своеобразный пропуск некоторых данных.

>253 - указал, потому что если указать 255 то массив не работает, в весь массив пишется одна и та же первая строчка либо по 5-7 дублей.

И еще один вопрос.

Код: Выделить всё

IF RIGHT(R_STR[j], 1)='$N' THEN
STR:='$06$31$38$31$0D$0A';
xStart:=TRUE;
RCV := ADR(R_BUF.Data);
R_STR[j] := LEFT(RCV^, R_BUF.Index);
IF LEN(R_STR[j])>253 THEN
j:=j+1;
У меня это получается запрос данных. Код запроса нашел на просторах интернета, он работает но я не до конца его понимаю.


1) IF RIGHT(R_STR[j], 1)='$N' THEN - если я правильно понял, то взять первый символ с конца который начинается на $N
2) STR:='$06$31$38$31$0D$0A'; - это согласно HEX таблице обращение к счетчику таблицу смотрел тут ascii-code.com
3) RCV := ADR(R_BUF.Data); - это строка которая принимает буфер, data из библиотеки
4) R_STR[j] := LEFT(RCV^, R_BUF.Index); - тут я получается заношу в строку данные в массив начиная слева по индексам с указанием данных из Data
5) IF LEN(R_STR[j])>253 THEN - тут я делаю проверку длины строки, если она превышает 253 символа то 6)
6) j:=j+1; - соответственно если строка больше 253 символов то переносим следующие 253 символа дальше и так пока не закончится буфер

Я все верно понял?

Огромная благодарность vodav, по его коду я смог сориентироваться как сделать то что мне нужно было.
Ответить

Вернуться в «Средний уровень автоматизации (управляющий)»