MOtor control Pololu
Dependencies: Encoder HIDScope mbed-dsp mbed
main.cpp
- Committer:
- vsluiter
- Date:
- 2014-09-29
- Revision:
- 4:1a53b06eeb7f
- Parent:
- 2:5f5b229b004d
- Child:
- 5:06381e54b94a
File content as of revision 4:1a53b06eeb7f:
#include "mbed.h" #include "encoder.h" #include "MODSERIAL.h" #define K_P .01 //0.007//0.0184997836671646 //0.015 #define K_I 0.00 //.000824387821287097 //0 #define K_D .05 //0.01//.0972091946803081 //0.077 #define POT_AVG 50 void coerce(float * in, float min, float max); float pid(float setpoint, float measurement); AnalogIn potmeter(PTC2); volatile bool looptimerflag; float potsamples[POT_AVG]; void setlooptimerflag(void) { looptimerflag = true; } void potAverager(void) { static uint16_t sample_index = 0; float voltage = potmeter.read()-.5; potsamples[sample_index] = voltage; sample_index++; if(sample_index >= POT_AVG) sample_index = 0; } void bubblesort(float arr[], int size) { int i,j; float temp; for ( i = 0 ; i <= (size/2)+1 ; i++ ) { for ( j = 0 ; j <= (size/2)+1 - i ; j++ ) { if ( arr[j] > arr[j + 1] ) { temp = arr[j] ; arr[j] = arr[j + 1] ; arr[j + 1] = temp ; } } } } void quicksort(float own_array[], int low, int high) { int i = low; int j = high; int y = 0; /* compare value */ int z = own_array[(low + high) / 2]; /* partition */ do { /* find member above ... */ while(own_array[i] < z) i++; /* find element below ... */ while(own_array[j] > z) j--; if(i <= j) { /* swap two elements */ y = own_array[i]; own_array[i] = own_array[j]; own_array[j] = y; i++; j--; } } while(i <= j); /* recurse */ if(low <= j) quicksort(own_array, low, j); if(i <= high) quicksort(own_array, i, high); } float getpotAverage(void) { //float own_array[POT_AVG]; //memcpy(own_array, potsamples, sizeof(own_array)); //bubblesort(own_array, POT_AVG-1); //return own_array[POT_AVG/2]; uint16_t valuecounter; float sum = 0; for(valuecounter = 0 ; valuecounter < POT_AVG ; valuecounter++) { sum += potsamples[valuecounter]; } return sum / (POT_AVG*1.); } int main() { Encoder motor1(PTD0,PTC9); Ticker potaverage; MODSERIAL pc(USBTX,USBRX); PwmOut pwm_motor(PTA12); DigitalOut motordir(PTD3); potaverage.attach(potAverager,0.002); pc.baud(921600); Ticker looptimer; looptimer.attach(setlooptimerflag,0.01); pc.printf("bla"); while(1) { float setpoint; float new_pwm; while(!looptimerflag); looptimerflag = false; setpoint = (getpotAverage())*2000; //new_pwm = (setpoint - motor1.getPosition())*.001; new_pwm = pid(setpoint, motor1.getPosition()); coerce(&new_pwm, -1,1); pc.printf("%f %f %f 0\n", setpoint/2000.+0.5, motor1.getPosition()/2000.+.5,new_pwm/2.+0.5); if(new_pwm > 0) motordir = 1; else motordir = 0; pwm_motor.write(abs(new_pwm)); } } //coerces value 'in' to min or max when exceeding those values //if you'd like to understand the statement below take a google for //'ternary operators'. void coerce(float * in, float min, float max) { *in > min ? *in < max? : *in = max: *in = min; } float pid(float setpoint, float measurement) { float error; static float prev_error = 0; float out_p = 0; static float out_i = 0; float out_d = 0; error = setpoint-measurement; out_p = error*K_P; out_i += error*K_I; out_d = (error-prev_error)*K_D; coerce(&out_i,-0.5,0.5); prev_error = error; return out_p + out_i + out_d; }