Форум: Техническая поддержка

Тема: написание софта под Е14-140 на С#

Вы не вошли.

 Поиск | Регистрация | Вход 

21.02.2013 10:10:43
#26

Сотрудник "Л Кард"
Здесь с 17.04.2014
Сообщений: 1,256

Re: написание софта под Е14-140 на С#

По поводу Вашего сообщения на форме:

Во-первых структуру ADC_PARS_E140 нужно объявить как struct, а не class. Раз Вы ее передаете в неуправляемый код на C, то делать ее динамическим управляемым объектом не стоит – могут быть дополнительные проблемы.

Во-вторых, структуры типа struct передаются в функции C вполне спокойно без использования специальных классов, просто с указанием ключевых слов ref или out. Достаточно объявить функцию так:

[DllImport("E140ForCSarp.dll", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Ansi)]
public static extern bool fnE140ForCSarpSET_ADC_PARS(ref ADC_PARS_E140 ap);

Соответственно, при вызове передать ее тоже со словом ref.

Антон
21.02.2013 13:17:35
#27

Гость

Re: написание софта под Е14-140 на С#

Алексей (L-Card), сделал как Вы сказали! но все равно Ваша функция SET_ADC_PARS возвращает ОШИБКУ (FALSE)... может не верно объявил структуру на С#?!
[StructLayout(LayoutKind.Sequential, Pack = 1, CharSet = CharSet.Unicode)]
// структура, задающая режим работы АЦП для модуля E14-140
    public struct ADC_PARS_E140
    {
        public ushort ClkSource;                            // источник тактовых импульсов для запуска АПП
        public ushort EnableClkOutput;                    // разрешение трансляции тактовых импульсов запуска АЦП
        public ushort InputMode;                            // режим ввода даных с АЦП
        public ushort SynchroAdType;                        // тип аналоговой синхронизации
        public ushort SynchroAdMode;                         // режим аналоговой сихронизации
        public ushort SynchroAdChannel;                  // канал АЦП при аналоговой синхронизации
        public short SynchroAdPorog;                     // порог срабатывания АЦП при аналоговой синхронизации
        public ushort ChannelsQuantity;                    // число активных каналов
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 128)]
        public ushort[] ControlTable;// = new ushort[128];                    // управляющая таблица с активными каналами
        public double AdcRate;                            // частота работы АЦП в кГц
        public double InterKadrDelay;                    // межкадровая задержка в мс
        public double KadrRate;                            // частота кадра в кГц
    };

21.02.2013 16:33:04
#28

Сотрудник "Л Кард"
Здесь с 17.04.2014
Сообщений: 1,256

Re: написание софта под Е14-140 на С#

Ошибка в программе в том, что GET_MODULE_DESCRIPTION надо делать до SET_ADC_PARS, тогда все будет работать (это должно быть описано в руководстве программиста).

Ничего дополнительного в обертке писать не нужно - вполне работает просто вызов функции:

E140FORCSARP_API BOOL WINAPI fnE140ForCSarpSET_ADC_PARS(ADC_PARS_E140 *ap)
{
    return(pModule->SET_ADC_PARS(ap));
}

Антон
21.02.2013 16:54:22
#29

Гость

Re: написание софта под Е14-140 на С#

Спасибо!!! Моя ошибка!(((

Антон
09.03.2013 13:20:47
#30

Гость

Re: написание софта под Е14-140 на С#

Здравствуйте Уважаемые знатоки! Возник вопрос по функции
ReadData(IO_REQUEST_LUSBAPI * const ReadRequest);
а именно как правильно представить структуру IO_REQUEST_LUSBAPI и Overlapped в С#?!
Пытаюсь перевести ВАШ пример использования ReadData() из С++ и ни чего не получается! Прошу ВАШЕГО примера! Спасибо!

Андрей
11.03.2013 09:10:26
#31

Гость

Re: написание софта под Е14-140 на С#

Я делал так:

        [StructLayout(LayoutKind.Sequential, Pack = 1)]
        public struct IO_REQUEST_LUSBAPI
        {
            public IntPtr Buffer;                              
            public UInt32 NumberOfWordsToPass;   
            public UInt32 NumberOfWordsPassed;           
            public IntPtr Overlapped;               
            public UInt32 TimeOut;                           
        };


        [StructLayout(LayoutKind.Sequential)]
        public struct OVERLAPPED
        {
            public IntPtr Internal;
            public IntPtr InternalHigh;
            public int Offset;
            public int OffsetHigh;
            public IntPtr hEvent;
        }

Описание импорта WinAPI функций и структур рекомендую смотреть на PInvoke.net
(http://pinvoke.net/default.aspx/Structu … ED%20.html)

Антон
12.03.2013 19:59:57
#32

Гость

Re: написание софта под Е14-140 на С#

Андрей, Спасибо! а дальше с OVERLAPPED работали через маршалинг... ?!

Андрей
13.03.2013 12:05:06
#33

Гость

Re: написание софта под Е14-140 на С#

За основу был взят пример из "MicroSoft Visual C++ 6.0/ReadData/ReadData.cpp" (Асинхронное чтение с 4 каналов АЦП) и переписан на C#. Для Всех функций из Lusbapi была сделана обертка (plain dll на MSVC, т.к. способа создать указатель на метод в С# я не нашел smile )
Дальше примерно так:

var ptr = CreateLInstance("E440");

var ReadOv = new OVERLAPPED[2];
var IoReq = new IO_REQUEST_LUSBAPI[2];
ReadOv[0] = new OVERLAPPED() { hEvent = CreateEvent(IntPtr.Zero, false, false, null), };

fixed (WinAPIImports.OVERLAPPED* ov0 = &ReadOv[0], ov1 = &ReadOv[1])
                {
                    // формируем необходимые для асинхронного сбора данных структуры
                    IoReq[0] = new IO_REQUEST_LUSBAPI()
                    {
                        Buffer = (IntPtr)ReadBuffer,
                        Overlapped = (IntPtr)ov0,
                        NumberOfWordsToPass = Nsamples,
                    };

ReadData(ptr, ref IoReq[RequestNumber])
}

---
где
импорт в C#

[DllImport("lusbapi.dll", EntryPoint = "CreateLInstance", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)]
public static extern IntPtr CreateLInstance(string DeviceName);

[DllImport(dllName, EntryPoint = "ReadData", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool ReadData(IntPtr ptr, ref LusbApiImports.IO_REQUEST_LUSBAPI ReadRequest);

код обертки над lusbapi:

BOOL ReadData(LPVOID ptr, IO_REQUEST_LUSBAPI * const ReadRequest)
{
    ILE440 *pModule = static_cast<ILE440 *>(ptr);
    if(pModule) return pModule->ReadData(ReadRequest);
    return FALSE;
}

Антон
15.03.2013 19:37:25
#34

Гость

Re: написание софта под Е14-140 на С#

Все заработало!

Антон
15.03.2013 19:37:49
#35

Гость

Re: написание софта под Е14-140 на С#

Спасибо!!!

Антон
01.04.2013 10:29:17
#36

Гость

Re: написание софта под Е14-140 на С#

Здравствуйте, в очередной раз, Уважаемые Знатоки и Разработчики! В продолжении темы возник вопрос! Все заработало, но не могу представить данные на графике в С#, а именно вытянуть, или даже "разложить", их из public IntPtr Buffer; после выполнения ReadData(ReadRequest);... ?! Рылся в ваших примерах так и не нашел как вытянуть данные по каждому каналу! или скорее до меня не дошло как!!!
Спасибо!!!

01.04.2013 12:34:22
#37

Сотрудник "Л Кард"
Здесь с 18.04.2014
Сообщений: 810

Re: написание софта под Е14-140 на С#

Антон, сами данные Вы получили? Т.е. вопрос в том, как их интерпретировать?
Это описано в руководстве. Данные представляют собой последовательность 16-битных знаковых целых (int16_t, signed short int), по 2 байта на отсчет, little-endian. Порядок следования обычный: кадр за кадром, а каждый кадр содержит по одному отсчету на канал в порядке их перечисления в таблице логических каналов.
То есть, например, если опрашиваются 4 канала, данные из которых обозначим соответственно Ai, Bi, Ci, Di (где i - номер отсчета в хронологическом порядке), то поток данных от модуля будет иметь вид:
A1, B1, C1, D1, A2, B2, C2, D2, A3, B3, C3, D3...
Важно помнить, что отсчеты 16-битные, а не 32-x.
В обычном C к ним надо обращаться, например, по указателю типа int16_t*. А в C# можно попробовать
Marshal::ReadInt16(intptr, byte_ofs), где byte_ofs увеличивается с шагом 2.

Антон
01.04.2013 14:00:43
#38

Гость

Re: написание софта под Е14-140 на С#

Александр Е, Сами данные я получаю!!! действительно необходимо интерпретировать!
Значит, я так понял  в C# мне необходимо делать Marshal::ReadInt16(intptr, byte_ofs), где byte_ofs =  2* ? ( ? - не понял, канал или номер отсчета). вот и не пойму как мне разложить по каналам!

01.04.2013 14:20:10
#39

Сотрудник "Л Кард"
Здесь с 17.04.2014
Сообщений: 1,256

Re: написание софта под Е14-140 на С#

Из написанного Александром Е получается, что если всего у Вас используется N каналов, то для того, чтобы получить i-ый отсчет по каналу ch (ch от 0 до N-1) byte_ofs = 2*(i*N + ch)

01.04.2013 14:22:06
#40

Сотрудник "Л Кард"
Здесь с 18.04.2014
Сообщений: 810

Re: написание софта под Е14-140 на С#

Через ReadInt16 (или что-то подобное, я не знаток C#) можно читать 16-битные слова; byte_ofs = 2*n, где n - номер отсчета в блоке данных, начиная с 0.
Как располагаются отсчеты каналов - см. предыдущий пост. Приведенный там пример
A1, B1, C1, D1, A2, B2, C2, D2, A3, B3, C3, D3
будет соответствовать n = 0, 1, ..., 11.

Иначе говоря, n = M * i + j, где M - количество каналов в кадре, i - номер кадра (начиная с 0), j - номер логического канала в таблице логических каналов (0 <= j < M).

Осталось, наверное, только уточнить, что данные идут непрерывным потоком с момента начала сбора данных (START_ADC), то есть если размер прочитанного блока данных (то, на что указывает IntPtr) не кратен размеру кадра, то в следующем блоке данные начнутся не с первого канала, а с того, на котором кончился предыдущий блок.
Скажем, если один запрос чтения вернул 6 отсчетов
{A1, B1, C1, D1, A2, B2}, а второй - {C2, D2, A3, B3, C3, D3}. То есть надо в программе хранить, например, текущее смещение в кадре (число j).

Антон
02.04.2013 00:42:52
#41

Гость

Re: написание софта под Е14-140 на С#

Огромное СПАСИБО! Помогли!!!
данные действительно идут непрерывно с момента START_ADC! По какой причине происходит такое смещение?!

02.04.2013 18:32:01
#42

Сотрудник "Л Кард"
Здесь с 18.04.2014
Сообщений: 810

Re: написание софта под Е14-140 на С#

Какое смещение? Как раз никакого сме

02.04.2013 18:33:47
#43

Сотрудник "Л Кард"
Здесь с 18.04.2014
Сообщений: 810

Re: написание софта под Е14-140 на С#

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

02.04.2013 18:37:20
#44

Сотрудник "Л Кард"
Здесь с 18.04.2014
Сообщений: 810

Re: написание софта под Е14-140 на С#

Если читать всегда блоками, кратными кадру, то в каждом блоке данные будут с первого канала. Но лично я не советую на это закладываться - получится "хрупкая" программа, которую (например, другой программист) может случайно сломать, нарушив неочевидное условие, и потом будет искать ошибку до посинения.

Антон
05.04.2013 12:19:26
#45

Гость

Re: написание софта под Е14-140 на С#

Спасибо!!! Вроде понял!))

Антон
05.04.2013 12:47:22
#46

Гость

Re: написание софта под Е14-140 на С#

Ребята, Советую ВАМ включить данное обсуждение в мануал!))) по написанию собственного программного обеспечения!

05.04.2013 17:40:15
#47

Сотрудник "Л Кард"
Здесь с 18.04.2014
Сообщений: 810

Re: написание софта под Е14-140 на С#

Ну, формат кадра и последовательность кадров там описаны (e14_140_programmers_guide.pdf 4.5.6, 3.2.4).
А то, что поток данных непрерывен, это по определению, он же поток. Иначе куда бы девались недочитанные данные? Поток данных не знает ничего о том, какими порциями его читает программа. Это можно внести в мануал, но вообще-то, по-моему, это очевидно.
(Представьте себе, что Вы переносите полное собрание сочинений Льва Толстого в 90 томах из сундука в книжный шкаф. Переносите порциями по нескольку томов, сколько удобно брать в руки, и ставите на полку по порядку. В результате сама нумерация томов никак не нарушается, и в конечном виде нельзя сказать, какими порциями носили тома, если их не повредили и не перепутали).

nik
08.04.2013 16:32:53
#48

Гость

Re: написание софта под Е14-140 на С#

Антон морально подготовьтесь к тому, что в очередной   Винде про нет технологии забудут. Это часто происходит с различными начинаниями от микрософт и Вам в срочном порядке придётся всё переписывать. Поддержка прекращена. Что Вы ответите на это.

Root_Александр
17.02.2015 18:31:25
#49

Гость

Re: написание софта под Е14-140 на С#

Доброго времени суток! Тема еще актуальна? Как я понимаю, Антону все-таки удалось написать все на c#. Дабы не городить велосипед - вопрос: не остался ли проект где-нибудь в закромах?

andy_plsql
15.11.2017 17:39:39
#50

Гость

Re: написание софта под Е14-140 на С#

Root_Александр пишет:

Доброго времени суток! Тема еще актуальна? Как я понимаю, Антону все-таки удалось написать все на c#. Дабы не городить велосипед - вопрос: не остался ли проект где-нибудь в закромах?

Да, вопрос актуален, можно ли где-то получить проект на C#?

Контакты

Адрес: 117105, Москва, Варшавское шоссе, д. 5, корп. 4, стр. 2

Многоканальный телефон:
+7 (495) 785-95-25
Факс: +7 (495) 785-95-14

Отдел продаж: sale@lcard.ru
Техническая поддержка: support@lcard.ru

Время работы: с 9-00 до 19-00 мск