Задать вопрос
  • Откута берется эта белая линия?

    Dyikot
    @Dyikot Автор вопроса
    VoidVolker, ты под квадратами имеешь в виду пиксели? как это реализовать интересно?
  • Откута берется эта белая линия?

    Dyikot
    @Dyikot Автор вопроса
    VoidVolker, не вижу квадратов
    Написано
  • Откута берется эта белая линия?

    Dyikot
    @Dyikot Автор вопроса
    не понял как это исправить
    Написано
  • Можно ли сделать концепт для функции у которой return value auto?

    Dyikot
    @Dyikot Автор вопроса
    Acaunt, надо было в ответ написать
    Написано
  • Можно ли сделать концепт для функции у которой return value auto?

    Dyikot
    @Dyikot Автор вопроса
    Acaunt, я где-то писал что это тип?
    Написано
  • Можно ли узнать типы сигнатуры std::function?

    Dyikot
    @Dyikot Автор вопроса
    Евгений Шатунов, Если что события я делаю чисто под себя, а не для библиотеки и поэтому оставлю std::function для удобства. В любом случае спасибо за уделенное время!
    Написано
  • Можно ли узнать типы сигнатуры std::function?

    Dyikot
    @Dyikot Автор вопроса
    Евгений Шатунов, Ну а как хранить тогда callable объект? Я хочу чтобы событию я передал делегат т.е класс который хранит ссылку на callable объект. Можно конечно передать сигнатуру функции, но я хочу именно делегат. Можно конечно сделать еще одну специализацию.
    Написано
  • Можно ли узнать типы сигнатуры std::function?

    Dyikot
    @Dyikot Автор вопроса
    Евгений Шатунов,
    template<typename TObject, typename TEventArgs>
    class Event<std::function<void(TObject*, const TEventArgs& e)>>

    Так? Как-то не особо вникал в частичную специализацию. Всегда думал что у нее шаблон всегда пустой.
    Написано
  • Можно ли узнать типы сигнатуры std::function?

    Dyikot
    @Dyikot Автор вопроса
    Евгений Шатунов, Пытался улучшить как мог:
    EventHandler

    template<typename TObject, typename TEventArgs> 
    	requires std::derived_from<TEventArgs, EventArgs>
    class EventHandler: public std::function<void(TObject*, const TEventArgs&)>
    {
    public:
    	using Base = std::function<void(TObject*, const TEventArgs&)>;
    	using Object = TObject;
    	using EventArgs = TEventArgs;
    public:
    	EventHandler() = default;
    
    	template<typename TCallable> 
    		requires !std::is_same_v<std::decay_t<TCallable>, EventHandler>
    	EventHandler(TCallable&& handler):
    		Base(std::forward<TCallable>(handler))
    	{}
    
    	EventHandler(const EventHandler& handler):
    		Base(static_cast<const Base&>(handler))
    	{}
    
    	EventHandler(EventHandler&& handler) noexcept:
    		Base(static_cast<Base&&>(handler))
    	{}
    
    	template<typename TCallable> 
    		requires !std::is_same_v<std::decay_t<TCallable>, EventHandler>
    	EventHandler& operator=(TCallable&& handler)
    	{
    		Base::operator=(std::forward<TCallable>(handler));
    		return *this;
    	}
    
    	EventHandler& operator=(const EventHandler& handler)
    	{
    		Base::operator=(static_cast<const Base&>(handler));
    		return *this;
    	}
    
    	EventHandler& operator=(EventHandler&& handler) noexcept
    	{
    		Base::operator=(static_cast<Base&&>(handler));
    		return *this;
    	}
    
    	bool operator==(const EventHandler& eventHandler) const noexcept
    	{
    		return this->target_type() == eventHandler.target_type();
    	}
    
    	bool operator!=(const EventHandler& eventHandler) const noexcept
    	{
    		return !operator==(eventHandler);
    	}
    };


    Event

    template<typename TEventHandler, 
    		 typename TObject = typename TEventHandler::Object,
    		 typename TEventArgs = typename TEventHandler::EventArgs> requires
    	std::is_base_of_v<EventHandler<typename TEventHandler::Object,
    								   typename TEventHandler::EventArgs>, TEventHandler>
    class Event
    {
    public:
    	using EventHanlder = TEventHandler;
    protected:
    	std::forward_list<TEventHandler> _handlers;
    public:
    	void Clear() noexcept { _handlers.clear(); }
    
    	template<typename TCallable> 
    		requires !std::is_same_v<std::decay_t<TCallable>, TEventHandler>
    	void operator+=(TCallable&& callable)
    	{
    		_handlers.emplace_front(std::forward<TCallable>(callable));
    	}
    
    	void operator+=(TEventHandler&& handler)
    	{
    		_handlers.push_front(std::move(handler));
    	}
    
    	void operator+=(const TEventHandler& handler)
    	{
    		_handlers.push_front(handler);
    	}
    
    	template<typename TCallable> 
    		requires !std::is_same_v<std::decay_t<TCallable>, TEventHandler>
    	void operator-=(TCallable&& callable)
    	{
    		_handlers.remove(std::forward<TCallable>(callable));
    	}
    
    	void operator-=(TEventHandler&& handler)
    	{
    		_handlers.remove(std::move(handler));
    	}
    
    	void operator-=(const TEventHandler& handler)
    	{
    		_handlers.remove(handler);
    	}
    
    	operator bool() const noexcept { return !_handlers.empty(); }
    
    	void operator()(TObject* sender, const TEventArgs& e) const
    	{
    		for(const TEventHandler& handler : _handlers)
    		{
    			handler(sender, e);
    		}
    	}
    };


    Все же хочу оставить как шаблон. Если использовать не шаблон, то в качестве делегатов должны быть только нужные классы, т.е уже лямбы отпадают, мне такое не подходит. Сделал так чтобы в качестве аргумента для Event был только EventHandler.
    Написано
  • Можно ли узнать типы сигнатуры std::function?

    Dyikot
    @Dyikot Автор вопроса
    Евгений Шатунов, Вот -
    Event

    template<typename THandler>
    class Event
    {
    protected:
    	std::forward_list<THandler> _handlers;
    public:
    	void operator+=(auto&& handler) 
    	{ 
    		_handlers.emplace_front(std::forward<decltype(handler)>(handler));
    	}
    
    	void operator-=(auto&& handler) 
    	{ 
    		_handlers.remove(std::forward<decltype(handler)>(handler));
    	}
    
    	operator bool() const noexcept
    	{ 
    		return !_handlers.empty();
    	}
    
    	template<typename TObject, typename TEventArgs> requires std::derived_from<TEventArgs, EventArgs>
    	void operator()(TObject* sender, const TEventArgs& e) const
    	{
    		for(const THandler& handler : _handlers)
    		{
    			handler(sender, e);
    		}
    	}
    
    	void Clear() noexcept
    	{ 
    		_handlers.clear(); 
    	}
    };


    Знать конечно не обязательно, можно всегда посмотреть, но хотелось бы если это возможно когда я начинаю писать оператор, и мне высвечивались конкретные типы для данного обработчика. Чтобы бы я не искал как там называется EventArgs для разных событий. Конечно это не критично. Но тут вопрос возможно ли узнать их.
    UPD:
    В общем разобрался как. Сделал отдельный класс:
    template<typename TObject, typename TEventArgs> requires std::derived_from<TEventArgs, EventArgs>
    class EventHandler: public std::function<void(TObject*, const TEventArgs&)>
    {
    public:
    	using ObjectType = TObject;
    	using ArgsType = TEventArgs;
    };

    и теперь в Event так:
    void operator()(THandler::ObjectType* sender, const THandler::ArgsType& e) const
    {
    	for(const THandler& handler : _handlers)
    	{
    		handler(sender, e);
    	}
    }
    Написано
  • Можно ли узнать типы сигнатуры std::function?

    Dyikot
    @Dyikot Автор вопроса
    Через шаблон.
    Написано
  • Можно ли узнать типы сигнатуры std::function?

    Dyikot
    @Dyikot Автор вопроса
    Евгений Шатунов, Хотелось бы видить конкретные для данного события типы аргументов которые требуются передать. В данный момент я вызываю через шаблон.
    template<typename TObject, typename TEventArgs> requires std::derived_from<TEventArgs, EventArgs>
    void operator()(TObject* sender, const TEventArgs& e) const
    {
    	for(const THandler& handler : _handlers)
    	{
    		handler(sender, e);
    	}
    }
    Написано
  • Почему может падать качество преобразования АЦП при повышении частоты сигнала?

    Dyikot
    @Dyikot Автор вопроса
    jcmvbkbc, Нет я дискретизирую на частоте в 4 раза больше, т.е если 100 Гц то будет 400 Гц. Но проблема была в другом. Получается генератор частот получается идеальный(тестрирую в программе) то и наложений более высоких частот нет, но была проблема с ОУ которые сдвигали сигнал и после него там на фротах были проседания.
    Написано
  • Почему может падать качество преобразования АЦП при повышении частоты сигнала?

    Dyikot
    @Dyikot Автор вопроса
    По той же логике и в 100 Гц будут присутсвовать составляющие высоких частот и они же не зависимы от часоты всегда будут там? то почему то при 100 Гц все в пределах 0,5%
    Написано
  • Почему может не заходить в обработчик таймер [STM32]?

    Dyikot
    @Dyikot Автор вопроса
    AiR_WiZArD, Ну т.е второй способо это как вы предложили но еще настроить также таймер 3 на 125 мкс? и вызвывать один раз в main и соответсвенно обратывать после того как буфер будет заполнен в HAL_ADC_ConvCpltCallback. Или не так?
    int main()
    {
        // some code
        HAL_TIM_Base_Start(&htim3);
        HAL_ADC_Start_DMA(&hadc1, &adcValue, DMABufferSize);
        while(1)
        {
            // some code
        }
    }

    А в настройках DMA не надо менять request mode на circular?
    Написано
  • Почему может не заходить в обработчик таймер [STM32]?

    Dyikot
    @Dyikot Автор вопроса
    AiR_WiZArD, Если я частоту повышу в 2(3) раза, то смогу считывать 125 мкс с HAL_TIM_PeriodElapsedCallback или все еще нет?
    Написано
  • Почему может не заходить в обработчик таймер [STM32]?

    Dyikot
    @Dyikot Автор вопроса
    AiR_WiZArD, таймер зачем тут нужен если мы в ручную запускаем преобразование? Мне же нужно как бы регулировать частоту вызовать таймера т.е Prescaler.
    Написано
  • Почему может не заходить в обработчик таймер [STM32]?

    Dyikot
    @Dyikot Автор вопроса
    0)
    Обработчик таймера

    void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
    {
    	if(htim == &htim2)
    	{
    		Display4Digit7Seg_Show(&display, NextDigitPosition());
    	}
    
    	if(htim == &htim3)
    	{
    		HAL_ADC_Start_DMA(&hadc1, &adcValue, DMABufferSize);
    	}
    }

    Тут пока DMABufferSize = 1

    1) так по заданию
    2)
    Инициализация ацп

    static void MX_ADC1_Init(void)
    {
    
      /* USER CODE BEGIN ADC1_Init 0 */
    
      /* USER CODE END ADC1_Init 0 */
    
      ADC_ChannelConfTypeDef sConfig = {0};
    
      /* USER CODE BEGIN ADC1_Init 1 */
    
      /* USER CODE END ADC1_Init 1 */
      /** Common config
      */
      hadc1.Instance = ADC1;
      hadc1.Init.ScanConvMode = ADC_SCAN_DISABLE;
      hadc1.Init.ContinuousConvMode = DISABLE;
      hadc1.Init.DiscontinuousConvMode = DISABLE;
      hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START;
      hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;
      hadc1.Init.NbrOfConversion = 1;
      if (HAL_ADC_Init(&hadc1) != HAL_OK)
      {
        Error_Handler();
      }
      /** Configure Regular Channel
      */
      sConfig.Channel = ADC_CHANNEL_1;
      sConfig.Rank = ADC_REGULAR_RANK_1;
      sConfig.SamplingTime = ADC_SAMPLETIME_1CYCLE_5;
      if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
      {
        Error_Handler();
      }
      /* USER CODE BEGIN ADC1_Init 2 */
    
      /* USER CODE END ADC1_Init 2 */
    
    }


    3)Вызывается обработчик HAL_TIM_PeriodElapsedCallback и просто когда например период < 150 мкс таймер 3 туда почему то не заходит.
    4) На крайний случай.
    5) Ну например выключю его, и типо будет все работать, а потом включю и нек будет.
    6) Согласен, но опять же такое задание(думаю реальных плат нету, либо есть но для всех не хватит).
    8) Надо пробывать.
    Написано
  • Как исправить ошибки вызова обработчика событий в другом потоке?

    Dyikot
    @Dyikot Автор вопроса
    res2001, Возникал еще крайне редкий случай не из-за событий (1 скрин). По итогу сделал thread и conditional_variable как поля в классе. И в декструкторе join.
    Написано
  • Как исправить ошибки вызова обработчика событий в другом потоке?

    Dyikot
    @Dyikot Автор вопроса
    res2001, ну так функция Reset сделает так чтобы он вышел из conditionalVariable. Не понял что еще то? Это задержка нужна тогда когда уже не в conditionalVariable, т.е он уже отсчитал и обработал событие либо в процессе обработки. И это задержка эта гарантие что за это время он обработает его. По сути минимальная задержка 15мс даже если я ставлю 1, и думается мне что не будет таких ситуаций когда событие будет выполняется более 15мс. Можно кончено сделать переменную и ждать завершилась ли обработка события.
    Написано