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: mbed QEI HIDScope biquadFilter MODSERIAL FastPWM
main.cpp
- Committer:
- paulstuiver
- Date:
- 2019-10-11
- Revision:
- 7:08fd3bc7a3cf
- Parent:
- 6:ea3b3f50c893
- Child:
- 11:ca91fc47ad02
File content as of revision 7:08fd3bc7a3cf:
#include "mbed.h"
#include "MODSERIAL.h"
#include "FastPWM.h"
#include "QEI.h"
#include <math.h>
#include "BiQuad.h"
DigitalIn button1(D12);
AnalogIn pot2(A0);
AnalogIn pot1(A1);
Ticker motor; //ticker to call motor values
DigitalOut motor1Direction(D7); // is a boolean
FastPWM motor1absolutemotorvalueocity(D6);
MODSERIAL pc(USBTX, USBRX);
QEI Encoder(D8,D9,NC,8400);
volatile double frequency = 17000.0;
volatile double period_signal = 1.0/frequency;
float timeinterval = 0.001f;
int counts;
float measuredposition;
float motorvalue;
double u_i;
float potmeter1 = pot1.read();
// -------------------- README ------------------------------------
// positive referenceposition corresponds to a counterclockwise motion
// negative referenceposition corresponds to a clockwise motion
//PID control implementation (BiQuead)
double PID_controller(double error)
{
static double error_integral = 0;
static double error_prev = error;
static BiQuad LowPassFilter(0.0640, 0.1279, 0.0640, -1.1683, 0.4241);
double Kp = pot1.read()*10;
double Ki = 0.1;
double Kd = 0.1;
//Proportional part:
double u_k = Kp * error;
// Integreal part
error_integral = error_integral + error * timeinterval;
double u_i = Ki*error_integral;
// anti wind up
if (u_i > 10)
{
u_i = 10 ;
}
// Derivate part
double error_derivative = (error - error_prev)/timeinterval;
double filtered_error_derivative = LowPassFilter.step(error_derivative);
double u_d = Kd * filtered_error_derivative;
error_prev = error;
//sum all parts and return it
return u_k + u_i + u_d;
}
//get the measured position
double getmeasuredposition()
{
counts = Encoder.getPulses();
measuredposition = ((float)counts) / 8400.0f * 2.0f;
return measuredposition;
}
//get the reference of the absolutemotorvalueocity
double getreferenceposition()
{
float referenceposition;
referenceposition = -1+2*pot2.read(); //this determines the amount of spins
return referenceposition;
}
//send value to motor
void sendtomotor(float motorvalue)
{
float absolutemotorvalue = 0.0f;
absolutemotorvalue = fabs(motorvalue);
absolutemotorvalue = absolutemotorvalue > 1.0f ? 1.0f : absolutemotorvalue; //if absolutemotorvalueocity is greater than 1, reduce to 1, otherwise remain absolutemotorvalue
motor1absolutemotorvalueocity = absolutemotorvalue;
motor1Direction = (motorvalue > 0.0f); //boolean output: true gives counterclockwise direction, false gives clockwise direction
}
// function to call reference absolutemotorvalueocity, measured absolutemotorvalueocity and controls motor with feedback
void measureandcontrol(void)
{
float referenceposition = getreferenceposition();
measuredposition = getmeasuredposition();
motorvalue = PID_controller(referenceposition - measuredposition);
sendtomotor(motorvalue);
}
int main()
{
pc.baud(115200);
pc.printf("Starting...\r\n");
motor1absolutemotorvalueocity.period(period_signal);
motor.attach(measureandcontrol, timeinterval);
while(true)
{
wait(0.5);
pc.printf("number of counts %i\r\n", counts);
pc.printf("measured position is %f\r\n", measuredposition);
pc.printf("motorvalue is %f\r\n", motorvalue);
pc.printf("u_i is %d\r\n", u_i);
pc.printf("potmeter 1 gives %f\r\n", potmeter1);
char c = pc.getcNb();
// type c to stop the program
if (c == 'c')
{
pc.printf("Program stopped running");
motorvalue = 0;
sendtomotor(motorvalue);
break;
}
}
}