Форум по Delphi программированию

Delphi Sources



Вернуться   Форум по Delphi программированию > Все о Delphi > Разное
Ник
Пароль
Регистрация <<         Правила форума         >> FAQ Пользователи Календарь Поиск Сообщения за сегодня Все разделы прочитаны

Ответ
 
Опции темы Поиск в этой теме Опции просмотра
  #1  
Старый 12.03.2011, 09:57
Asinkrit Asinkrit вне форума
Местный
 
Регистрация: 29.10.2009
Сообщения: 446
Репутация: 271
По умолчанию Небольшая проблема

Вопрос конкретно людям отлично знающим дельфи.

Есть проект, его суть автоматизация поверки компараторов (сверхточных весов) массы.

Для общения с компараторами есть библиотека, отлаженная, сто процентов рабочая (проверенная временем в других проектах).
Так же, есть эмулятор компаратора.

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

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

Я ничего не менял в программе, за исключением удаления из проекта ссылок на файл бывшего компонента, и переноса из файла компонента в другой но похожий по логике модуль uComparators.
Код:
const
  CCompUnitType:array [0..3] of string = ('kg','g','mg','mkg');
  CUnitType:array [0..3] of string = ('кг','г','мг','мкг');
Соответственно, везде в uses заменил имя модуля компонента на uComparators, где его не хватало.

Все хорошо компилируется, сборку собирал с полной пере-компиляцией на разных машинах, результат один и тот же. В предыдущей версии все норм отрабатывает, в новой нет. При том, эмулятор возвращает правильно серийный номер и модель, а компаратор нет.

Для связи с весами, во всех точках программы используется функция:
Код:
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;
На выходе из функции, в переменных edSN, edModel в старой версии имею серийный номер и модель, полученный с компаратора и эмулятора, а вот в новой, с компаратора получаю в обоих переменных текущий вес с компаратора а с эмулятора серийный номер и модель. ConnectStr - строка подключения к весам, на входе в функцию правильная.
Функция получения веса, во всех случаях работает правильно:
Код:
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  
Старый 12.03.2011, 11:12
Аватар для Aristarh Dark
Aristarh Dark Aristarh Dark вне форума
Модератор
 
Регистрация: 07.10.2005
Адрес: Москва
Сообщения: 2,906
Версия Delphi: Delphi XE
Репутация: выкл
По умолчанию

Увидел вот такую разницу в функциях: в функции получения веса ты очищаешь буферы ScalesDirectClearBuffers(hScales), а в функции получения серийного номера и модели - не очищаешь.
__________________
Некоторые программисты настолько ленивы, что сразу пишут рабочий код.

Если вас наказали ни за что - радуйтесь: вы ни в чем не виноваты.
Ответить с цитированием
  #3  
Старый 12.03.2011, 17:39
Asinkrit Asinkrit вне форума
Местный
 
Регистрация: 29.10.2009
Сообщения: 446
Репутация: 271
По умолчанию

Честно говоря, на функции получения веса и установки связи я грешить не могу, они взяты из другого отлаженного проекта, я конечно попробую вставить ScalesDirectClearBuffers(hScales) и посмотреть, но здесь явно дело в другом.
Ответить с цитированием
  #4  
Старый 14.03.2011, 18:00
Asinkrit Asinkrit вне форума
Местный
 
Регистрация: 29.10.2009
Сообщения: 446
Репутация: 271
По умолчанию

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


Delphi Sources

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск
Опции просмотра

Ваши права в разделе
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы не можете редактировать сообщения

BB-коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход


Часовой пояс GMT +3, время: 22:07.


 

Сайт

Форум

FAQ

RSS лента

Прочее

 

Copyright © Форум "Delphi Sources" by BrokenByte Software, 2004-2023

ВКонтакте   Facebook   Twitter