Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: MODSERIAL QEI biquadFilter mbed
Fork of Controller by
main.cpp
- Committer:
- rubenlucas
- Date:
- 2018-10-19
- Revision:
- 5:7007230db09c
- Parent:
- 4:0251290a2fc0
- Child:
- 7:d63ec7fe96ae
File content as of revision 5:7007230db09c:
#include "mbed.h" #include "math.h" #include "MODSERIAL.h" #include "QEI.h" #include "BiQuad.h" //Tickers Ticker TickerMeasureAndControl; Ticker TickerPrintToScreen; //Communication MODSERIAL pc(USBTX,USBRX); QEI Encoder(D10,D11,NC,32); //Global pin variables PwmOut PwmPin(D5); DigitalOut DirectionPin(D4); AnalogIn Potmeter1(A1); AnalogIn Potmeter2(A0); //Global variables volatile bool PrintFlag = false; //Global variables for printing on screen volatile float PosRefPrint; // for printing value on screen volatile float PosMotorPrint; // for printing value on screen volatile float ErrorPrint; //----------------------------------------------------------------------------- //The double-functions //Get reference position double GetReferencePosition() { // This function set the reference position to determine the position of the signal. // a positive position is defined as a counterclockwise (CCW) rotation double ValuePot = Potmeter1.read(); // Read value from potmeter (range from 0-1) double PositionRef = 3*6.2830*ValuePot - 3*3.1415; // position reference ranging from -1.5 rotations till 1.5 rotations return PositionRef; //rad } // actual position of the motor double GetActualPosition() { //This function determines the actual position of the motor //The count:radians relation is 8400:2pi double EncoderCounts = Encoder.getPulses(); //number of counts double PositionMotor = EncoderCounts/8400*(2*6.283); // in rad (6.283 = 2pi), 2* is for compensating X4 --> X2 encoding return PositionMotor; } ///The controller double PID_Controller(double Error) { double Ts = 0.01; //Sampling time 100 Hz double Kp = 2; // proportional gain double Ki = 0.85; double Kd = 20*Potmeter2.read(); //integral gain ranging from 0-20. static double ErrorIntegral = 0; static double ErrorPrevious = Error; static BiQuad LowPassFilter(0.0640, 0.1279, 0.0640, -1.1683, 0.4241); //Proportional part: double u_k = Kp * Error; //Integral part: ErrorIntegral = ErrorIntegral + Error*Ts; double u_i = Ki * ErrorIntegral; //Derivative part: double ErrorDerivative = (Error - ErrorPrevious)/Ts; double FilteredErrorDerivative = LowPassFilter.step(ErrorDerivative); double u_d = Kd * FilteredErrorDerivative; ErrorPrevious = Error; // sum of parts and return it return u_k + u_i + u_d; //This will become the MotorValue } //Ticker function set motorvalues void SetMotor(double MotorValue) { if (MotorValue >=0) { DirectionPin = 1; } else { DirectionPin = 0; } if (fabs(MotorValue)>1) // if error more than 1 radian, full duty cycle { PwmPin = 1; } else { PwmPin = fabs(MotorValue); } } // ---------------------------------------------------------------------------- //Ticker function void MeasureAndControl(void) { double PositionRef = GetReferencePosition(); double PositionMotor = GetActualPosition(); double MotorValue = PID_Controller(PositionRef - PositionMotor); // input is error SetMotor(MotorValue); //for printing on screen PosRefPrint = PositionRef; PosMotorPrint = PositionMotor; ErrorPrint = PositionRef - PositionMotor; } void PrintToScreen() { PrintFlag = true; } //----------------------------------------------------------------------------- int main() { pc.baud(115200); pc.printf("Hello World\n\r"); PwmPin.period_us(60); // 16.66667 kHz (default period is too slow!) TickerMeasureAndControl.attach(&MeasureAndControl,0.01); //100 Hz TickerPrintToScreen.attach(&PrintToScreen,0.25); //Every second four times the values on screen while (true) { if(PrintFlag) // if-statement for printing every second four times to screen { double KpPrint = 2; double KiPrint = 0.86; double KdPrint = 20*Potmeter2.read(); pc.printf("Pos ref = %f, Pos motor = %f, Error = %f, Kp = %f, Ki = %f and Kd = %f\r",PosRefPrint,PosMotorPrint,ErrorPrint,KpPrint,KiPrint,KdPrint); PrintFlag = false; } } }