Руководство по триггерам цифрового вывода в Dewesoft C++
Полное руководство по реализации триггеров цифрового вывода в модуле Dewesoft C++. Узнайте, как отправлять импульсы 5В с определенными интервалами с рабочими примерами кода.
Как реализовать систему триггера цифрового вывода в модуле C++ Dewesoft для отправки импульсов 5В с определенными интервалами?
Я пытаюсь реализовать систему триггера цифрового вывода в скриптовом модуле C++ Dewesoft, которая отправляет импульсы 5В через каналы DO1 и DO2 с определенными интервалами (25 мс и 50 мс соответственно). Несмотря на то, что я следовал онлайн-курсу и реализовал, как мне кажется, правильный код, я не могу заставить систему срабатывать должным образом.
Вот мой подход к реализации:
- Я настроил входной канал как временной сигнал (требуется Dewesoft)
- Я настроил два выходных канала для цифрового вывода 1 и 2
- Я связал выводы цифрового вывода с программными выходами
- Я реализовал следующий код:
namespace bsc = Dewesoft::Math::Api::Basic;
class Module : public bsc::MathModule {
public:
Module();
~Module();
void configure() override;
void start() override;
void stop() override;
void clear() override;
// Outputs have been mapped to Ctrl DO1 / Ctrl DO2 in A/D out
double PyroOneOut = 0.0; // "First Pyro's Output"
double PyroTwoOut = 0.0; // "Second Pyro's Out"
private:
// Timing parameters (ms)
const double t1_ms = 25.0; // DO1 fires at 25 ms
const double t2_ms = 50.0; // DO2 fires at 50 ms
const double width_ms = 5.0; // pulse width
// Internal clock
std::chrono::steady_clock::time_point t0;
};
inline void Module::start() {
t0 = std::chrono::steady_clock::now();
PyroOneOut = 0.0;
PyroTwoOut = 0.0;
}
inline void Module::calculate() {
using namespace std::chrono;
const double ms =
duration<double, std::milli>(steady_clock::now() - t0).count();
const bool do1_high = (ms >= t1_ms) && (ms < (t1_ms + width_ms));
const bool do2_high = (ms >= t2_ms) && (ms < (t2_ms + width_ms));
PyroOneOut = do1_high ? 1.0 : 0.0;
PyroTwoOut = do2_high ? 1.0 : 0.0;
}
Проблема в том, что несмотря на эту реализацию, цифровые выводы не срабатывают как ожидается. Не мог бы кто-то, имеющий опыт работы с модулем C++ Dewesoft, определить, что может быть не так с моим подходом или кодом? Любые рекомендации по правильной реализации таймированных триггеров цифрового вывода в Dewesoft были бы очень признательны.
Триггеры цифрового вывода в модуле C++ Dewesoft
Триггеры цифрового вывода в модуле C++ Dewesoft требуют правильной настройки каналов, реализации тайминга в методе calculate() и корректного отображения вывода. Ваш подход в целом верный, но отсутствуют несколько критических деталей реализации, включая правильные объявления методов, расчет тайминга с использованием внутренней системы тайминга Dewesoft и требования к настройке каналов.
Содержание
- Распространенные проблемы в реализации цифрового вывода C++ в Dewesoft
- Правильная структура модуля C++ и реализация методов
- Лучшие практики расчета тайминга
- Настройка каналов и отображение вывода
- Шаги отладки и устранения неполадок
- Полный рабочий пример
- Расширенные параметры настройки триггеров
Распространенные проблемы в реализации цифрового вывода C++ в Dewesoft
Существует несколько распространенных проблем, которые мешают правильной работе триггеров цифрового вывода в модулях C++ Dewesoft:
Отсутствующие объявления методов: Как указано в учебных материалах Dewesoft, метод calculate() должен быть правильно объявлен в интерфейсе класса, а не только реализован. Это частая ошибка, которая предотвращает работу модуля.
Неправильный подход к таймингу: Прямое использование std::chrono::steady_clock может не соответствовать внутренней системе тайминга Dewesoft. В руководстве по C++ Script указано, что тайминг должен основываться на переменной callInfo.endBlockTime для обработки на основе блоков или на временных метках отдельных выборок.
Нарушения потокобезопасности: Согласно документации Dewesoft, “Запись в выходные каналы и чтение из входных каналов допустимы только внутри процедуры ::calculate(), и только из основного потока! Попытки сделать это из любой другой функции или любого другого потока могут привести к сбою вашего плагина!”
Отсутствующая настройка каналов: Временной сигнал входного канала, упомянутый в вашем подходе, должен быть правильно настроен в методе configure(), который в настоящее время отсутствует в вашей реализации.
Правильная структура модуля C++ и реализация методов
Полный модуль C++ Dewesoft требует правильных объявлений и реализаций методов на протяжении всего жизненного цикла модуля. Вот исправленная структура:
namespace bsc = Dewesoft::Math::Api::Basic;
class Module : public bsc::MathModule {
public:
Module();
~Module();
// Требуемые методы жизненного цикла
void configure() override;
void start() override;
void stop() override;
void clear() override;
// Метод calculate() - ОБЯЗАТЕЛЕН для обработки
void calculate() override;
// Выходные каналы
double PyroOneOut = 0.0; // "Выход первого пиро"
double PyroTwoOut = 0.0; // "Выход второго пиро"
private:
// Параметры тайминга (мс)
const double t1_ms = 25.0; // DO1 срабатывает через 25 мс
const double t2_ms = 50.0; // DO2 срабатывает через 50 мс
const double width_ms = 5.0; // ширина импульса
// Внутреннее состояние тайминга
double startTime_ms = 0.0;
bool measurementStarted = false;
};
Ключевые улучшения:
- Добавлено объявление метода
calculate() - Улучшено управление состоянием тайминга
- Добавлен флаг measurementStarted для правильного управления жизненным циклом
Метод configure() должен быть реализован для установки свойств каналов и их взаимосвязей:
void Module::configure() {
// Настройка входного канала как временного сигнала
// Это необходимо для правильного тайминга в Dewesoft
setInputChannel(0, "TimeSignal", "Time Signal");
// Настройка выходных каналов
setOutputChannel(0, "PyroOneOut", "First Pyro's Output", "V");
setOutputChannel(1, "PyroTwoOut", "Second Pyro's Output", "V");
// Установка свойств выходного канала для цифрового вывода
setOutputChannelProperty(0, "DigitalOutput", "Ctrl DO1");
setOutputChannelProperty(1, "DigitalOutput", "Ctrl DO2");
}
Лучшие практики расчета тайминга
Правильная реализация тайминга критически важна для триггеров цифрового вывода. Модуль C++ Dewesoft работает с двумя подходами к таймингу:
Обработка на основе выборок
Для обработки на основе выборок тайминг должен рассчитываться с использованием временной метки текущей выборки:
void Module::calculate() {
// Получение текущего времени выборки в миллисекундах
double currentTime_ms = getSampleTime(0) * 1000.0; // Преобразование в мс
if (!measurementStarted) {
startTime_ms = currentTime_ms;
measurementStarted = true;
}
double elapsedTime_ms = currentTime_ms - startTime_ms;
// Расчет состояний цифрового вывода
const bool do1_high = (elapsedTime_ms >= t1_ms) &&
(elapsedTime_ms < (t1_ms + width_ms));
const bool do2_high = (elapsedTime_ms >= t2_ms) &&
(elapsedTime_ms < (t2_ms + width_ms));
// Установка значений вывода (1.0 для ВЫСОКИЙ уровень, 0.0 для НИЗКИЙ уровень)
PyroOneOut = do1_high ? 1.0 : 0.0;
PyroTwoOut = do2_high ? 1.0 : 0.0;
// Опционально: сброс тайминга для непрерывной работы
if (elapsedTime_ms > (t2_ms + width_ms + 1000.0)) {
startTime_ms = currentTime_ms;
}
}
Обработка на основе блоков
Для обработки на основе блоков используйте endBlockTime, как указано в руководстве по C++ Script:
void Module::calculate(const Dewesoft::Math::Api::CallInfo& callInfo) {
// Использование времени окончания блока для тайминга
double currentTime_ms = callInfo.endBlockTime * 1000.0;
// ... остальная логика тайминга остается прежней ...
}
Критические соображения по таймингу:
- Всегда используйте внутреннюю систему тайминга Dewesoft, а не внешние источники времени
- Правильно обрабатывайте жизненный цикл измерения с помощью методов start/stop
- Учитывайте режимы непрерывной и однократной работы
- Учитывайте задержки обработки блоков в расчетах тайминга
Настройка каналов и отображение вывода
Правильная настройка каналов необходима для работы триггеров цифрового вывода. Вот пошаговый процесс настройки:
Настройка входного канала
- Добавьте входной канал временного сигнала в настройках Dewesoft
- Сопоставьте этот канал как первый входной канал в вашем модуле C++
- Настройте канал для предоставления эталонного времени
Настройка выходного канала
Согласно обсуждениям на форуме Dewesoft, выходные каналы должны быть правильно сопоставлены с оборудованием:
void Module::configure() {
// ... существующий код ...
// Убедитесь, что выходные каналы сопоставлены с цифровыми выводами
setOutputChannelProperty(0, "HardwareOutput", "DO1");
setOutputChannelProperty(1, "HardwareOutput", "DO2");
// Установка диапазона для цифровых сигналов
setOutputChannelProperty(0, "Range", "0-5V");
setOutputChannelProperty(1, "Range", "0-5V");
}
Настройка триггера цифрового вывода
В руководстве Dewesoft объясняется, что цифровые выводы могут быть настроены с определенными условиями срабатывания:
- Задержка: Время между событием триггера и началом сигнала DO
- Ширина импульса: Длительность выходного импульса
- Логические условия: До 16 аппаратных условий могут быть объединены
Шаги отладки и устранения неполадок
Когда цифровые выводы не срабатывают как ожидается, следуйте этим систематическим шагам отладки:
1. Проверка регистрации модуля
Убедитесь, что ваш модуль правильно зарегистрирован в Dewesoft:
// В инициализации вашего модуля
bsc::MathModule::registerModule("DigitalOutputTrigger",
"Модуль триггера цифрового вывода",
"1.0",
"Название вашей компании");
2. Проверка потокобезопасности
Как подчеркивается в учебных материалах Dewesoft, доступ ко всем каналам должен происходить в методе calculate():
void Module::calculate() {
// Безопасно: весь доступ к каналам здесь
PyroOneOut = 1.0; // Это безопасно
// Небезопасно: вызовет сбой
// someOtherMethod();
// PyroOneOut = 1.0; // Это вызовет сбой
}
3. Мониторинг значений тайминга
Добавьте вывод отладки для проверки расчетов тайминга:
void Module::calculate() {
double currentTime_ms = getSampleTime(0) * 1000.0;
double elapsedTime_ms = currentTime_ms - startTime_ms;
// Вывод отладки (можно просматривать в консоли отладки Dewesoft)
debugOutput("Текущее время: %.2f мс, Прошло: %.2f мс",
currentTime_ms, elapsedTime_ms);
// ... остальная логика ...
}
4. Проверка отображения вывода
Используйте встроенные инструменты Dewesoft для проверки сопоставления выходных каналов:
- Перейдите в Настройка → Каналы → Цифровой вывод
- Убедитесь, что ваши каналы сопоставлены с правильными выводами оборудования
- Проверьте диапазоны напряжений и условия срабатывания
5. Тестирование с упрощенной логикой
Начните с простого теста включения/выключения для изоляции проблемы:
void Module::calculate() {
// Простой тест: всегда выводить 5В на DO1
PyroOneOut = 1.0;
PyroTwoOut = 0.0;
}
Если это работает, постепенно добавляйте сложность, чтобы определить, где логика тайминга дает сбой.
Полный рабочий пример
Вот полный, рабочий реализации системы триггеров цифрового вывода:
#include <chrono>
#include <Dewesoft/Math/Api/Basic.h>
namespace bsc = Dewesoft::Math::Api::Basic;
class DigitalOutputTrigger : public bsc::MathModule {
public:
DigitalOutputTrigger();
~DigitalOutputTrigger();
// Жизненный цикл модуля
void configure() override;
void start() override;
void stop() override;
void clear() override;
void calculate() override;
// Выходные каналы
double PyroOneOut = 0.0; // "Выход первого пиро"
double PyroTwoOut = 0.0; // "Выход второго пиро"
private:
// Параметры тайминга
const double t1_ms = 25.0; // DO1 срабатывает через 25 мс
const double t2_ms = 50.0; // DO2 срабатывает через 50 мс
const double width_ms = 5.0; // ширина импульса
// Состояние тайминга
double startTime_ms = 0.0;
bool measurementStarted = false;
int cycleCount = 0;
};
// Конструктор
DigitalOutputTrigger::DigitalOutputTrigger() {
// Регистрация модуля
bsc::MathModule::registerModule("DigitalOutputTrigger",
"Триггер цифрового вывода",
"1.0",
"Ваша компания");
}
// Деструктор
DigitalOutputTrigger::~DigitalOutputTrigger() {
// Очистка при необходимости
}
void DigitalOutputTrigger::configure() {
// Настройка входного временного сигнала
setInputChannel(0, "TimeSignal", "Time Signal");
// Настройка выходных каналов
setOutputChannel(0, "PyroOneOut", "First Pyro's Output", "V");
setOutputChannel(1, "PyroTwoOut", "Second Pyro's Output", "V");
// Сопоставление с цифровыми выводами
setOutputChannelProperty(0, "DigitalOutput", "Ctrl DO1");
setOutputChannelProperty(1, "DigitalOutput", "Ctrl DO2");
// Установка диапазонов напряжений
setOutputChannelProperty(0, "Range", "0-5V");
setOutputChannelProperty(1, "Range", "0-5V");
}
void DigitalOutputTrigger::start() {
startTime_ms = 0.0;
measurementStarted = false;
cycleCount = 0;
debugOutput("Триггер цифрового вывода запущен");
}
void DigitalOutputTrigger::stop() {
debugOutput("Триггер цифрового вывода остановлен после %d циклов", cycleCount);
}
void DigitalOutputTrigger::clear() {
PyroOneOut = 0.0;
PyroTwoOut = 0.0;
}
void DigitalOutputTrigger::calculate() {
// Получение текущего времени в миллисекундах
double currentTime_ms = getSampleTime(0) * 1000.0;
if (!measurementStarted) {
startTime_ms = currentTime_ms;
measurementStarted = true;
}
double elapsedTime_ms = currentTime_ms - startTime_ms;
// Сброс цикла, если мы завершили один полный период
const double cyclePeriod_ms = t2_ms + width_ms + 1000.0; // 1 секунда между циклами
if (elapsedTime_ms > cyclePeriod_ms) {
startTime_ms = currentTime_ms;
elapsedTime_ms = 0.0;
cycleCount++;
}
// Расчет состояний цифрового вывода
const bool do1_high = (elapsedTime_ms >= t1_ms) &&
(elapsedTime_ms < (t1_ms + width_ms));
const bool do2_high = (elapsedTime_ms >= t2_ms) &&
(elapsedTime_ms < (t2_ms + width_ms));
// Установка значений вывода
PyroOneOut = do1_high ? 5.0 : 0.0; // 5В для ВЫСОКОГО уровня, 0В для НИЗКОГО уровня
PyroTwoOut = do2_high ? 5.0 : 0.0;
// Вывод отладки (можно отключить в продакшене)
if (do1_high || do2_high) {
debugOutput("DO1: %s, DO2: %s в %.2f мс",
do1_high ? "ВЫСОКИЙ" : "НИЗКИЙ",
do2_high ? "ВЫСОКИЙ" : "НИЗКИЙ",
elapsedTime_ms);
}
}
Ключевые особенности этой реализации:
- Правильные объявления методов и управление жизненным циклом
- Надежный расчет тайминга с использованием внутреннего тайминга Dewesoft
- Непрерывная работа с автоматическим сбросом цикла
- Вывод отладки для устранения неполадок
- Правильные уровни напряжения (5В для ВЫСОКОГО уровня, 0В для НИЗКОГО уровня)
- Потокобезопасный доступ к каналам
Расширенные параметры настройки триггеров
Для более сложных требований к срабатыванию Dewesoft предлагает несколько расширенных функций:
Условия аппаратного триггера
Как упоминается в руководстве Dewesoft, вы можете настроить до 16 аппаратных условий:
void Module::configure() {
// ... существующая настройка ...
// Установка условий аппаратного триггера
setOutputChannelProperty(0, "TriggerCondition", "RisingEdge");
setOutputChannelProperty(0, "TriggerDelay", "0");
setOutputChannelProperty(0, "TriggerPulseWidth", "5");
}
Режим синхронного тактового сигнала
Для точного тайминга рассмотрите использование режима поставщика синхронного тактового сигнала, как упоминается в расширенных учебных материалах:
void Module::onPreinitiate() {
// Установка выходного канала в синхронный режим
setOutputChannelProperty(0, "Synchronous", "true");
setOutputChannelProperty(1, "Synchronous", "true");
}
Логика множественных триггеров
В руководстве Dewesoft объясняется, что множественные условия срабатывания используют логику И:
void Module::calculate() {
// Пример множественных условий
bool condition1 = (elapsedTime_ms >= t1_ms) &&
(elapsedTime_ms < (t1_ms + width_ms));
bool condition2 = getSampleTime(1) > 2.5; // Какое-то аналоговое условие
// Оба условия должны быть истинными (логика И)
PyroOneOut = (condition1 && condition2) ? 5.0 : 0.0;
}
Интеграция внешнего триггера
Для систем, требующих внешней синхронизации, вы можете интегрировать внешние триггеры:
void Module::configure() {
// Настройка внешнего входного триггера
setInputChannel(1, "ExternalTrigger", "External Trigger Signal");
// Установка свойств триггера
setInputChannelProperty(1, "TriggerEdge", "Rising");
setInputChannelProperty(1, "TriggerLevel", "2.5");
}
Источники
- Обучение плагину обработки сигналов C++ Dewesoft
- Руководство по C++ Script Dewesoft
- Triggers out RT - Руководство Dewesoft X
- Попытка изучить модуль C++ Dewesoft - Stack Overflow
- Аналоговый вход, триггеры, сигналы тревоги и вывод - Форум Dewesoft
- Расширенная разработка пользовательских плагинов на C++ - Обучение Dewesoft
Заключение
Реализация триггеров цифрового вывода в модуле C++ Dewesoft требует внимания к нескольким ключевым аспектам:
Структура методов и жизненный цикл: Убедитесь, что все требуемые методы (configure(), start(), stop(), clear(), calculate()) правильно объявлены и реализованы. Метод calculate() особенно критичен, так как это единственное потокобезопасное место для доступа к каналам.
Подход к таймингу: Используйте внутреннюю систему тайминга Dewesoft через getSampleTime() или callInfo.endBlockTime, а не внешние источники времени, такие как std::chrono. Это обеспечивает синхронизацию с системой измерения Dewesoft.
Настройка каналов: Правильно настраивайте входные временные сигналы и сопоставляйте выходные каналы с цифровым оборудованием с правильными диапазонами напряжений и свойствами.
Стратегия отладки: Реализуйте вывод отладки для мониторинга значений тайминга и состояний вывода, затем постепенно увеличивайте сложность для изоляции проблем.
Расширенные функции: Для более сложных приложений изучите условия аппаратного триггера, режимы синхронного тактового сигнала и интеграцию внешних триггеров.
Предоставленный полный рабочий пример должен решить проблемы срабатывания, с которыми вы сталкиваетесь. Начните с этой реализации, а затем настройте параметры тайминга и логику в соответствии с вашими конкретными требованиями.