![](/media/cache/img/default_profile.jpg.50x50_q85.jpg)
For flywheel rig. Interfaces with matlab flywheel interface. 2.007 MIT Biomimetics Robotics Lab. Sangbae Kim. Ben Katz.
Revision 12:f9f08c7551f4, committed 2017-04-14
- Comitter:
- abraham1
- Date:
- Fri Apr 14 18:06:13 2017 +0000
- Parent:
- 11:ad41446b0edb
- Commit message:
- Commented code;
Changed in this revision
main.cpp | Show annotated file Show diff for this revision Revisions of this file |
diff -r ad41446b0edb -r f9f08c7551f4 main.cpp --- a/main.cpp Fri Apr 14 17:35:05 2017 +0000 +++ b/main.cpp Fri Apr 14 18:06:13 2017 +0000 @@ -1,5 +1,7 @@ ///setup code for encoder on pins PA0 and PA1 (A0 and A1)/// +// TODO: explain basic flow of run and data collection + #include "mbed.h" #include "time.h" #include "stdio.h" @@ -7,20 +9,31 @@ #define PI 3.14159265358979323846 +//Just for basic debugging +//User button controls motor speed +//Green LED should turn on while listening to pc for input before starting run InterruptIn button(USER_BUTTON); -PwmOut pwm(D5);//do not use D3 -DigitalOut a(D2); -DigitalOut b(D4); - -AnalogIn currentSense(A5); //hook up to Vout on current sensor -Serial pc(USBTX, USBRX, 115200); DigitalOut green(LED2); -const int CPR = 900*4; // Encoder counts per revolution. Change to match your encoder. x4 for quadrature! -const double VREF = 3; //Microcontroller reference voltage -const float currentSensorOutputRatio = 0.185; // Volts/Amp. Divide Voltage by cSenseOutput to get current -const float PSupply_Voltage = 12.0; -const float Output_Voltage = 2.0; +// Pololu VNH5019 Motor Driver Carrier. https://www.pololu.com/product/1451 +PwmOut pwm(D5); //pwm input on motor controller. do not use D3 +DigitalOut a(D2); //IN_A input on motor controller +DigitalOut b(D4); //IN_B input on motor controller + +//Hook up to Vout on current sensor +//SparkFun Hall-Effect Current Sensor Breakout - ACS712 +//https://www.sparkfun.com/products/8882 +AnalogIn currentSense(A5); + +//For communication with pc through matlab +//Make sure baud rates are equal +Serial pc(USBTX, USBRX, 115200); + +const int CPR = 900*4; // Encoder counts per revolution (900). Change to match your encoder. x4 for quadrature +const double VREF = 3; // Microcontroller reference voltage +const float currentSensorOutputRatio = 0.185; // Volts/Amp specified by current sensor. Divide Voltage by cSenseOutput to get current +const float PSupply_Voltage = 12.0; // Voltage input from power supply +const float Output_Voltage = 2.0; // Desired output voltage to motor const float pwm_flywheel = Output_Voltage/PSupply_Voltage; void EncoderInitialise(void) { @@ -77,32 +90,41 @@ int main() { - int endcount, startcount; - double time_between_readings; + int endcount, startcount; //encoder counts + double time_between_readings; //between encoder readings double velocity; double currentSensed = 0; clock_t start, end, absoluteStart; int ticks; a=1; b=0; pwm.write(0); - button.fall(&pressed); - double updatePeriod = 0.01; /* must select carefully */ - double publishFrequency = 0.05; /* seconds. rate to publish to matlab */ - double samplesPerPublish = (int)(publishFrequency/updatePeriod); /*this improves time response of filter and maintains smoothness*/ + button.fall(&pressed); //adds pressed callback upon button push + + /* we don't send all the information to matlab all the time. some collection and smoothing is done + here in order to not overload matlab with input making it slow. And to take a lot of data so we + can do smoothing quickly on this side */ + double updatePeriod = 0.01; /* must select carefully. too fast and you don't get enough encoder ticks*/ + double publishFrequency = 0.05; /* seconds. rate to publish to matlab. no need to overload matlab with input*/ + double samplesPerPublish = (int)(publishFrequency/updatePeriod); /*this improves time response of current filter and maintains smoothness*/ int publishCounter = 1; + + /* the filter ratio on the speed data from encoder and on current input */ double filterRatio = 0.1; double currentFilterRatio = 0.035; + + /* the current sensor has some resting value. record and subtract that out */ float currentSensorOffset = 0; int i; for(i=1;i<301;i++){ currentSensorOffset += currentSense.read(); } currentSensorOffset = currentSensorOffset*VREF/300; + EncoderInitialise(); - fflush(pc); + fflush(pc); //clear any previous output while(1) { - while(1) { - + + while(1) { //Listen for PC input to start run green = true; if(pc.readable()) { char charIn = pc.getc(); @@ -119,12 +141,11 @@ break; } } - wait(0.05); - } + while(1) { green = false; @@ -137,20 +158,22 @@ ticks = endcount-startcount; if(abs(ticks)>CPR/2) /***** for rollover case: *****/ { ticks = ((ticks<0)-(ticks>0))*(CPR-abs(ticks)); } + velocity = filterRatio*((double)ticks)/CPR*2*PI/time_between_readings + (1-filterRatio)*velocity; /* with filtering*/ currentSensed = currentFilterRatio*((double)currentSense.read()*VREF-currentSensorOffset) + (1-currentFilterRatio)*currentSensed; - if(pc.readable()) - { + + if(pc.readable()) { //PC will send 'r' when run is finished char charIn = pc.getc(); if(charIn == 'r'){ fflush(pc); - pwm.write(0.0); - break; + pwm.write(0.0); //kill the motor + break; //return to listening loop } } - if(publishCounter == samplesPerPublish) { + + if(publishCounter == samplesPerPublish) { //only publish once every samplesPerPublish printf("%+9.5f,%+8.4f,%+9.4f,%+8.2f\n", currentSensed/currentSensorOutputRatio, pwm.read(), -velocity, ((double)(end-absoluteStart)/CLOCKS_PER_SEC)); - publishCounter = 1; // good for 1000 seconds. and room to grow one power of 10 on all other inputs. //just changed velocity to 4 precision to give it extra room for no load? bug maybe? + publishCounter = 1; //output formatting very important. running a simple string length checksum on matlab side to discard bad data } publishCounter++;