|
|
Регистрация | << Правила форума >> | FAQ | Пользователи | Календарь | Поиск | Сообщения за сегодня | Все разделы прочитаны |
|
Опции темы | Поиск в этой теме | Опции просмотра |
#1
|
|||
|
|||
Небольшая проблема
Вопрос конкретно людям отлично знающим дельфи.
Есть проект, его суть автоматизация поверки компараторов (сверхточных весов) массы. Для общения с компараторами есть библиотека, отлаженная, сто процентов рабочая (проверенная временем в других проектах). Так же, есть эмулятор компаратора. Пред-история: Поверка может проводиться по одной из трех схем измерений, для каждой схемы, свой вид таблицы конечных результатов, так как, ни один компонент типа Grid не удовлетворил моих потребностей, я написал свой, для отображения этих таблиц. Все работало хорошо, компаратор определялся, получал данные взвешивания, никаких проблем не наблюдалось во всей программе, кроме одного но, программа падала при завершении, причиной тому было, неправильная работа, или неправильная связь компонента с датасоурсом, и эту проблему мне так и не удалось решить, тогда я взял код компонента, и вынес его прямо в форму измерений. Проблема соответственно исчезла. Но появилась другая, и не на форме измерений, а в любых точках программы, где устанавливается связь с компаратором, связь устанавливается на ура, но вот возвращает вместо серийного номера и модели - текущий вес. Я ничего не менял в программе, за исключением удаления из проекта ссылок на файл бывшего компонента, и переноса из файла компонента в другой но похожий по логике модуль uComparators. Код:
const CCompUnitType:array [0..3] of string = ('kg','g','mg','mkg'); CUnitType:array [0..3] of string = ('кг','г','мг','мкг'); Все хорошо компилируется, сборку собирал с полной пере-компиляцией на разных машинах, результат один и тот же. В предыдущей версии все норм отрабатывает, в новой нет. При том, эмулятор возвращает правильно серийный номер и модель, а компаратор нет. Для связи с весами, во всех точках программы используется функция: Код:
function TDM.CheckScale(ConnectStr: ansistring; var edSN, edModel: ansistring): integer; var bOk: Boolean; hScales: HWND; nRet: Integer; nAct: DWORD; arBuffer: tBuffer; begin hScales := ScalesCreateInterface(PAnsiChar('Sartorius\Common'), ''); ScalesSetupConnection(hScales, 1, PAnsiChar(ConnectStr)); bOk := True; nRet := ScalesDirectQueryModelName(hScales, 2000, nAct, arBuffer, 64); if RET_SCALES_OK = nRet then edModel := StrPas(arBuffer) else begin edModel := ''; bOk := False; end; if bOk = True then begin nRet := ScalesDirectQuerySerialNumber(hScales, 2000, nAct, arBuffer, 64); if RET_SCALES_OK = nRet then edSN := StrPas(arBuffer) else begin edSN := ''; end; end else begin edSN := ''; end; ScalesReleaseInterface(hScales); CheckScale := nRet; end; Функция получения веса, во всех случаях работает правильно: Код:
function TDM.GetWeight(ConnectStr: ansistring; var arWeight, arUnit: String): integer; var hScales: HWND; nLastQueryWeight: DWORD; nRet: Integer; nAct: DWORD; nWeigthState: DWORD; aFloatWeight: tBuffer; aUnit: tBuffer; bQuery: Boolean; begin inherited; nRet := 0; hScales := ScalesCreateInterface(PAnsiChar('Sartorius\Common'), ''); ScalesSetupConnection(hScales, 1, PAnsiChar(ConnectStr)); ScalesDirectClearBuffers(hScales); nLastQueryWeight := GetTickCount(); bQuery := True; while (nLastQueryWeight + 30000 > GetTickCount()) and (nRet <> RET_SCALES_OK) do begin if bQuery then begin ScalesDirectQueryWeight(hScales, 1); bQuery := False; end; nRet := ScalesDirectWaitWeight(hScales, 50, nAct, aFloatWeight, 64, aUnit, 64, nWeigthState); if RET_SCALES_OK = nRet then begin if WSTATE_STABLE = nWeigthState then begin arWeight:=String(aFloatWeight); arUnit:=String(aUnit); end else begin nRet := 0; bQuery := True; end; end; end; if nRet <> RET_SCALES_OK then begin arWeight:=''; arUnit:=''; end; Result:=nRet; ScalesReleaseInterface(hScales); end; Код:
procedure TSysOptionsFrame.btnScaleEditClick(Sender: TObject); var tmpRec:Integer; COMList:TStringList; i,c:integer; f:boolean; zScaleSerial, ScaleType:AnsiString; aw, au:String; begin if MessageDlg('Внимание, текущие настройки подключений будут переопределены, продолжить?', mtConfirmation, [mbOk, mbCancel], 0) = mrCancel then exit; WaitForm.ShowNow('Поиск компараторов'); _Delay(100); SetEnableds(false); with qryVwComs do begin DM.Comparators.Clear; DisableControls; tmpRec:=RecNo; First; //обновим список компараторов while not Eof do begin DM.Comparators.Update(FieldByName('comparator_id').AsInteger, qryVwComsfactory_number.AsString, '', AnsiString(FieldByName('com_settings').AsString),false, utMg); Next; end; //получим список COM-портов COMList:=DM.GetCOMList; //ищем компараторы по COM-портам if DM.Comparators.Count > 0 then for I := 0 to DM.Comparators.Count - 1 do with DM.Comparators.Comparators[i] do if not Is_active then begin f:=false; c:=0; while (c < COMList.Count) and (not f) do begin DM.CheckScale(DM.GetConnectStr(COMList.Strings[c],String(COM)), zScaleSerial, ScaleType); //здесь получаем правильные данные if zScaleSerial <> '' then if ScaleSerial = zScaleSerial then begin Port:=COMList.Strings[c]; Is_active:=true; if DM.IsDebug then DM.LogAdd('[Поиск компаратора '+ScaleSerial+'] '+DM.GetConnectStr(COMList.Strings[c],String(COM))+' - найден'); COMList.Delete(c); f:=true; if DM.GetWeight(DM.GetConnectStr(String(Port),String(COM)),aw, au) = RET_SCALES_OK then WeightUnit:=TranslateUnitType(au); end; if DM.IsDebug and (not f) then DM.LogAdd('[Поиск компаратора '+ScaleSerial+'] '+DM.GetConnectStr(COMList.Strings[c],String(COM))); inc(c); Application.ProcessMessages; end; end; //обновляем SetEnableds(true); qryVwComs.Refresh; RecNo:=tmpRec; EnableControls; //сохраняем DM.Comparators.SaveToFile(ChangeFileExt(Application.ExeName,'.tcm')); end; COMList.Destroy; WaitForm.Hide; end; Код:
function TTestForm.IsConnect(var ScaleText: String): Integer; var nRet: integer; begin inherited; nRet := DM.CheckScale(AnsiString(ConnectStr), ScaleSerial, ScaleType); if ScaleSerial <> '' then begin nRet := 1; ScaleText := 'Весы подключены.'; end else begin if nRet = RET_SCALES_NO_PORT then ScaleText := 'COM-порт недоступен!' else ScaleText := 'Нет ответа от весов!'; nRet := 0; end; IsConnect := nRet; end; Среда: CODE Gear RAD Studio 2009 Версия: 12.0.3420.21218 Обновления: Update3, Update4 (Database Pack Update) ОС: XP SP3 //так же, компилировал и на Win7 с той же версией дельфи и обновлениями. Скажу честно, уже голову сломал, а причину понять не могу, как две перенесенные строчки кода из одного модуля в другой, могли дать такой резонанс. В понедельник поеду к заказчику, со средой дельфи, подскажите какие либо методики выявления такого рода ошибок, я с отладкой программ на ты, но в данном случае, не понимаю даже в какую сторону копать. Буду признателен любой помощи, будут попутные вопросы задавайте. Уж решения проблемы от вас не жду, но жду хотя бы хороших советов и наставлений. Последний раз редактировалось Asinkrit, 12.03.2011 в 10:15. |
#2
|
||||
|
||||
Увидел вот такую разницу в функциях: в функции получения веса ты очищаешь буферы ScalesDirectClearBuffers(hScales), а в функции получения серийного номера и модели - не очищаешь.
Некоторые программисты настолько ленивы, что сразу пишут рабочий код. Если вас наказали ни за что - радуйтесь: вы ни в чем не виноваты. |
#3
|
|||
|
|||
Честно говоря, на функции получения веса и установки связи я грешить не могу, они взяты из другого отлаженного проекта, я конечно попробую вставить ScalesDirectClearBuffers(hScales) и посмотреть, но здесь явно дело в другом.
|
#4
|
|||
|
|||
Наконец-то напряг мозги, и на разных компараторах протестил программу, оказалось, что только один компаратор давал такой не однозначный вариант, а в итоге, оказалось, что он каждую секунду слал в порт текущий вес.
|