Как вариант - нет контроля возможного переполнения вторичного буфера otvet.
Просто проанализируйте что будет если для comand_type = 0 придет 6,6 и еще раз 6. Без раздумий о том, откуда они возьмутся.
Вид для печати
Как вариант - нет контроля возможного переполнения вторичного буфера otvet.
Просто проанализируйте что будет если для comand_type = 0 придет 6,6 и еще раз 6. Без раздумий о том, откуда они возьмутся.
Буфер otvet чистится каждый раз перед новым запросом...
Подскажите, а как можно контролировать переполнение? или можно просто увеличить буфер otvet до 30 например?Код:FOR i:=0 TO 15 DO
otvet[i]:=0;
END_FOR
Про comand_type = 0 в rejim = 0 ответа нет (стоит заглушка). Когда rejim = 2, то проверяю наличие ответа с длиной принятого ответа = 7. Если да, присваиваю string = good.
Про повторные ответы прибора не понял, прибор же вроде отвечает один раз на запрос. ПЛК прочитав ответ длиной 7, дальше не слушает порт, по идее все остальное улетает мимо... Или я ошибаюсь?
Код-то чего убрали ? Ваши сикреты вряд ли тут кому нужны.
Да пофигу на Ваш rejim. У Вас жесткие условия выхода 7 или 15. Как Вам 18 ? Па буковам - просто проанализируйте что будет еcли придет 6,6 и еще раз 6. В разных циклах. За 600мс много чего может навалится в порт. На другой стороне случайно начихают в порт, ваша прога - в перезагруз.Цитата:
Когда rejim = 2, то проверяю наличие ответа с длиной принятого ответа = 7.
Это
можно вообще выкинуть. Пустая трата времениЦитата:
Буфер otvet чистится каждый раз перед новым запросом...
Методом тыка, заметил, что при уменьшении времени ожидания ответа до 100мс. ПЛК перестал перезагружаться...
Но и правильных ответов на запрос нету...
Подскажите а как можно фильтровать полученный ответ, зная что начало ответа прибора 16#10, 16#FF, 16#90 далее отсчитать длину и остальное просто не сохранять в буфер?
Я не пойму как это сделать... Вернее как правильно это записать...
Структуру чтения ответа брал из примера с сайта Овен.
l откуда считается (длина запроса), т.е. по коду присвоения нет, только в конце в виде очищения приравнивается к нулю? И не пойму, зачем массив otvet заполняется с индексом l+i а не просто i ?Код:buf_otvet: ARRAY [0..7] OF BYTE ;
otvet: ARRAY [0..15] OF BYTE ;
byte_read:DWORD;
l:DWORD:=0;
-----
byte_read:=SysComRead(port_number, ADR(buf_otvet), 8, 0);
IF byte_read>0 THEN
FOR i:=0 TO byte_read-1 DO
otvet[l+i]:=buf_otvet[i];
END_FOR
l:=l+byte_read;
Вы вообще ответы читаете ? За 600мс много чего может навалится в портЦитата:
при уменьшении времени ожидания ответа до 100мс. ПЛК перестал перезагружаться...
Косяки могут быть где угодно у кого угодно. Главное - их увидеть. В том коде - есть потенциальная мина.Цитата:
брал из примера с сайта Овен
К авторам. В данном фрагменте вообще много лишнегоЦитата:
l откуда ... ? И не пойму .. i ?
Сначала надо определится, что является разделением пакетов - символы и/или время ? (таймаут - отдельная песня).Цитата:
а как можно фильтровать полученный ответ, зная что начало ответа прибора 16#10, 16#FF, 16#90 далее отсчитать длину и остальное просто не сохранять в буфер?
Раз Вы копались с получением real'а непосредственно в бинарнике, смело предположу что константы гонять по сети Вы не будете и осторожно напомню, что при разделении "только символ" легко можете получить случайный разрез при некоторых значениях в данных.
И если разделение "только символ", то почему "остальное" не может следующим пакетом ?Цитата:
далее отсчитать длину и остальное просто не сохранять в буфер?
Вновь выложенный проект если и смогу посмотреть, то позднее (календарь-с)
Конечно читаю :) Я просто не придумал как оградить буфер от переполнения, поэтому и методом тыка, увидел, что при меньшем времени буфер не успевает завалить данными, и ПЛК не ребутится...
Пошагово отлаживал программу, заметил, что наполнение массива otvet после каждого запроса выполняется правильно, так же как я вижу через снифер. Совпадает с описанием протокола обмена.
Но когда запускаю без точек останова, то вижу что данные сначала идут верные, а потом идет абракадабра и ребут ПЛК.
Еще для эксперимента, поменял скорость обмена на 9600, и Время ожидания ответа = 300ms; Задержка между запросами=T#1000ms;Код:byte_read:=SysComRead(port_number, ADR(buf_otvet), 7, 0);
FOR i:=0 TO byte_read-1 DO
otvet[l+i]:=buf_otvet[i];
END_FOR
В итоге данные получаю стабильным id прибора (string), а t1 (real) через раз или два верное значение каждого опроса...
Подскажите как можно правильно контролировать начало массива otvet? По протоколу, ответ каждого запроса одинаковы первые 3 байта: 16#10, 16#FF, 16#90