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:
- Sven_van_Wincoop
- Date:
- 2018-10-26
- Revision:
- 8:0ed8609252d3
- Parent:
- 7:d63ec7fe96ae
- Child:
- 9:34e3dd8548c0
File content as of revision 8:0ed8609252d3:
#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);
DigitalIn BUT1(D8);
DigitalIn BUT2(D9);
DigitalIn button(SW2);
//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
static double PositionRef = 0;
if (button)
{
if (BUT2 == false)
{
if (PositionRef <= 0.4*(6.2830))
{
PositionRef += 0.0005*(6.2830);
}
}
if (BUT1 == false)
{
if (PositionRef >= -0.4*(6.2830))
{
PositionRef -= 0.0005*(6.2830);
}
}
}
else
{
if (PositionRef <= 0)
{
PositionRef += 0.0005*(6.2830);
}
if (PositionRef >= 0)
{
PositionRef -= 0.0005*(6.2830);
}
}
// double ValuePot = Potmeter1.read(); // Read value from potmeter (range from 0-1)
//double PositionRef = 0.8*6.2830*ValuePot - 0.8*3.1415; // position reference ranging from -0.4 rotations till 0.4 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 = 3.7; // proportional gain
double Ki = 5;
double Kd = 2.8; //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.002); //500 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 = 3.52;
double KiPrint = 0.88;
double KdPrint = 6.9;
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;
}
}
}
