Skip to main content

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

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