rsiot/components/cmp_plc/plc/library/timer/
ton.rs

1//! Таймер TON
2
3use serde::{Deserialize, Serialize};
4
5use crate::components::cmp_plc::plc::FbSystemData;
6
7use super::super::super::function_block_base::{FunctionBlockBase, IFunctionBlock};
8use super::super::super::{library::edge_detect::rising_edge, types};
9
10/// Входные данные
11#[derive(Clone, Debug, Default, Deserialize, PartialEq, Serialize)]
12pub struct I {
13    /// Входной сигнал для контроля
14    pub input: bool,
15    /// Задание времени
16    pub preset_time: types::TimeDuration,
17}
18
19/// Выходные данные
20#[derive(Clone, Debug, Default, Deserialize, PartialEq, Serialize)]
21pub struct Q {
22    /// Устанавливается в true, когда таймер насчитал время
23    pub output: bool,
24    /// Время работы таймера
25    pub elapsed_time: types::TimeDuration,
26}
27
28/// Статичные данные
29#[derive(Clone, Debug, Default, Deserialize, PartialEq, Serialize)]
30pub struct S {
31    input_rising_edge: rising_edge::FB,
32    delay: types::TimeInstant,
33}
34
35impl IFunctionBlock<I, Q, S> for FunctionBlockBase<I, Q, S> {
36    fn logic(input: &mut I, stat: &mut S, _system_data: &FbSystemData) -> Q {
37        if stat
38            .input_rising_edge
39            .call(&mut rising_edge::I { i: input.input })
40            .q
41        {
42            stat.delay = types::TimeInstant::now();
43        }
44
45        Q {
46            output: stat.delay.elapsed() >= input.preset_time,
47            elapsed_time: stat.delay.elapsed(),
48        }
49    }
50}
51
52/// Таймер TON
53pub type FB = FunctionBlockBase<I, Q, S>;