|
Внимание, важное сообщение: Дорогие Друзья!
В ноябре далекого 2001 года мы решили создать сайт и форум, которые смогут помочь как начинающим, так и продвинутым пользователям разобраться в операционных системах. В 2004-2006г наш проект был одним из самых крупных ИТ ресурсов в рунете, на пике нас посещало более 300 000 человек в день! Наша документация по службам Windows и автоматической установке помогла огромному количеству пользователей и сисадминов. Мы с уверенностью можем сказать, что внесли большой вклад в развитие ИТ сообщества рунета. Но... время меняются, приоритеты тоже. И, к сожалению, пришло время сказать До встречи! После долгих дискуссий было принято решение закрыть наш проект. 1 августа форум переводится в режим Только чтение, а в начале сентября мы переведем рубильник в положение Выключен Огромное спасибо за эти 24 года, это было незабываемое приключение. Сказать спасибо и поделиться своей историей можно в данной теме. С уважением, ваш призрачный админ, BigMac... |
|
| Компьютерный форум OSzone.net » Программирование, базы данных и автоматизация действий » Программирование и базы данных » .NET - C# Программирование АЦП |
|
|
.NET - C# Программирование АЦП
|
|
Старожил Сообщения: 251 |
АЦП Zet 220 (USB), есть библиотека zadc.dll на C. Функций в dll много, поэтому хотел бы в одном файле разместить обращение к dll. Начал с функций ZOpen и ZClose:
В другом файле хотел бы разместить программу считывания данных из АЦП. Но уже при попытке вызвать ZOpen в Main возникли проблемы: ZetFun не видится в файле программы и после точки не показываются функции dll (если описание функций разместить в классе Program, то все работает). Пробовал сделать public ZOpen и ZClose - результат тот же. Если разместить методы в одном файле с программой - все работает. Подскажите, пожалуйста, что нужно изменить в файле (классе) ZetFun c функциями dll и файле (классе) Program, чтобы можно было обращаться к функциям dll из файла (класса) Program. Проект прикрепил.
|
|
|
Отправлено: 11:22, 01-02-2021 |
|
Забанен Сообщения: 793
|
Какбэ... есть такая штука, модфикаторы называется: public, protect, internal. В C# объявление класса без явных модификаторов подразумевает private класс, то есть если вы разбиваете проект на сборки, данный аспект особенно чувствителен.
using System;
using System.Runtime.InteropServices;
namespace KakayaToZhopa {
inetrnal static class ExternalCall {
// импорты
[DllImport("tugoybolt.dll", SetLastError = true]
internal static extern Int32 ZhOpen(Int32 DeviceType, Int32 DSPNumber);
}
internal sealed class Program {
static void Main() {
// ... точка входа
}
}
}
|
|
Отправлено: 17:53, 03-02-2021 | #2 |
|
Старожил Сообщения: 251
|
Профиль | Отправить PM | Цитировать Спасибо за ответ. Я попробовал internal и public сразу же после того, как задал вопрос - не получилось. Оказалось, что я случайно исключил файл с функциями из DLL из компилирования. Прошу прощения за свою невнимательность.
Возникла более серьезная проблема. Есть пример программы на C++ (Test_Zadc.cpp), который я поместил в архив. Код на С++ работает, я проверял на АЦП с подключенными к первому (0) и второму (1) входам АЦП батарейками на 1.5 и 3 V. Все функции из zadc.dll работают нормально в программе на C#, ошибок не выдают. Но у меня не получается правильно перевести строки с указателями. В коде на C++ (проверку на ошибки убрал): short *pBuffer16ADC = NULL; // Указатель на начало буфера драйвера для АЦП с разрядностью не более 16 бит
long *pBuffer32ADC = NULL; // Указатель на начало буфера драйвера для АЦП с разрядностью более 16 бит
long sizeBufferADC; // Размер буфера драйвера в словах
long pointerADC = 0; // Указатель на текущий элемент заполнения буфера драйвера (кратен 2)
long pointerADC_old = 0; // Предыдущее значение указателя на буфер драйвера
// Запрос буфера АЦП
Err = ZGetBufferADC(typeDevice, numberDSP, (void**) &pBuffer16ADC, &sizeBufferADC);
pBuffer32ADC = (long*) pBuffer16ADC;
// Запрос на останов АЦП
Err = ZStopADC(typeDevice, numberDSP);
// Запрос на запуск АЦП
Err = ZStartADC(typeDevice, numberDSP);
// Цикл чтения данных АЦП
while(!kbhit())
{
// Задержка обновления данных АЦП для отображения
Sleep(500);
// Запрос указателя на текущий элемент буфера
Err = ZGetPointerADC(typeDevice, numberDSP, &pointerADC);
// Если новые данные в буфер от АЦП не поступили, то перейти в начало цикла и подождать
if(pointerADC == pointerADC_old)
continue;
// Обновление предыдущего значения указателя
pointerADC_old = pointerADC;
// Переход на отсчет первого включенного канала последнего кадра АЦП
if(pointerADC - numWordsADC * numChannelsADC < 0)
pointerADC = sizeBufferADC + pointerADC - numWordsADC * numChannelsADC;
else
pointerADC = pointerADC - numWordsADC * numChannelsADC;
// Вычисление из целого значения отсчета АЦП вещественного значение отсчета (в вольтах) для первого канала
if(numWordsADC == 1)
volt0 = resolutionADC0 * (pBuffer16ADC[pointerADC]) / amplifyADC0;
else
volt0 = resolutionADC0 * (pBuffer32ADC[pointerADC / numWordsADC]) / amplifyADC0;
// Вывод мгновенного значения напряжения для первого канала
printf("%+8.4f", volt0);
// Если количество каналов устройства больше одного
if(numChannelsADC > 1)
{
// Переход на следующий отсчет АЦП
pointerADC += numWordsADC;
// При выходе за границу буфера, осуществляется переход в начало
if(pointerADC >= sizeBufferADC)
pointerADC = pointerADC - sizeBufferADC;
// Вычисление из целого значения отсчета АЦП вещественного значение отсчета (в вольтах) для второго канала
if(numWordsADC == 1)
volt1 = resolutionADC1 * (pBuffer16ADC[pointerADC]) / amplifyADC1;
else
volt1 = resolutionADC1 * (pBuffer32ADC[pointerADC/numWordsADC]) / amplifyADC1;
// Вывод мгновенного значения напряжения для второго канала
printf("\t%+8.4f", volt1);
IntPtr pBuffer16;
int sizeBuffer;
if (ZetFun.ZGetBufferADC(typeDevice, numberDSP, out pBuffer16, out sizeBuffer) != 0)
ShowMes("Не удалось получить указатель на буфер АЦП!");
IntPtr pBuffer32 = pBuffer16; //НАВЕРНОЕ, НУЖНО КАКОЕ-ТО ПРЕОБРАЗОВАНИЕ
if (ZetFun.ZStartADC(typeDevice, numberDSP) != 0) // инициализация АЦП
ShowMes("Не удалось запустить АЦП!");
var watch = new Stopwatch();
double[] volt = new double[nChan];
int pointer; int pointer_old;
watch.Start();
while (true)
{
Thread.Sleep(500);
if (watch.ElapsedMilliseconds >= 6000)
break;
if (ZetFun.ZGetPointerADC(typeDevice, numberDSP, out pointer) != 0)
ShowMes("Не удалось получить указатель на текущий элемент буфера!");
if (pointer == pointer_old)
continue;
pointer_old = pointer;
for (int i = 0; i < ariNumberChannel.Length; i++)
{
if (pointer - numWords * ariNumberChannel[i] < 0)
pointer = sizeBuffer + pointer - numWords * ariNumberChannel[i];
else
pointer = pointer - numWords * ariNumberChannel[i];
volt[i] = ardResol[i] * (pBuffer32[pointer / numWords]) / ardAmplify[i]; // ТУТ ОШИБКА
// (pBuffer32[pointer / numWords]) подчеркнут красным, я не знаю, как правильно записать эту строку
Console.WriteLine(volt[i]);
pointer += numWords;
if (pointer >= sizeBuffer)
pointer = pointer - sizeBuffer;
} // for
} // while
watch.Stop();
// Запрос на останов АЦП
if(ZetFun.ZStopADC(typeDevice, numberDSP) != 0)
ShowMes("Не удалось остановить АЦП!");
// Запрос на освобождение буфера АЦП
if (pBuffer16 != null)
{
if(ZetFun.ZRemBufferADC(typeDevice, numberDSP, ref pBuffer16) != 0)
ShowMes("Не удалось освободить буфер!");
}
if (ZetFun.ZClose(typeDevice, numberDSP) != 0)
ShowMes("Ошибка ZClose!");
|
|
Отправлено: 14:59, 04-02-2021 | #3 |
|
Забанен Сообщения: 793
|
В C# указатели реализуются через unsafe code.
|
|
Отправлено: 16:34, 04-02-2021 | #4 |
|
Старожил Сообщения: 251
|
Профиль | Отправить PM | Цитировать Это я знаю. Только никак не могу понять, как при получении указателя с помощью функции
получить из pBuffer16 указатель pBuffer32 и правильно записать формулу
Я выделял кусок кода с помощью unsafe{...}, но возникали ошибки. Особенно мне не ясно, что значит выражение (pBuffer32[pointer / numWords]), которое похоже на указание элемента указателя и записывается как массив. В квадратных скобках получается число типа int, поделенное в моем случае на двойку.
|
|
|
Отправлено: 22:00, 04-02-2021 | #5 |
|
|
Участник сейчас на форуме |
|
Участник вне форума |
![]() |
Автор темы |
![]() |
Сообщение прикреплено |
| |||||
| Название темы | Автор | Информация о форуме | Ответов | Последнее сообщение | |
| Звук - Выяснить параметры ЦАП и АЦП? | Firm_Head | Прочее железо | 2 | 23-08-2010 21:53 | |
| Программирование | andy666 | Программирование и базы данных | 3 | 24-10-2003 22:17 | |
| Программирование | andy666 | Программирование и базы данных | 1 | 10-10-2003 19:52 | |
| Программирование | LeXo | Программирование и базы данных | 10 | 11-10-2002 12:23 | |
|