|
|
|
|
Проблемка с LTR212
Используем: крейт с 2 модулями LTR212, режим – 1, диапазон - +/-20мВ/В, 4 канала на 1 модуле, 4 канала на 2 модуле.
Определили и запустили крейт и два 212 модуля. Запустили сбор данных и сразу после выполнения функции LTR212_Recv структура LTR212 обнуляется.
Функция LTR212_ProcessData выдает код ошибки = 63533.
Вариант 2: 3 канала на 1 модуле, 3 канала на 2 модуле.
Определили и запустили крейт и два 212 модуля. Запустили сбор данных, получили коды, усреднили их – заполнили свой массив Massiv и количество датчиков Kol_Dat= кол-ву датчиков 1ого модуля. В цикле переходим ко второму модулю. Сразу после выполнения функции LTR212_Recv массив Massiv и Kol_Dat обнулилось (самопроизвольно). Следовательно потеряны данные с первого модуля.
Massiv=(1 канал 1 модуля, 2 канал 1 модуля, 3 канал 1 модуля, 1 канал 2 модуля, 2 канал 2 модуля, 3 канал 2 модуля). : array [0..19] ofreal
Kol_Dat1= Kol_Dat1 : byte
Kol_Dat2= Kol_Dat1+ Kol_Dat2: byte
Что это может быть?
|
|
|
|
|
Re: Проблемка с LTR212
Код модуля-потока сбора данных с LTR212:
unit LTR212OprosUnit;
interface
uses
Classes, windows, Forms, SysUtils,
ltr212api,
SYNCOBJS;
const
POINTS_PER_CHANNEL=10;
schet=11;
type
LTR212_Opros = class(TThread)
private
{ Private declarations }
protected
procedure Execute; override;
end;
var
SIZZE : integer;
DataCntr, fmn : word;
data : array [0..79] of cardinal;
code : array [0..39] of real;
Time : array [0..8] of cardinal;
Massiv : array [0..19] of real;
p : byte;
Kol_Dat : byte;
implementation
usesIsxDanUnit, LTRUnit;
{ LTR212_Opros }
procedure LTR212_Opros.Execute;
var
min,max : real;
m,j,k,i,n : byte;
begin
for j:= 0 to 2*POINTS_PER_CHANNEL*NCH[p+1] do
data[j]:=0;
for k:=0 to POINTS_PER_CHANNEL*NCH[p+1] do
code[k]:=0;
for p:=1 to Activ_212 do
if IsxDanForm.CheckListBox1.Checked[4*(p-1)] or IsxDanForm.CheckListBox1.Checked[4*(p-1)+1] or IsxDanForm.CheckListBox1.Checked[4*(p-1)+2] or IsxDanForm.CheckListBox1.Checked[4*(p-1)+3] then
begin
err:=LTR212_Start(@LTR212[p]);
if err<>0 then
begin
G:=LTRForm.ErrorString(err);
Application.MessageBox(PChar(G),//'Ошибкапристартесбораданных.//',mb_OK);
exit;
end;
end;
whileFlag_DO_MESUREdo //крутим, поканесниметсяфлагизмерений
begin
Kol_Dat:=0;
FOR n:=1 to Activ_212 do
BEGIN
if IsxDanForm.CheckListBox1.Checked[4*(n-1)] or IsxDanForm.CheckListBox1.Checked[4*(n-1)+1] or IsxDanForm.CheckListBox1.Checked[4*(n-1)+2] or IsxDanForm.CheckListBox1.Checked[4*(n-1)+3] then
begin
//Прием данных, перерасчет размера
SIZZE:=2*POINTS_PER_CHANNEL*NCH[n];
DataCntr:=LTR212_Recv(@LTR212[n],@data[0],@Time,SIZZE,10000);
ifDataCntr<>SIZZE then
begin
fmn:=LTR212_GetErrorString(DataCntr);
Application.MessageBox(PChar(fmn),//'Ошибкаприполученииданных.//',mb_OK);
Flag_DO_MESURE:=false;
exit;
end;
//Обрабатываем полученные данные
err:=LTR212_ProcessData(@LTR212[n],@data[0],@code[0],@SIZZE,false);
if err<>0 then
begin
G:=LTRForm.ErrorString(err);
Application.MessageBox(PChar(G+IntToStr(n)),//'Ошибкаприобработкеданных.//',mb_OK);
Flag_DO_MESURE:=false;
exit;
end;
for j:= 0 to NCH[n]-1 do
begin
min:=0;
for k:= 0 to POINTS_PER_CHANNEL-1 do //среднеепоодномуканалу
begin
min:=min+code[j+NCH[n]*k];
end;
min:=min/POINTS_PER_CHANNEL;
Massiv[j+Kol_Dat]:=min;
end;
Kol_Dat:=Kol_Dat+NCH[n];
ifflag_Section then
begin
for j:= Kol_Dat-NCH[n] to Kol_Dat-1 do
begin
section.Enter;
MassivCode[j]:=round(Massiv[j]/256); //создаем один массив для всех датчиков
section.Leave;
end;
end;
end;
END;
end;
//Остановка измерений
for p:= 1 to Activ_212 do
if IsxDanForm.CheckListBox1.Checked[4*(p-1)] or IsxDanForm.CheckListBox1.Checked[4*(p-1)+1] or IsxDanForm.CheckListBox1.Checked[4*(p-1)+2] or IsxDanForm.CheckListBox1.Checked[4*(p-1)+3] then
begin
err:=LTR212_Stop(@LTR212[p]);
if err<>0 then
begin
G:=LTRForm.ErrorString(err);
Application.MessageBox(PChar(G),//'Ошибкаприостановкесбораданных.//',mb_OK);
exit;
end;
end;
end;
end.
|
|
|
|
|
Re: Проблемка с LTR212
Попробуем разобраться по порядку.
Убедитесь, что по-умолчанию в среде стоит выравнивание данных на 4, а не на 8, как это обычно бывает в Delphi. Знаете, где это менять? После изменения выравнивания полностью пересобирите проект с новыми установками. Если это не поможет, то попробуйте повторить эту ошибку без использования многопоточности. Функции наших библиотек являются реентерабельными, но не потокобезопасными, поэтому следить за вызовом функций необходимо программисту.
Самопроизвольное обнуление и другие чудеса спокойно могут быть связаны с тем же выравниванием. Это частые грабли, на них программисты Delphi очень часто наступают, когда работают с нашими библиотеками (можете поискать по форуму).
|
|
|
|
|
Re: Проблемка с LTR212
ясно....а что это за выравнивание??и где его смотреть?менять?
|
|
|
|
|
Re: Проблемка с LTR212
Меню Project->Options..., вкладка Compiler, выпадающий список Record field alignment, установите 4
Не забудьте пересобрать проект с изменениями: меню Project->Build %ProjectName%
http://en.wikipedia.org/wiki/Data_structure_alignment
|
|
|
|
|
Re: Проблемка с LTR212
да, спасибо, с этим разобрались,но толку ни какого....ни чего не изменилось...
Многопоточность убрала, на 3 каналах и более(как раньше впрочем) вся структура LTR212 сбрасывается.
А что вы подразумеваете под "следить за вызовом функций"?? В варианте одномодульной программы ни чего подобного не наблюдается???
и еще вопрос появился, почему может обнуляться счетчик n, который отвечаем за нумерацию модулей??
|
|
|
|
- Сотрудник "Л Кард"
- Здесь с 18.04.2014
- Сообщений: 810
|
Re: Проблемка с LTR212
Память затираете.
LTR212_Recv(@LTR212[n],@data[0],@Time,SIZZE,10000);
data : array [0..79] of cardinal;
Time : array [0..8] of cardinal;
const POINTS_PER_CHANNEL=10;
SIZZE:=2*POINTS_PER_CHANNEL*NCH[n];
Во-первых, массив Time должен быть равен по размеру data (или быть nil). Во-вторых, если исправить Time на [0..79], то NCH[n] должно быть не больше 80/(2*POINTS_PER_CHANNEL) = 4.
Рекомендую проверять это поближе к вызову функции, например:
if (SIZZE > Length(data)) or ((Time <> nil) and (SIZZE > Length(Time))) then begin
Application.MessageBox("Монета-то, монета-то фальшивая!", "Так не пойдет!", MB_OK);
Exit;
end;
DataCntr:=LTR212_Recv(@LTR212[n],@data[0],@Time,SIZZE,10000)
|
|
|
|
- Сотрудник "Л Кард"
- Здесь с 18.04.2014
- Сообщений: 810
|
Re: Проблемка с LTR212
Секундные метки ставятся на каждый отсчет - это просто счетчик, по моменту смены значения которого можно позиционировать разные данные во времени с точностью до одного отсчета (time[i+1] > time[i], значит, секундомер щелкнул где-то между data[i] и data[i+1]).
Если не нужны метки времени, передайте функции Recv nil вместо этого массива и забудьте про него.
|
|
|
|
|
Re: Проблемка с LTR212
массив Time нулевой.а NCH и так 4 не превышает(задаем в ручную).но спасибо, за подсказку, попробуем.
|
|
|
|
- Сотрудник "Л Кард"
- Здесь с 18.04.2014
- Сообщений: 810
|
Re: Проблемка с LTR212
Что значит - массив Time нулевой?
Он имеет размер 9 cardinal (DWORD), и если передать размер больше (SIZZE > 9), то функция LTR212_Recv будет писать данные в память за пределами массива Time. Последствия непредсказуемы и могут включать искажение посторонних переменных, вылет по ошибке <<программа выполнила недопустимую операцию>> и т.п.
Вот если АДРЕС нулевой, т.е. если в функцию вместо указателя на массив передать nil, то она ничего не затрет, потому что специально так написана (сравнивает с nil и тогда ничего не пишет).
|
|
|
|
|
Re: Проблемка с LTR212
1.С двухместного крейта перешли на восьмиместный, с которым планируется дальнейшая работа. Появилась следующая проблема: обнуляется структура LTR212 первого и(или) второго модуля. Третий и т. д. работают нормально.
Модули и каналы используемые задаем вручную. Если задаем 1ый или 2ой модули, или их оба, то они в определенный момент (уже после того, как открылись и все параметры были заданы, но до старта сбора данных) обнуляются, соответственно при старте сбора данных ошибка ->выход.
А если начинаем с 3его – все нормально.
2.Калибровка.8модульный крейт. На модуле подключено 2 канала, 2 канала «висят в воздухе», калибровка завершается с ошибкой, как и UTS. Но до этого мы проводили эксперименты на 2модульном крейте на другом копьютере и калибровка проходила. Выдовала конечно сообщение об ошибке, но значения на 2х первых каналах были откалиброваны.
|
|
|
|
- Сотрудник "Л Кард"
- Здесь с 18.04.2014
- Сообщений: 810
|
Re: Проблемка с LTR212
по пункту 1.
Вы исправили ошибку с затиранием памяти, о которой мы говорили выше?
Проверьте код, если не сможете найти - присылайте минимальный исходник (без GUI) и описание опыта, в котором можно возпроизвести ситуацию.
|
|
|
|
|
Re: Проблемка с LTR212
да, все исправили... было все хорошо, перешли на 8местный крейт и начались новые фокусы
а программку мою вам отправляли(даже вроде лично), но неисправленную версию...отправитель Протопопов А.Ю.
|
|
|
|
- Сотрудник "Л Кард"
- Здесь с 18.04.2014
- Сообщений: 810
|
Re: Проблемка с LTR212
Могу только гадать. Проверьте все вызовы, не стоит ли где-то ссылка на другую переменную (если копировали куски кода через clipboard, а потом меняли имя переменной, такое бывает). Или указатель вместо копии. Или опять где-то указан размер больше фактического...
Исходника Вашего у меня нет. Если можете сделать из своего текущего варианта минимальный тест, пришлите на по почте на yem@ или сбросьте сюда.
|
|
|
|
|
Re: Проблемка с LTR212
Спасибо..вроде помогло...
|
|
|
|
|
Re: Проблемка с LTR212
Но с калибровкой проблема осталась.
Имеем 8местный крейт, на 1ом, 4ом и 8ом модулях подключено по два канала(1 и 2) на каждом, на 6 модуле подключен 2 канал. Калибруем на 5 диапазоне.
Проверяем через UTS каждый канал по отдельности. Первые каналы – калибровка проходит нормально, а на вторых каналах (на любом из модулей) выдает сообщение об ошибке «Ошибка входных параметров». При чем, если в окне «Конфигурация модуля» выбрать 4 канала, а в окне «Калибровка» оставить только второй канал, то калибровка проходит нормально.
|