#Region Project Attributes
#AutoFlushLogs: True
#CheckArrayBounds: True
#StackBufferSize: 300
#End Region
Sub Process_Globals
Public Serial1 As Serial
Dim t As Timer
Dim kp, ki, kd As Double
Dim integral As Double
Dim cont As CONTROLLINO
Dim setpotpin, feedbackpin, outputpin, additionaloutputpin As Pin
Dim A As Long = 1000
Dim B As Int = 15
Dim Rc As Int = 10
Dim input, setpoint, output As Double
Dim feedbackval As Float
Dim outputMin, outputMax As Double
Dim threshold As Double = 3
Dim atSetpoint, isStopped As Boolean
End Sub
Private Sub AppStart
Serial1.Initialize(115200)
Log("AppStart")
integral = 0
outputMin = 0
outputMax = 255
setpotpin.Initialize(cont.CONTROLLINO_A1, setpotpin.MODE_INPUT)
feedbackpin.Initialize(cont.CONTROLLINO_A0, feedbackpin.MODE_INPUT)
outputpin.Initialize(cont.CONTROLLINO_D0, outputpin.MODE_OUTPUT)
additionaloutputpin.Initialize(cont.CONTROLLINO_D1, additionaloutputpin.MODE_OUTPUT)
t.Initialize("t_tick", 20)
kp = 0.4
ki = 6.0
kd = 0.0001
RunNative("setup", Null)
RunNative("setOutputRange", Null)
RunNative("setGains", Array(kp, ki, kd))
t.Enabled = True
End Sub
Sub t_tick
setpoint = setpotpin.AnalogRead/4
feedbackval = readFeedback
RunNative("loop", Null)
RunNative("getIntegral", Null)
If integral > 60 Then
RunNative("setIntegral", 60)
else if integral < 0 Then
RunNative("setIntegral", 0)
End If
Log("Setpoint = ", setpoint)
Log("Feedback = ", feedbackval)
Log("Output = ", output)
Log("integral = ", integral)
RunNative("atSetPoint", threshold)
Log("atSetPoint = ", atSetpoint)
RunNative("isStopped", Null)
Log("isStopped = ", isStopped)
Log(" ")
outputpin.AnalogWrite(output)
additionaloutputpin.AnalogWrite(output)
End Sub
Sub readFeedback As Float
Dim mean As Float = 0
Dim V As Float
For i = 0 To 99
V = feedbackpin.AnalogRead
mean = mean + (V * A * 10) / (B * Rc * (1024 - V))
Next
mean = (mean / 100)
Return mean
End Sub
#If C
#include <AutoPID.h>
#define FEEDBACK_READ_DELAY 10 //
//pid settings and gains
#define OUTPUT_MIN 0
#define OUTPUT_MAX 0
#define KP 0.0
#define KI 0.0
#define KD 0.0
double feedback, setPoint, outputVal;
//input/output variables passed by reference, so they are updated automatically
AutoPID myPID(&feedback, &setPoint, &outputVal, OUTPUT_MIN, OUTPUT_MAX, KP, KI, KD);
unsigned long lastFeedbackUpdate; //tracks clock time of last feedback update
bool updateFeedback() {
if ((millis() - lastFeedbackUpdate) > FEEDBACK_READ_DELAY) {
feedback = b4r_main::_feedbackval; //get feedback reading
lastFeedbackUpdate = millis();
feedback = b4r_main::_feedbackval; //get feedback reading //request reading for next time
return true;
}
return false;
}
void loop(B4R::Object* o) {
updateFeedback();
setPoint = b4r_main::_setpoint;
myPID.run(); //call every loop, updates automatically at certain time interval
b4r_main::_output = outputVal;
}
void setup(B4R::Object* o) {
myPID.setTimeStep(50); //updates automatically at certain time interval
}
void setGains(B4R::Object* o) {
myPID.setGains(b4r_main::_kp, b4r_main::_ki, b4r_main::_kd);
}
void getIntegral(B4R::Object* o) {
b4r_main::_integral = myPID.getIntegral();
}
void setIntegral(B4R::Object* o) {
myPID.setIntegral(o->toDouble());
}
void setOutputRange(B4R::Object* o) {
myPID.setOutputRange(b4r_main::_outputmin, b4r_main::_outputmax);
}
void atSetPoint(B4R::Object* o) {
boolean asp = myPID.atSetPoint(o->toDouble());
b4r_main::_atsetpoint = asp;
}
void stop(B4R::Object* o) {
myPID.stop();
}
void reset(B4R::Object* o) {
myPID.reset();
}
void isStopped(B4R::Object* o) {
boolean isStopped = myPID.isStopped();
b4r_main::_isstopped = isStopped;
}
#End If