Форум » » Отличие CP3 и MC2E » Ответить

Отличие CP3 и MC2E

kislez2015: Такая ситуация - есть программа, в которой есть всего 1 simpl+ модуль. Он скомпилирован для процессоров 2 и 3 серии Но почему-то на MC2E программа работает корректно, а на CP3 такое ощущение, что работает все кроме simpl+ модуля... В чем может быть дело?

Ответов - 36, стр: 1 2 All

Igor: kislez2015, что за модуль и в чем выражаются "ощущения"?

kislez2015: Igor модуль, который из данных сервера делает фамилии для 24 кнопок, изображающих места. а при нажатии людьми кнопок формирует строку очередности докада. И вот строка очередности на MC2E формируется, а на CP3 - нет... абсолютно одна программа но при этом я моделирую ответы сервера через serial i/o и этот же simpl+ модуль обрабатывает эти строки, вытягивая из них номер места, и фамилию т е не работает этот модуль тоже частично

Igor: kislez2015, это не тот ли модуль который зарождался тут?


kislez2015: Igor частично))) но на деле с сервера идет строка, в которой зашит номер места и фамилия вот из фамилий при нажатии людьми кнопок формируется "строка ожидания" единственное, что я заметил - это то, что если скомпилировать мой модуль для X-gen он выдает 10 ошибок, но не думаю, что это должно влиять - ведь для этих двух процов я компилирую для 2 и 3 серий

Вячеслав: Приложите часть кода по PUSH событию, для формирования строки очередности. Я так понимаю, что только эта чать не работает. Подозреваю, нужен просто корректный конвертор русских букв. С латинскими названиями можете попробовать? В дебагере строку очередности можете вывести (в смысле она пустая или нет) Вообще конвертор русских букв используете?

kislez2015: Вячеслав конвертер русских букв вообще не использую... все тестирую на английском вот кусок что отвечает за формирование 2 списков при нажатии желающими на кнопку (первый - максимум 5 фамилий для вывода, и второй - все фамилии во внутренней памяти) не уверен, что тут реально разобраться)) CHANGE Report { INTEGER pos, sit, L, num_rep, pn; STRING NewDelegate[50], NumberString[2], HexNumber[1], removebuf[1200]; STRING NewDelegateWithNumber[51]; // we make the list when somebody push the button IF (mid(Report, 1, 19)="report delegatename" && DelegateCommandShot=1) { NewDelegate=mid(Report, 22, len(Report)-22); sit=byte(Report,21)-64; NumberString=itoa(sit)+"\x0D"; print("Delegate nawat %d", DelegatePressed[sit]); print(" NumberString %s", NumberString); IF (DelegatePressed[sit]=1) { NumberInList=NumberInList+1; print("Chislo v Ocheredi %d", NumberInList); IF (NumberInList<=5) { SubListAfter=SubListBefore+NewDelegate+"\x0D"; DelagateList=SubListAfter; SubListBefore=SubListAfter; SubListAfter2=SubListAfter; SubListBefore2=SubListBefore; } ELSE { SubListAfter2=SubListBefore2+NewDelegate+"\x0D"; SubListBefore2=SubListAfter2; } NumberList=NumberList+NumberString; print(" Spisok cifr %s", NumberList); } ELSE IF (DelegatePressed[sit]=0) { NumberInList=NumberInList-1; print("Chislo v Ocheredi%d", NumberInList); IF (NumberInList<5) { L=len(NewDelegate); pos=find(NewDelegate,SubListBefore,1); SubListAfter=Left(SubListBefore,pos-1); removebuf=RemoveByLength(pos+L,SubListBefore); SubListAfter=SubListAfter+SubListBefore; DelagateList=SubListAfter; SubListBefore=SubListAfter; SubListAfter2=SubListAfter; SubListBefore2=SubListBefore; } ELSE { pos=find(NewDelegate,SubListBefore2,1); L=len(NewDelegate); SubListAfter2=Left(SubListBefore2,pos+L); pos=0; num_rep=0; while (find("\x0D",SubListAfter2,pos+1)>0) { pos=find("\x0D",SubListAfter2,pos+1); num_rep=num_rep+1; } pos=find(NewDelegate,SubListBefore2,1); SubListAfter2=Left(SubListBefore2,pos-1); removebuf=RemoveByLength(pos+L,SubListBefore2); SubListAfter2=SubListAfter2+SubListBefore2; SubListBefore2=SubListAfter2; IF (num_rep<=5) { pos=0; num_rep=0; while (num_rep<5) { pos=find("\x0D",SubListAfter2,pos+1); num_rep=num_rep+1; } SubListAfter=Left(SubListAfter2,pos); DelagateList=SubListAfter; SubListBefore=SubListAfter; } } pn=find(NumberString,NumberList,1); NumberList2=Left(NumberList,pn-1); removebuf=RemoveByLength(pn+1,NumberList); NumberList2=NumberList2+NumberList; NumberList=NumberList2; print(" Spisok cifr %s", NumberList); } }

Вячеслав: Начну с частностей (которые по идее не зависят от серии контроллера, но только по идее см. ниже) Мне кажется ошибочным часть кода: while (num_rep<5) { pos=find("\x0D",SubListAfter2,pos+1); num_rep=num_rep+1; } SubListAfter=Left(SubListAfter2,pos); Вне зависимости от результатов функции find, данный цикл выполнится 5 раз (num_rep= 0 1 2 3 4) Если в строке SubListAfter2 окажется менее 5 блоков оканчивающихся на "\x0D", то значение переменной POS после цикла будет равно 0. А следовательно результат SubListAfter=Left(SubListAfter2,pos) обнулит строку SubListAfter. Если это не задумка программиста при которой нужно очищать строку SubListAfter при количестве записей менее 5, то налицо ошибка приводящая к потере данных. Учитывая код вашего блока можно предположить что сохранение значения глобальной переменной SubListAfter2 к концу блока не важно, то всю конструкцию: IF (num_rep<=5) { pos=0; num_rep=0; while (num_rep<5) { pos=find("\x0D",SubListAfter2,pos+1); num_rep=num_rep+1; } SubListAfter=Left(SubListAfter2,pos); можно заменить одной единственной строкой (которая не потеряет данные и оптимизирует код): SubListAfter=Remove("\x0D",SubListAfter2); По поводу частичной работоспособности при эмуляции ответов сервера могу предположить, либо не достаточное количество эмулированных ответов (ошибка может появится не сразу) или тем что ответ сервера отличается от вашей эмуляции, а именно ответ представляет собой не полную строку. Исходя из вашего кода смею предположить, что переменная Report имеет у вас тип String_input, а такие вещи правильнее реализовывать через тип Buffer_input. В буфере можно собирать куски строк, а не терять их части при событии CHANGE. Теперь об особенностях 3 серии: Количество одновременных циклов while в 3 серии ограничено 8 (правда проверялось внутри одного SIMPL+ модуля, но скорее всего справедливо для всей программы) Таким образом при превышении числа 8 одновременно запущенных циклов while, тело следующих игнорируется со всеми вытекающими. Проверить просто, добавьте отладочную информацию для дебагера с помощью Print или Trace (бывает работает только одна из них - это тоже "особенности" уже любой серии) до цикла и в его теле. Пример: Trace("\nPoint1"); while (num_rep<5) { Trace("\nPoint2 num_rep=%u",num_rep); pos=find("\x0D",SubListAfter2,pos+1); num_rep=num_rep+1; } Если в дебагере вы увидите пару подряд идущих Point1 Point1 не разделенных Point2, то факт невыполнения тела цикла налицо. Оптимизируйте программу с целью уменьшения циклов while (например как я предложил выше) и попробуйте отказаться от бесконечных циклов while например на polling входах некоторых модулей. Ну и на закуску: В вашем куске кода не бьется количество скобок } не говоря уж про неиспользованные и объявленные переменные. Либо часть кода удалена, либо скопировали без последней скобки. Удачи!

kislez2015: Вячеслав пока не могу проверить, спасибо но циклы while пока единственное на что можно спихнуть вину за неработоспособность?

Вячеслав: Почему же единственное, а предполагаемая ошибка о которой я писал точно не ошибка? Тем более могут быть и другие в таком длинном коде, чем вдаваться в разборку проще начать отлаживать по контрольным точкам, состояние нужной переменной. Только представьте что может произойти, когда тело события CHANGE Report еще обрабатывается, а пришел еще один ответ от сервера. Хорошо, если второй процесс будет поставлен в очередь ( а это не так) а так они оба будут пытаться изменить общие для них глобальные переменные в одно и тоже время по своему усмотрению. Впрочем в 3 серии за счет скорости вероятность этого явления скорее будет уменьшаться, чем увеличиваться поэтому этот вариант скорее на заметку. Если при эмуляции ответов сервера, все правильно работает, то смотрите в сторону buffer_input. Опять таки дебагер вам в помощь. Ведь там видно строка от сервера как приходит на одной строчке или иногда на 2 распадается и т.п.

kislez2015: Вячеслав но почему он на MC2E работает без проблем? мне интересно именно какое различие этих процессоров может быть причиной? а про первый пункт - завтра попробую

Вячеслав: Я затрудняюсь сказать как обрабатывается прием команд в COM порт у процессора. Другими словами в какой момент, процессор принимает решение, что пора данные из буфера передать программе управления. Может 3 серия, решает это делать раньше чем вторая и строка приходит частями. Ваш код к этому не готов.

kislez2015: Не знаю поможет ли... но то что я кинул на самом деле не IF а Esle if. А накинается кодом вверху, но эту часть он отрабатывает нормально (всего там 24 таких повротения). И я тестируюсь не на сервере, а засчет Serial IO который дает имена 8ми и 24 людей CHANGE Report { INTEGER pos, sit, L, num_rep, pn; STRING NewDelegate[50], NumberString[2], HexNumber[1], removebuf[1200]; STRING NewDelegateWithNumber[51]; // we must to act when filling places with data IF (mid(Report, 1, 19)="report delegatename" && BusyStart=1) { HexNumber=mid(Report, 21, 1); IF (CompareStringsNoCase(HexNumber, "\x41")=0) { Seat_Number[1]="1"; Delegatename[1]=mid(Report, 22, len(Report)-22); } ELSE IF (CompareStringsNoCase(HexNumber, "\x42")=0) { Seat_Number[2]="2"; Delegatename[2]=mid(Report, 22, len(Report)-22); } ELSE IF (CompareStringsNoCase(HexNumber, "\x43")=0) { Seat_Number[3]="3"; Delegatename[3]=mid(Report, 22, len(Report)-22); } ELSE IF (CompareStringsNoCase(HexNumber, "\x44")=0) { Seat_Number[4]="4"; Delegatename[4]=mid(Report, 22, len(Report)-22); } ELSE IF (CompareStringsNoCase(HexNumber, "\x45")=0) { Seat_Number[5]="5"; Delegatename[5]=mid(Report, 22, len(Report)-22); } ELSE IF

Вячеслав: Кучу вложенных друг в друга If мне тоже не по душе, может и компилятору тоже 0)) Используйте конструкцию Switch(HexNumber) {case(0x41):{} case(0x42):{} и т.п.} Будет более наглядно и компактно. Serial i/o созданный для имитации ответов сервера у вас заведен на вход Report модуля? Если только с него присылать статусы все работает?

kislez2015: нет, просто тестирую этим На одном работает, на другом нет

kislez2015: Вячеслав а можно еще вопрос, есть конструкция такого типа в симпл+ edit_bluray_in_bedroom=edit_bluray_in_bedroom_p1; edit_top_box_in_bedroom=edit_top_box_in_bedroom_p1; edit_wdtv_in_bedroom=edit_wdtv_in_bedroom_p1; edit_blank_in_bedroom=edit_blank_in_bedroom_p1; edit_bluray_in_lr=edit_bluray_in_lr_p1; edit_top_box_in_lr=edit_top_box_in_lr_p1; edit_wdtv_in_lr=edit_wdtv_in_lr_p1; edit_blank_in_lr=edit_blank_in_lr_p1; как заставить каждый из этих сигналов быть малой длительности, пока они непрерывные никак не получается коммутацию сделать вроде бы пускаю через буфер, ставлю на enable вход сигнал длительность 1t, НО НЕТ - он все равно держится 233 мс. почему так происходит?

Вячеслав: Если речь про digital сигналы у него всего 2 состояния 1 и 0. Пока он не переходит в другое состояние, предыдущее можно назвать бесконечным. )) Для того чтобы послать импульс на digital_output выход SIMPL+ модуля используется функция pulse(1,edit_bluray_in_bedroom); В результате выход с именем edit_bluray_in_bedroom будет иметь значение 1 на протяжении 0,01с, потом вернется в значение 0. Может у Вас процессор перегружен неправильными кодами (бесконечными циклами), вот и тайминги ползут. Посмотрите в тулбоксе через командную строку загрузку процессора, при этом желательно дебагер не закрывать, так как он тоже серьезно грузит процессор. Загрузка процессора отображается по команде TOP В PRO3 можно загрузку посмотреть прямо на дисплее процессора

kislez2015: Вячеслав но мне же сначала нужно до pulse(1,edit_bluray_in_bedroom) понять нужно ли этому сигналу вообще присваивать единичное значение. в том и проблема...

Вячеслав: Тогда так: if (edit_bluray_in_bedroom_p1=1){pulse(1,edit_bluray_in_bedroom);} Это основываясь на вашем куске кода, предполагая что переменная edit_bluray_in_bedroom_p1 определяет нужно ли сигналу присваивать (теперь на время) единичное значение. Имейте ввиду, что если выходу dit_bluray_in_bedroom до этого места уже жестко установили единичное значение (присвоив =1), pulse уже не вернет его с 0.

kislez2015: Вячеслав спасибо а еще вопрос про оптимизацию кода в симпл+ если у меня мой симпл+ модуль сохраняет пресеты матричного коммутатора - 4 выхода 5 входов, выходит 20 значений Если у меня в программе предполагается 4 пресета - выходит в памяти надо хранить 80 значений, чтобы по запросы присваивать их на 20 выходов. Это же как я понимаю никак не оптимизировать? у меня весь модуль состоит в присваивании пресетов значениям фидбеков а потом по запросу вывод их...

Вячеслав: Не совсем понял идею, но по мне так при 4 выходах и 5 входах, возможных комбинаций будет не 20, а 45=1024 С количеством пресетов скорее всего придется определиться заранее. Пусть их будет 20 и пусть они будут пользовательскими (сохраняемыми). Чтоб сохранить 1 пресет нужен массив переменных например nonvolatile integer in_for_out[4] где элемент in_for_out[1] содержит значение номера входа, который был скоммутирован на выход с номером 1. элемент in_for_out[2] содержит значение номера входа, который был скоммутирован на выход с номером 2. и т.д. Следовательно чтобы сохранить 20 пользовательских пресетов в энергонезависимой памяти (для любых комбинаций вход-выход) нужно 20 таких массивов: nonvolatile integer in_for_out[20][4] Т.е. суть оптимизации это использование массива переменных. Это наглядно, компактно и удобно для управления. Для сохранения пресета в таком массиве, желательно чтоб выход с модуля управлением матричным коммутатором имел аналоговые выходы для каждого номера выхода коммутатора, какой номер входа на него скоммутирован. Хороший пример в этом смысле Crestron DigitalMedia матрицы. Часто матричные коммутаторы имеют встроенную функцию сохранения текущей конфигурации вход-выход (Extron, RGB Spectrum). И в этом случае можно просто управлять сохранением и загрузкой этих пресетов посылая команду на матричный коммутатор с номером пресета (SAVE или LOAD)



полная версия страницы