Overview
In this tutorial, we will create a control using a hysteresis-based approach to manage temperature. Hysteresis control is often used in systems that need to prevent rapid switching and stabilize a control variable around a set point. We will configure this control to activate or deactivate an output based on fixed temperature thresholds, creating a stable temperature range.
The objectives of this tutorial are to:
- Explain the concept of hysteresis control.
- Define the control class for basic hysteresis temperature management.
- Implement the hysteresis logic to control an output based on fixed temperature thresholds.
What is Hysteresis Temperature Control?
Hysteresis control is a method of managing a system output based on an upper and lower threshold. In temperature control, hysteresis helps maintain a target temperature range without frequent on-off cycles, which can lead to instability and wear on equipment.
For example, in a heating system, the heater may turn on when the temperature drops below a lower threshold and turn off when the temperature exceeds an upper threshold. The gap between the two thresholds prevents the system from rapidly switching, allowing the temperature to fluctuate within a stable range.
Step 1: Define the Hysteresis Temperature Control Class
In this control class, we will define one xentara::Float64Input for the temperature input and one xentara::BooleanOutput for the heater state output. We will also include fixed configuration parameters for the upper and lower thresholds.
Here is the code for SimpleHysteresisTempControl.hpp:
#pragma once
#include <xentara/cpp-control.h>
{
public:
private:
xentara::Float64Input temperatureInput;
xentara::BooleanOutput heaterState;
double lowerThreshold {0.0};
double upperThreshold {0.0};
};
An interface class which provides declaration of all the callbacks for this control.
Definition Control.hpp:19
virtual auto initialize(InitContext &context) -> void=0
Callback that is called by the framework to initialize the control object.
virtual auto step(RunContext &context) -> void=0
Main callback responsible for executing the core control logic.
An initialization context with configuration information and access to Xentara Elements.
Definition InitContext.hpp:35
An run context with execution information and is required for the read and write for Input and Output...
Definition RunContext.hpp:46
Step 2: JSON Configuration for Inputs, Outputs, and Thresholds
The following JSON configuration file sets up the data points for the temperature input and heater state output, as well as the parameters for the lower and upper thresholds.
{
"children": [
{
"@Skill.CPP.Control": {
"name": "Simple Hysteresis Temperature Control",
"UUID": "bbbe9b21-602e-4ac7-bd7a-e09d80cf0957",
"controlPath": "libsimple-hysteresis-temperature-control.so",
"parameters": {
"lowerThreshold": 18.0,
"upperThreshold": 22.0,
"temperatureInput": "Temperature Input",
"heaterState": "Heater State"
}
}
},
{
"@Skill.SignalFlow.Register": {
"name": "Temperature Input",
"UUID": "c2e17c47-90ab-4aac-a24d-98e9d6ed80df",
"defaultValue": [ "float64", 20.0 ]
}
},
{
"@Skill.SignalFlow.Register": {
"name": "Heater State",
"UUID": "fd032506-6db5-4cc6-a8e5-c9b3229ef158",
"defaultValue": [ "bool", false ]
}
},
{
"@Track": {
"name": "Control Track",
"UUID": "fb0a26f8-7d84-4af9-9345-4145263d09c7",
"children": [
{
"@Timer": {
"name": "Timer",
"UUID": "e6580c24-dbf9-43a0-aa81-c5ed8da6f734",
"period": "50ms"
}
},
{
"@Pipeline": {
"name": "Pipeline",
"UUID": "040f156e-2744-4008-8195-cd7f17078668",
"triggers": [
"Control Track.Timer.expired"
],
"checkpoints": [
{},
{}
],
"segments": [
{
"start": 0,
"end": 1,
"tasks": [
{
"function": "Simple Hysteresis Temperature Control.step"
}
]
}
]
}
}
]
}
}
]
}
In this configuration:
Temperature Input is the input data point representing the current temperature.
Heater State is the output data point indicating the heater on/off status.
- The control parameters include
lowerThreshold and upperThreshold to specify the temperature range.
- Note
- In this example, the
@Skill.SignalFlow.Register skill is used for simplicity. However, other skills should be used to connect to the sensors depending on the specific hardware and protocols in use. For instance, skills such as EtherCAT, Modbus, or OPC UA could be used to interact with real-world temperature sensors. The choice of skill depends on the communication protocol supported by the device.
Step 3: Implement the Hysteresis Control Logic
In SimpleHysteresisTempControl.cpp, we will initialize the input and output data points and configure the hysteresis thresholds in the initialize method. The step function will check the temperature against the thresholds and turn the heater on or off accordingly.
Here is the code for SimpleHysteresisTempControl.cpp:
#include "SimpleHysteresisTempControl.hpp"
{
temperatureInput = context.
config().getDataPoint(
"temperatureInput");
heaterState = context.
config().getDataPoint(
"heaterState");
lowerThreshold = context.
config().getDouble(
"lowerThreshold");
upperThreshold = context.
config().getDouble(
"upperThreshold");
}
{
auto currentTemperature = temperatureInput.read(context);
if (currentTemperature < lowerThreshold)
{
heaterState.write(context, true);
}
else if (currentTemperature > upperThreshold)
{
heaterState.write(context, false);
}
else
{
}
}
A class used to export your control class with Xentara.
Definition ControlExporter.hpp:38
auto config() const -> const Config &
Gets the configuration.
Conclusion
In this tutorial, we implemented a basic hysteresis temperature control. This control reads a temperature input and, based on fixed thresholds, turns a heater on or off to maintain a stable temperature range. This setup provides a simple yet effective method to stabilize temperature in systems requiring consistent management within defined limits.