|
- Участник
- Здесь с 12.02.2022
- Сообщений: 23
|
Re: Astra Linux
Доброй ночи! Продолжаю задавать вопросы Подскажите, сколько максимум значений можно считать в функции LTR22_Recv ?
|
|
- Сотрудник "Л Кард"
- Здесь с 17.04.2014
- Сообщений: 1,291
|
Re: Astra Linux
Добрый день. А с чем связан вопрос? 1. Формально размер технически ограничен значением, которое можно передать в типе INT для передачи размера в запросе и получении результат. Но это очень большое значение (2^31) и на реальную работу никак не влияет. Реально ограничение идет не явное по следующим двум пунктам. 2. Размером буфера - data и tstamp должны быть достаточного размера, чтобы вместить максимально запрашиваемое количество отсчетов. Ну тут уже явной самой верхней границы дать нельзя, но в любом случае это влияет на занимаемую оперативную память и должно быть какое-то разумное значение. 3. Время выполнения функции. Т.к. отсчеты АЦП получает с определенной настроенной частотой, то соответственно чем больше будет размер, тем больше времени на их сбор, тем больше нужно будет ставить таймаут на прием и соответственно большее время будет выполняться функция при том, что ее нельзя отменить. Если таймаут будет слишком маленький, то Recv примет столько данных, сколько будет получено от модуля за указанное время (проверить, все ли принялись данные, можно по результату функции)
|
|
- Участник
- Здесь с 12.02.2022
- Сообщений: 23
|
Re: Astra Linux
Спасибо, за подробный ответ Наконец-то получилось протестировать ПО с источником данных (генератор импульсов). В LGraph2 фиксируется сигнал с быстрым ростом значения от 0 до 5, а затем медленный спад до 0. Мое ПО фиксирует только кусок сигнала (медленный спад). Т.е. данные, которые фиксируются сразу после "Спад сигнала на разъёме SYNC" я не могу получить. В какую сторону смотреть? hcrate = new TLTR();
module1 = new TLTR22(); // создаем структуру в памяти
//memset(module1,0,sizeof(TLTR22));
LTR22_Init(module1);
module2 = new TLTR22(); // создаем структуру в памяти
//memset(module2,0,sizeof(TLTR22));
LTR22_Init(module2);
module1->Channel.saddr = 0x7f000001; //127.0.0.1
module1->Channel.sport = 11111;
module1->Channel.csn[0] = '6';
module1->Channel.csn[1] = 'T';
module1->Channel.csn[2] = '7';
module1->Channel.csn[3] = '6';
module1->Channel.csn[4] = '9';
module1->Channel.csn[5] = '6';
module1->Channel.csn[6] = '5';
module1->Channel.csn[7] = '1';
module1->Channel.cc = 1;
module2->Channel.saddr = 0x7f000001; //127.0.0.1
module2->Channel.sport = 11111;
module2->Channel.csn[0] = '6';
module2->Channel.csn[1] = 'T';
module2->Channel.csn[2] = '7';
module2->Channel.csn[3] = '6';
module2->Channel.csn[4] = '9';
module2->Channel.csn[5] = '6';
module2->Channel.csn[6] = '5';
module2->Channel.csn[7] = '1';
module2->Channel.cc = 2;
DataModul1 = new double[32000*4];
DataModul2 = new double[32000];
int rez1=LTR22_Close(module1);
int rez2=LTR22_Close(module2);
rez1=LTR22_Open(module1, module1->Channel.saddr, module1->Channel.sport, module1->Channel.csn, module1->Channel.cc);
rez2=LTR22_Open(module2, module2->Channel.saddr, module2->Channel.sport, module2->Channel.csn, module2->Channel.cc);
//modul1
rez1 = LTR22_SwitchMeasureADCZero(module1, false);
rez1 = LTR22_SwitchACDCState(module1, true);
rez1 = LTR22_SetADCChannel(module1,0,true);
rez1 = LTR22_SetADCChannel(module1,1,true);
rez1 = LTR22_SetADCChannel(module1,2,true);
rez1 = LTR22_SetADCChannel(module1,3,true);
rez1 = LTR22_SetFreq(module1,true, 2);
rez1=LTR22_SetADCRange(module1, 0, 4); // +-10B
rez1=LTR22_SetADCRange(module1, 1, 4);
rez1=LTR22_SetADCRange(module1, 2, 4);
rez1=LTR22_SetADCRange(module1, 3, 4);
rez1=LTR22_GetConfig(module1);
//modul2
rez2 = LTR22_SwitchMeasureADCZero(module2, false);
rez2 = LTR22_SwitchACDCState(module2, true);
rez2 = LTR22_SetADCChannel(module2,0,true);
rez2 = LTR22_SetADCChannel(module2,1,false);
rez2 = LTR22_SetADCChannel(module2,2,false);
rez2 = LTR22_SetADCChannel(module2,3,false);
rez2 = LTR22_SetFreq(module2,true, 2);
rez2=LTR22_SetADCRange(module2, 0, 4);
rez2=LTR22_GetConfig(module2);
//crate
rez_crate = LTR_Init(hcrate);
rez_crate = LTR_OpenCrate(hcrate, 0x7f000001, 11111, 2, "");
// старт сбора данных
rez = LTR22_StartADC(module1, false);
rez = LTR22_StartADC(module2, false);
rez_crate = LTR_StartSecondMark(hcrate, LTR_MARK_EXT_DIGIN1_FALL);//по спаду DIGIN1
//в отдельном потоке для каждого модуля
// старт сбора данных
bool flag_out = true;
int module_en_ch_cnt = 4; /* кол-во разрешенных каналов в модуле */
int module_num = 0;/* номер модуля, 0 или 1 */
DWORD rbuf[4*BLOCK_RX_CH_WORDS_CNT];
DWORD tstmp[4*BLOCK_RX_CH_WORDS_CNT];
double *proc_buf = new double[4*BLOCK_RX_CH_WORDS_CNT];
DWORD last_tstmp[2]; /* сохранение tstmp для отслеживания изменения по каждому модулю. Нужно сохранять, т.к. может изменится на границе блоков! */
bool last_tstmp_valid[2] = {false, false}; /* признак, что инициализировали значение last_tstmp */
double pt;
//byte OverflowFlags[4];
byte *OverflowFlags = new byte[4];
while (flag_out)
{
//возвращает количество полученных данных
int recvd = LTR22_Recv(dev_ConnectLcard->module1, rbuf, tstmp, module_en_ch_cnt * BLOCK_RX_CH_WORDS_CNT, 2000);
cout << "количество полученных данных MODUL 1 = " << recvd << endl;
if (recvd > 0)
{
/* если еще значение метки не инициализировано, то иницизируем первым принятым значением */
if (!last_tstmp_valid[module_num])
{
cout << " init metka " << endl;
last_tstmp[module_num] = tstmp[0] & 0xFFFF; /* используем только младшие 16 бит - метку СЕКУНДА без учета метки СТАРТ */
last_tstmp_valid[module_num] = true;
}
/* обработка данных */
rez = LTR22_ProcessData(dev_ConnectLcard->module1, rbuf, proc_buf, recvd, true, true, OverflowFlags);
if(rez != 0) cout << "!!! ERROR MODUL 1 LTR22_ProcessData = " << LTR22_GetErrorString(rez) << endl;
/* быстрая проверка, изменилась ли метка, сравнивая метку на конец блока с последней действительной. */
if (last_tstmp[module_num] != (tstmp[recvd-1] & 0xFFFF))
{
/* ищем момент изменения метки - для простоты примера просто проходим по всем элементам без каких-то ускоренных поисков */
for (int i = 0; i < recvd; ++i)
{
if (last_tstmp[module_num] != (tstmp[i] & 0xFFFF))
{
flag_out = false;
cout << "количество полученных данных MODUL 1 = " << recvd << endl;
last_tstmp[module_num] = tstmp[i] & 0xFFFF;
/* обновляем последнее значение метки */
/* метка изменилась на i-ом элементе */
/* полчаем позицию в массиве на канал после обработки */
int proc_ch_pos = (i / module_en_ch_cnt);
cout << "!!!!!!! proc_ch_pos = " << proc_ch_pos << endl;
for (int ch_num = 0; ch_num < module_en_ch_cnt; ++ch_num)
{
/* для каждого канала получаем точку за изменением метки времени.
если нужно более одной точки то можем пройтись по позиции с proc_ch_pos до proc_ch_pos + N,
но должны учитывать, что следующие точки могут выйти за границу блока,
принятого в этот раз. Тогда нужно ставить флаг для модуля, что обработать еще сколько-то
точек из следующего блока */
for(int point = 0; point<32000-proc_ch_pos; point++)
{
pt = proc_buf[recvd/module_en_ch_cnt * ch_num + proc_ch_pos + point];
/* сохраняем полученную точку или обрабатываем другим требуемым образом */
dev_ConnectLcard->DataModul1[32000*ch_num + point] = pt;
}
}
}
i = recvd;
}
}
}
}
//в основном потоке
rez = LTR_StopSecondMark(hcrate); /* останов меток (может быть и после останова модулей) */
rez = LTR22_StopADC(module1); /* останов сбора*/
rez = LTR22_ClearBuffer(module1,true); /* очистка буфера */
rez = LTR22_StopADC(module2); // останов сбора
rez = LTR22_ClearBuffer(module2,true); // очистка буфера
rez1=LTR22_Close(module1);
rez2=LTR22_Close(module2);
rez_crate = LTR_Close(hcrate);
|
|
- Сотрудник "Л Кард"
- Здесь с 17.04.2014
- Сообщений: 1,291
|
Re: Astra Linux
Честно говоря не до конца понял, что именно подаете на DIGIN1 и на входы АЦП и что именно изображено на осциллографе (на нем то никакого медленного спада нет). Можете подробнее описать, как выглядят подаваемые сигналы на АЦП и DIGIN1 во времени, как это видится в LGraph2 (скриншот), как в Вашей программе? В LGraph2 идет постоянная запись или тоже настраивается старт записи по метке? Какая задержка между ожидаемым началом данных и реальным? фиксирована ли она от запуска к запуску?
|
|
- Участник
- Здесь с 12.02.2022
- Сообщений: 23
|
Re: Astra Linux
В LGraph2 настроен старт записи так же по спаду DIGIN1. Оказывается импульс поступает на плату и она имитирует вот такой сигнал:
Задержка между ожидаемым началом данных и реальным 400 - 800 мс, задержка плавающая. Мое ПО считывает только участок спада.
|
|
- Сотрудник "Л Кард"
- Здесь с 17.04.2014
- Сообщений: 1,291
|
Re: Astra Linux
У Вас i = recvd; похоже должно быть на уровень выше по скобкам, т.е. сейчас он у Вас к циклу относится и по сути Вы всегда выходите из цикла при i = 0. Т.е. как только выполнится if (last_tstmp[module_num] != (tstmp[recvd-1] & 0xFFFF)) вы заходите в цикл и сразу выходите, не сбросив flag_out и ничего не обработав, т.е. Вы пропускаете данные от реальной метки до конца блока приема и сохраняете только следующий блок, отчего и идет пропажа начала сигнала. Я бы вообще явно сделал выход из цикла по флагу: for (int i = 0; (i < recvd) && flag_out; ++i) без всяких i = recvd а BLOCK_RX_CH_WORDS_CNT у Вас равно 32000?
|
|
- Участник
- Здесь с 12.02.2022
- Сообщений: 23
|
Re: Astra Linux
Алексей L Card пишет:У Вас i = recvd; похоже должно быть на уровень выше по скобкам, т.е. сейчас он у Вас к циклу относится и по сути Вы всегда выходите из цикла при i = 0. Т.е. как только выполнится if (last_tstmp[module_num] != (tstmp[recvd-1] & 0xFFFF)) вы заходите в цикл и сразу выходите, не сбросив flag_out и ничего не обработав, т.е. Вы пропускаете данные от реальной метки до конца блока приема и сохраняете только следующий блок, отчего и идет пропажа начала сигнала. Я бы вообще явно сделал выход из цикла по флагу: for (int i = 0; (i < recvd) && flag_out; ++i) без всяких i = recvd а BLOCK_RX_CH_WORDS_CNT у Вас равно 32000?
Да, Вы правы! Пока нет возможности протестировать с источником данных, но похоже в том и закралась ошибка. Спасибо!!! Да, BLOCK_RX_CH_WORDS_CNT равно 32000. У меня еще вопрос. Как посчитать сколько мне сохранять точек, если, допустим, мне нужны данные только за первую секунду? Есть какой-то параметр наподобие "Частота опроса", зная который я могу рассчитать требуемое число точек?
|
|
- Сотрудник "Л Кард"
- Здесь с 17.04.2014
- Сообщений: 1,291
|
Re: Astra Linux
Частоту сбора Вы задаете с помощью LTR22_SetFreq(). Она определяет по сути время между двумя отсчетами одного канала. Частота определяется как 20 МГц / (128 * div_main * div_extra), где div_extra зависит от второго параметра функции (3, если true, 2 - false), а второй делитель задается явно третьим параметром. Т.е. в Вашем случае LTR22_SetFreq(module1,true, 2); получается 20 МГц / (128 * 2 * 3) = 26041,6666667 КГц, т.е. Вам для этой частоты нужно 26042 точки для получения 1 с (Дополнительно есть функция LTR22_FindAdcFreqParams (правда недокументированная) подбора этих параметров под нужную частоту сбора, которой передается желаемая частота, а на выходе получаются два параметра для передачи LTR22_SetFreq и реально получившаяся частота). Вам только Важно учитывать, что у Вас (recvd - proc_ch_pos) может быть меньше требуемого размера. Т.е. Вам нужно в этом случае скопировать (recvd - proc_ch_pos) точек по каждому каналу, после чего дополнительно вызвать Recv и ProcessData на (module_en_ch_cnt * (26042 - (recvd - proc_ch_pos))) точек и дописать результаты в конец Вашего буфера.
|
|
- Участник
- Здесь с 12.02.2022
- Сообщений: 23
|
Re: Astra Linux
Спасибо вам, сотрудники поддержки LCard! Вы быстро и подробно отвечаете на вопросы! Обняла
|
|
- Сотрудник "Л Кард"
- Здесь с 17.04.2014
- Сообщений: 1,291
|
Re: Astra Linux
Рады были помочь, если что - обращайтесь!
|
|
- Участник
- Здесь с 03.06.2022
- Сообщений: 1
|
Re: Astra Linux
Отключилась в Windows, запустила в Linux LTR Manager, настроила, отключила/включила питание модуля и все заработало - спасибо smile
|
|
- Участник
- Здесь с 12.02.2022
- Сообщений: 23
|
Re: Astra Linux
Добрый вечер! Возникает необходимость с одного ПК поочередно подключаться к разным модулям. Вроде отключаюсь всегда корректно LTR22_Close(module1);
LTR22_Close(module2);
LTR_Close(hcrate);
Но при попытке соединится с новым модулем (с которым уже были соединения ранее) возникают ошибки: LTR22Open = Указанный крейт не найден
Даже LTRManager не может подключиться.
Помогает только подключиться к модулю через провод и выполнить в LTRManager сброс крейта. Но данный способ мне не подходит. Пытаюсь выполнить LTR_ResetModule, но возникает ошибка при выполнении данной команды: -14 (Указанный крейт не найден) hcrate = new TLTR();
int rez_crate = LTR_Init(hcrate);
if(rez_crate != 0)
cout << "!!! ERROR crate LTR_Init = " << LTR22_GetErrorString(rez_crate) << endl;
int resopen = LTR_OpenSvcControl(hcrate, 0x7f000001, 11111);
cout << "LTR_OpenSvcControl = " << resopen << endl;
int rezcrate = LTR_ResetModule(hcrate, LTR_CRATE_IFACE_TCPIP, "", 1, 0);
cout << "LTR_ResetModule 1 = " << rezcrate << endl;
rezcrate = LTR_ResetModule(hcrate, LTR_CRATE_IFACE_TCPIP, "", 2, 0);
cout << "LTR_ResetModule 2 = " << rezcrate << endl;
вывод: LTR_OpenSvcControl = 0
LTR_ResetModule 1 = -14
LTR_ResetModule 2 = -14
Как можно сбросить крейт по сети?
|
|
- Участник
- Здесь с 12.02.2022
- Сообщений: 23
|
Re: Astra Linux
TaPan пишет:Даже LTRManager не может подключиться.
Еще раз проверила - LTRManager может подключаться, а из моего приложения нет, на команду LTR22_Open ответ: Указанный крейт не найден. Сбросить крейт по сети не получается.
|
|
- Сотрудник "Л Кард"
- Здесь с 17.04.2014
- Сообщений: 1,291
|
Re: Astra Linux
Что-то несколько не до конца понял, Вы пишите, что LTR Manager может подключаться, а из приложения нет. Но на скрине как раз LTR Manager не может подключиться к крейту, список крейтов пуст. В этом случае как раз логична ошибка, что крейт не найден, т.к. LTR Manager не смог с ним соединиться. Если действительно проблема в том, что к самому крейту LTR Manager не может подключится по Ethernet, но может по USB, то проверьте при подключившись по USB версию прошивки крейта (выводится в информации о крейте при его выделении в LTR Manager), если версия 2.0.0.0, то в ней возможна проблема, что если с крейтом соединение закрыто некорректно (это не относится к вызову функций работы с модулями, а например если физически кабель был отключен или если комп например был выключен нештатным образом), то крейт не давал установить новое соединение. В этом случае Вы можете подключить крейт по USB и обновить прошивку модуля через LTR Manager (по Ethernet обновление не работает к сожалению). Арихив с прошивками - https://www.lcard.ru/download/ltreu-fw-3.0.0.13.zip. Для духместного (вроде он у Вас был до этого на скринах) нужен файл, начинающийся с ltr031 (ltr030 - для 8/16 местного). Для обновления достаточно подключить крейт по USB и нажать на него правой кнопкой мыши и выбрать обновить прошивку крейта и указать файл, после чего пересбросить весь крейт.
|
|
- Участник
- Здесь с 12.02.2022
- Сообщений: 23
|
Re: Astra Linux
Алексей L Card пишет:Что-то несколько не до конца понял, Вы пишите, что LTR Manager может подключаться, а из приложения нет. Но на скрине как раз LTR Manager не может подключиться к крейту, список крейтов пуст. В этом случае как раз логична ошибка, что крейт не найден, т.к. LTR Manager не смог с ним соединиться. Если действительно проблема в том, что к самому крейту LTR Manager не может подключится по Ethernet, но может по USB, то проверьте при подключившись по USB версию прошивки крейта (выводится в информации о крейте при его выделении в LTR Manager), если версия 2.0.0.0, то в ней возможна проблема, что если с крейтом соединение закрыто некорректно (это не относится к вызову функций работы с модулями, а например если физически кабель был отключен или если комп например был выключен нештатным образом), то крейт не давал установить новое соединение. В этом случае Вы можете подключить крейт по USB и обновить прошивку модуля через LTR Manager (по Ethernet обновление не работает к сожалению). Арихив с прошивками - https://www.lcard.ru/download/ltreu-fw-3.0.0.13.zip. Для духместного (вроде он у Вас был до этого на скринах) нужен файл, начинающийся с ltr031 (ltr030 - для 8/16 местного). Для обновления достаточно подключить крейт по USB и нажать на него правой кнопкой мыши и выбрать обновить прошивку крейта и указать файл, после чего пересбросить весь крейт.
Добрый вечер! Я обновила прошивку до 3.0.0.13. Проверила, работу своего ПО с одного ПК (ПО подключается к крейтам без ошибок, считываются данные). Затем то же ПО запустила на другом ПК и в результате ошибки при выполнении команды LTR22Open "Указанный крейт не найден", при этом LTR Manager подключается без ошибок. Помогает только команда "Сброс крейта" через LTR Manager (но требует подключения через USB), но в дальнейшем я не смогу так подключаться, а работать только по сети. Программным способом нашла команды сброса только модулей, а не крейта. Как я могу поочередно работать с крейтом с разных ПК?
|
|
- Сотрудник "Л Кард"
- Здесь с 17.04.2014
- Сообщений: 1,291
|
Re: Astra Linux
1. Не совсем понятно, что имеется ввиду под "LTR Manager подключается без ошибок." Если подключается к крейту, то соответствующая запись IP-адреса должна быть в состоянии "Подключен", а крейт с модулями в дереве активных крейтов, но тогда к нему возможно и подключится через Open. Ошибка "Указанный крейт не найден" как раз говорит, что крейта в списке активных нет. Можете прислать выложить скрин с LTR Manager с журналом, что именно происходит. 2. Важно понимать, что с крейтом неможет быть установлено соединение одновременно с разных ПК через ltrd/LTR Manager, работать можно только поочередно, отключив соединение на одном ПК перед тем как подключаться с другого. При этом также важно понимать, что реально соединение устанавливает служба ltrd, а LTR Manager - только графический интерфейс для просмотра информации и управления, т.е. само закрытие программы LTR Manager не приводит к разрыву соединения, нужно явно отключать крейт по IP-адресу через LTR Manager или функцию библиотеки. 3. В прошивке 3.0.0.13 должна быть возможность подключиться к крейту по IP-записи, если даже установлено соединение из другого ПК, при этом на другом ПК соединение будет разорвано. Однако, если у Вас установлены флаги A (автоподключение) и R (повторное подключение), то при разрыве соединения служба ltrd будет автоматически пытаться подключиться заново к крейту, что может привести, что при таких настройках на двух ПК может привести к тому, что службы с разных ПК будут поочередно перехватывать друг у друга подключение к крейту. Для работы с разных ПК возможно имеет смысл не устанавливать флаги A и R, а выполнять подключение и отключение по IP-адресу вручную (либо через LTR Manager, либо функции библиотеки) только на время, когда крейт нужен на соответствующем ПК.
|