Как вариант - нет контроля возможного переполнения вторичного буфера 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'а непосредственно в бинарнике, смело предположу что константы гонять по сети Вы не будете и осторожно напомню, что при разделении "только символ" легко можете получить случайный разрез при некоторых значениях в данных.
И если разделение "только символ", то почему "остальное" не может следующим пакетом ?далее отсчитать длину и остальное просто не сохранять в буфер?
Вновь выложенный проект если и смогу посмотреть, то позднее (календарь-с)
Последний раз редактировалось Валенок; 06.03.2016 в 12:44.
Конечно читаю Я просто не придумал как оградить буфер от переполнения, поэтому и методом тыка, увидел, что при меньшем времени буфер не успевает завалить данными, и ПЛК не ребутится...
Пошагово отлаживал программу, заметил, что наполнение массива 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