SSR Control with Pulse cmd -> help needed

Moderators: grovkillen, Stuntteam, TD-er

Post Reply
Message
Author
SawaX
Normal user
Posts: 4
Joined: 29 Apr 2021, 16:01

SSR Control with Pulse cmd -> help needed

#1 Post by SawaX » 29 Apr 2021, 16:20

Hello,

I have a small issue... I am working on PID controller implementation with SSR output.
I made a plugin to let the magic happens... the only thing I can't pass is the pulse command.
I want to run this command inside code, after PID calculations.

my idea is:
input -> PID -> SRR on for 0-1000 ms dependent from PID output.

Is there any way to implement pulse event?

Regards

TD-er
Core team member
Posts: 4932
Joined: 01 Sep 2017, 22:13
Location: the Netherlands
Contact:

Re: SSR Control with Pulse cmd -> help needed

#2 Post by TD-er » 29 Apr 2021, 16:30

What do you mean by "pulse events" ?
Sending out a single pulse of set duration?
You can output a longpulse_ms from the rules. See: https://espeasy.readthedocs.io/en/lates ... ernal-gpio

If you like to measure a pulse, you can use the pulse plugin, but I am not entirely sure if that's the most responsive one to act on an incoming pulse.
Or you try to monitor a pin, but then the measured duration may be unstable as it is handled by events to be processed in the rules.

Also keep in mind that almost all solid state relays are made for AC, so they only switch during a zero-crossing of the mains voltage.
Meaning you can only switch in descrete steps of 20 msec (in 50 Hz areas)

SawaX
Normal user
Posts: 4
Joined: 29 Apr 2021, 16:01

Re: SSR Control with Pulse cmd -> help needed

#3 Post by SawaX » 29 Apr 2021, 22:29

Ok, I will start from the beginning... I have two similar projects -> both of them are based on:

-Wemos d1 mini pro,
-2 x db18s20,
-2 x SSR,
-2kW Heating element
-1kW Heating element.

Both are designed more or less for the same target -> precise temperature control (but in different environments).

I tested the normal level regulator with hysteresis 0.1 and 0... but because of the thermal inertia of the heater and poorly isolated environment, I am getting -4/+4 °C... which is not acceptable :)

I decided to make my own plugin based on the Arduino PID library, with temporary, test code below:

Code: Select all

    case PLUGIN_ONCE_A_SECOND:
      {
        // we're checking a var from another task, so calculate that basevar
        taskIndex_t TaskIndex = PCONFIG(0);
        byte BaseVarIndex = TaskIndex * VARS_PER_TASK + PCONFIG(1);
       
        // load var
        float SetPoint = PCONFIG_FLOAT(0);
        float kP = PCONFIG_FLOAT(1);
        float kI = PCONFIG_FLOAT(2);
        float kD = PCONFIG_FLOAT(3);
        
        float Input = UserVar[BaseVarIndex] / SetPoint;
        float lastInput = PCONFIG_FLOAT(4);
        float Error = 1 - Input;
        float dInput = Input - lastInput;
    
        float outputSum = PCONFIG_FLOAT(5) + (kI * Error);
        boolean pOnE = PCONFIG(2);
        
        if(!pOnE) outputSum -= kP * dInput;

        if(outputSum > 1) outputSum = 1;
        else if(outputSum < 1) outputSum = 0;

        float PID = 0;
        if(pOnE) PID += kP * Error;

        PID += outputSum - kD * dInput;

        if(PID > 1) PID = 1;
        else if(PID < 1) PID = 0;

        float TimeNow = millis();
        float TimeDiff = TimeNow - PCONFIG_FLOAT(6);
           
        PCONFIG_FLOAT(4) = Input;
        PCONFIG_FLOAT(5) = outputSum; 
        PCONFIG_FLOAT(6) = TimeNow;
        
        UserVar[event->BaseVarIndex] = PID;
        UserVar[event->BaseVarIndex + 1] = PID * 1000;
        UserVar[event->BaseVarIndex + 2] = Input;
        UserVar[event->BaseVarIndex + 3] = TimeDiff;  //----------> here i am getting 970-1010 ms which is perfect.
        
        //--------------------------------------------------------------------> here i want to trigger sth like Pulse,2,0,PID*1000 on SSR
        
        sendData(event);
        
        success = true;
        break;
      }
now, If I put sth like this in rules:

Code: Select all

 
       on PID_C#event do
              Pulse,2,0,[PID_C#SSR_ms] //-->only for test purpose... internal led
              TaskValueSet,2,3,[Dummy#Time] //copy previous %unixtime%
              TaskValueSet,2,2,%unixtime%   //store new %unixtime%
       endon
If there are any mistakes -> sorry, I wrote rules out of my head...

anyway, I am getting the difference around 2-3s... I can see it also on the internal LED.

Or maybe I am doing it wrong... could be also...

I know that SSR has some limitations but in that case should be sufficient. otherwise I can make SCR regulator with zero cross detection :lol: but I wanted to avoid that :D

TD-er
Core team member
Posts: 4932
Joined: 01 Sep 2017, 22:13
Location: the Netherlands
Contact:

Re: SSR Control with Pulse cmd -> help needed

#4 Post by TD-er » 30 Apr 2021, 00:16

First of all, you should use the pulse command with the "_ms" postfix to be able to use sub-second precision.
Second, you should use the long_pulse command to make sure the unit is not blocking (in your use case: longpulse_ms)

As is stated in the documentation the "pulse" is blocking code, so it prevents further execution of any other code until it is finished.
A longpulse (and thus also longpulse_ms) will just start the pulse and schedule an internal action to stop the pulse.
This also means the longpulse/longpulse_ms command will immediately return in the rules processing, while the "pulse" command only continues execution after the pulse is finished.

This blocking is more than just the rules execution, as it blocks everything (!!!), even handling your plugin calls like "PLUGIN_FIFTY_PER_SECOND" etc.
The only thing that may not be blocked is the registration of an interrupt attached to a GPIO pin. But unless you keep some statistics in handling those interrupts, you may loose pulse counts, pulse duration, etc.

Oh and another thing... you should look at the event values of an event, not at the task values.
Events are scheduled, so by the time you test a task value (format [taskname#varname] ) the content may have changed.

SawaX
Normal user
Posts: 4
Joined: 29 Apr 2021, 16:01

Re: SSR Control with Pulse cmd -> help needed

#5 Post by SawaX » 03 May 2021, 08:25

sorry, I was out of reach for a couple of days...

Indeed, longpulse_ms make a job. I didn't read the documentation carefully... Thx for the help!

TD-er
Core team member
Posts: 4932
Joined: 01 Sep 2017, 22:13
Location: the Netherlands
Contact:

Re: SSR Control with Pulse cmd -> help needed

#6 Post by TD-er » 03 May 2021, 10:42

You're welcome and have fun with it :)

SawaX
Normal user
Posts: 4
Joined: 29 Apr 2021, 16:01

Re: SSR Control with Pulse cmd -> help needed

#7 Post by SawaX » 06 May 2021, 13:24

I found another issue... I am not sure how to solve it, probably my stupid mistake... :D

I made PID plugin with data struct...

If I add one device -> no issues...
but when I am trying to use two PID devices, Free RAM is running to 0 in a couple of minutes which leads to device reset. I would like to avoid it XD

If someone has some more knowledge than I have + some free time and can take a look at my code, It would be great...

1.png
1.png (59.95 KiB) Viewed 1366 times
2.png
2.png (21.17 KiB) Viewed 1366 times
Attachments
_P220_PID.zip
(2.92 KiB) Downloaded 27 times

TD-er
Core team member
Posts: 4932
Joined: 01 Sep 2017, 22:13
Location: the Netherlands
Contact:

Re: SSR Control with Pulse cmd -> help needed

#8 Post by TD-er » 06 May 2021, 17:28

In PLUGIN_ONCE_A_SECOND you may also want to check if BaseVarIndex is valid (checking if TaskIndex is valid may be a good start)

Also you should really check P220_data isn't a nullptr before dereferencing it.

Calling sendData will call the controllers to send data to their configured endpoints.
Maybe there is something wrong?

You also use the PLUGIN_SET_CONFIG, which does call to save the settings.
How often do you call it?
This may destroy your flash in no-time and you will also hit the max. 100 writes per day.

Post Reply

Who is online

Users browsing this forum: No registered users and 28 guests