2

I have a PID controller working in simulink, but I want to pass it to C++ code. I found how to make a PID with code, something like this:

error = input - refeed;
iError += error * sampleTime;
dError = (error - lastError)/ sampleTime;
//PID Function
output = Kp * error + Ki * iError + Kd * dError;
refeed = output;
lastError = error;

But, that's the only clear thing I got in my research.

I need to know what's the next step, I have the transfer function discretized but I'm not sure about what should I do with the "z" parameters, the times, ...

Is it possible to pass manually a PID controller to C++? How?

marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
Sik
  • 41
  • 1
  • 1
  • 4

4 Answers4

2

The Temperature Control Lab passes a PID output from Python to an Arduino that runs C++ code through a serial USB interface. It is easier to plot values with Python than C++ if you can create an interface for your application. GitHub source code is here.

Test PID Control

John Hedengren
  • 12,068
  • 1
  • 21
  • 25
  • If you need to add a discrete time transfer function model to compare with then PID response you can use a time series model where each z^-1, z^-2, z^-3, etc is the number of time steps back for that variable. https://apmonitor.com/wiki/index.php/Apps/ARXTimeSeries – John Hedengren Nov 04 '19 at 12:24
1

For the digital control systems, you need to sample the data and execute the controller at every sampling time. z-transform converts the continuous system to the discrete system.
For exampl, if your sampling time is '1', you can express a simple time-series model as below,

y(t) = a1*u(t-1) + a2*u(t-2)
--> y(t) = a1*z^-1*u(t) + a2*z^-2*u(t)
--> y(t) = A(z)u(t), where A(z) = a1*z^-1 + a2*z^-2
a1, a2 = FIR coefficients

However, this time-shift operator 'z^-1' does not appear in your code. It is implicitly expressed with your sampling-time and FOR or DO loop depending on the language that you are using. Please see the python code for velocity form of PID controller. Velocity form is a little bit easier to implement because you don't worry about the additional logic for the anti-reset windup.

for i in range(1, ns):  #ns = simulation time
    # PID Velocity form
    e[i] = sp[i] - pv[i]
    P[i] = Kc * (e[i] - e[i-1])
    I[i] = Kc*delta_t/tauI * (e[i])
    D[i] = Kc*tauD/delta_t * (pv[i] - 2*(pv[i-1]) + pv[i-2])
    op[i] = op[i-1] + P[i] + I[i] + D[i]
    if op[i] < oplo or op[i] > ophi:
        # clip output
        op[i] = max(oplo,min(ophi,op[i]))

You can also find an example of a PID controller using a GEKKO package in the following link.

https://apmonitor.com/wiki/index.php/Main/GekkoPythonOptimization

Junho Park
  • 997
  • 4
  • 12
0

Yes it is possible. Have you considered using someone else's code? Or do you want to write it yourself? If you have no problem using allready written code, check out Github. It has a lot of PID projects. For example PID-controller. It has a usage example and you only have to pass in your p, i and d parameters (which you allready got from Matlab).

Good luck!

MartijnKor
  • 82
  • 1
  • 9
  • I checked the link you passed me and it's similar to my code. But what I want is something like the output graph that you can obtain in Matlab when compiling a PID with a transfer function, an example of the values ​​of the output as time progresses. But thank you for your time! – Sik Apr 27 '18 at 07:38
  • Sure no problem! I guess you could find a library to make a graph then right? I think Boost has a graph library but I have never used it. – MartijnKor May 01 '18 at 16:58
0

Basically, you should send the values somewhere. Reading through the comments, you want to make a plot of the output variable in time, so I guess your best bet (and easier way) is to use gnuplot.

Basically, output the data in a text file, then use gnuplot to display it.

HappyCactus
  • 1,935
  • 16
  • 24