-1

I'm trying to develop a package/module in golang which will work similar to a PLC function block.

The main difference between PLC function and function block involves internal memory. So for instance, a function can be described as something like an equation or formula that accepts inputs and calculates an output value. Moreover, it always returns the same output value for the same inputs. In contrast, a function block relies on internal memory. So it is possible to have a different output value with the same inputs because there is another value stored in memory that has an impact on the final output value.

Are there any ways to achieve this in golang?

For example, I want to create a timer block (TON) with inputs IN (bool-start timer), PT (int64-set duration of the timer) and output Q (bool-is the set duration reached), ET (int64-elapsed time) The way it should work is, this method will be called in an infinite loop and must retain it's last state and do it's job!

TON FB: https://help.codesys.com/webapp/ton;product=codesys;version=3.5.11.0

  • 1
    If I understand correctly, you're asking how to write stateful code in Golang. Struct fields, package variables, and closures are some ways to do this in the memory of your application. However if you want state to persist between executions of your application, you'll need to save it somewhere outside of application memory (e.g. in a file on disk). Also, please note that statefulness (at least in the application's memory) can lead to thread safety problems - so I hope you know what you are doing. – phonaputer May 23 '23 at 05:26
  • Write a function closure. Like this you can enclose some memory into the function. – Volker May 23 '23 at 08:07

1 Answers1

0

This is a simple isolated example that replicates the TON functionality of a PLC using struct:

package main

import (
    "fmt"
)

type TON struct {
    on bool
    PT int
    ET int
    Q  bool
}

func (t *TON) IN(execute bool) {
    t.on = execute
    if !execute {
        t.Q = false
        t.ET = 0
    }
}

// call this method "cyclically"
func (t *TON) run() {
    if t.on {
        t.ET = t.ET + 1
    }
    if t.ET == t.PT {
        t.Q = true
    }
}

func main() {
    t := TON{
        on: false,
        PT: 9,
        ET: 0,
        Q:  false,
    }
    t.run()
    t.IN(true)
    i := 0
    for i < 10 {
        i += 1
        t.run()
        fmt.Printf("Q = %t, ET = %d \n", t.Q, t.ET)
    }
}
chrisbeardy
  • 114
  • 5