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.
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 |
--- 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++;