Modified Motor Driver Firmware to include Flash + Thermal

Dependencies:   FastPWM3 mbed-dev-STM-lean

Files at this revision

API Documentation at this revision

Comitter:
benkatz
Date:
Wed Dec 05 04:07:46 2018 +0000
Parent:
46:2d4b1dafcfe3
Child:
48:74a40481740c
Commit message:
albert revision;

Changed in this revision

CAN/CAN_com.h Show annotated file Show diff for this revision Revisions of this file
Calibration/calibration.cpp Show annotated file Show diff for this revision Revisions of this file
Calibration/calibration.h Show annotated file Show diff for this revision Revisions of this file
Config/current_controller_config.h Show annotated file Show diff for this revision Revisions of this file
Config/hw_config.h Show annotated file Show diff for this revision Revisions of this file
Config/motor_config.h Show annotated file Show diff for this revision Revisions of this file
FOC/foc.cpp Show annotated file Show diff for this revision Revisions of this file
FOC/foc.h Show annotated file Show diff for this revision Revisions of this file
PositionSensor/PositionSensor.cpp Show annotated file Show diff for this revision Revisions of this file
PositionSensor/PositionSensor.h Show annotated file Show diff for this revision Revisions of this file
main.cpp Show annotated file Show diff for this revision Revisions of this file
math_ops.cpp Show annotated file Show diff for this revision Revisions of this file
math_ops.h Show annotated file Show diff for this revision Revisions of this file
structs.h Show annotated file Show diff for this revision Revisions of this file
--- a/CAN/CAN_com.h	Thu Jul 12 02:50:34 2018 +0000
+++ b/CAN/CAN_com.h	Wed Dec 05 04:07:46 2018 +0000
@@ -1,10 +1,10 @@
 #ifndef CAN_COM_H
 #define CAN_COM_H
 
-#include "structs.h"
+#include "../structs.h"
 #include "user_config.h"
 #include "mbed.h"
-#include "math_ops.h"
+#include "../math_ops.h"
 
 void pack_reply(CANMessage *msg, float p, float v, float t);
 void unpack_cmd(CANMessage msg, ControllerStruct * controller);
--- a/Calibration/calibration.cpp	Thu Jul 12 02:50:34 2018 +0000
+++ b/Calibration/calibration.cpp	Wed Dec 05 04:07:46 2018 +0000
@@ -16,7 +16,7 @@
     printf("\n\r Checking phase ordering\n\r");
     float theta_ref = 0;
     float theta_actual = 0;
-    float v_d = .05f;                                                             //Put all volts on the D-Axis
+    float v_d = V_CAL;                                                             //Put all volts on the D-Axis
     float v_q = 0.0f;
     float v_u, v_v, v_w = 0;
     float dtc_u, dtc_v, dtc_w = .5f;
@@ -32,7 +32,7 @@
         wait_us(100);
         }
     //ps->ZeroPosition();
-    ps->Sample(); 
+    ps->Sample(DT); 
     wait_us(1000);
     //float theta_start = ps->GetMechPositionFixed();                                  //get initial rotor position
     float theta_start;
@@ -51,7 +51,7 @@
         TIM1->CCR3 = (PWM_ARR>>1)*(1.0f-dtc_u);                                        //Set duty cycles
         TIM1->CCR2 = (PWM_ARR>>1)*(1.0f-dtc_v);
         TIM1->CCR1 = (PWM_ARR>>1)*(1.0f-dtc_w);
-       ps->Sample();                                                            //sample position sensor
+       ps->Sample(DT);                                                            //sample position sensor
        theta_actual = ps->GetMechPositionFixed();
        if(theta_ref==0){theta_start = theta_actual;}
        if(sample_counter > 200){
@@ -84,7 +84,7 @@
     float * error_filt;
     
     const int n = 128*NPP;                                                      // number of positions to be sampled per mechanical rotation.  Multiple of NPP for filtering reasons (see later)
-    const int n2 = 50;                                                          // increments between saved samples (for smoothing motion)
+    const int n2 = 40;                                                          // increments between saved samples (for smoothing motion)
     float delta = 2*PI*NPP/(n*n2);                                              // change in angle between samples
     error_f = new float[n]();                                                     // error vector rotating forwards
     error_b = new float[n]();                                                     // error vector rotating backwards
@@ -101,7 +101,7 @@
     raw_b = new int[n]();
     float theta_ref = 0;
     float theta_actual = 0;
-    float v_d = .05f;                                                             // Put volts on the D-Axis
+    float v_d = V_CAL;                                                             // Put volts on the D-Axis
     float v_q = 0.0f;
     float v_u, v_v, v_w = 0;
     float dtc_u, dtc_v, dtc_w = .5f;
@@ -122,7 +122,7 @@
             }
         wait_us(100);
         }
-    ps->Sample();   
+    ps->Sample(DT);   
     controller->i_b = I_SCALE*(float)(controller->adc2_raw - controller->adc2_offset);    //Calculate phase currents from ADC readings
     controller->i_c = I_SCALE*(float)(controller->adc1_raw - controller->adc1_offset);
     controller->i_a = -controller->i_b - controller->i_c;
@@ -144,9 +144,9 @@
             TIM1->CCR2 = (PWM_ARR>>1)*(1.0f-dtc_w);
             }
             wait_us(100);
-            ps->Sample();
+            ps->Sample(DT);
         }
-       ps->Sample();
+       ps->Sample(DT);
        theta_actual = ps->GetMechPositionFixed();
        error_f[i] = theta_ref/NPP - theta_actual;
        raw_f[i] = ps->GetRawPosition();
@@ -169,9 +169,9 @@
             TIM1->CCR2 = (PWM_ARR>>1)*(1.0f-dtc_w);
             }
             wait_us(100);
-            ps->Sample();
+            ps->Sample(DT);
         }
-       ps->Sample();                                                            // sample position sensor
+       ps->Sample(DT);                                                            // sample position sensor
        theta_actual = ps->GetMechPositionFixed();                                    // get mechanical position
        error_b[i] = theta_ref/NPP - theta_actual;
        raw_b[i] = ps->GetRawPosition();
--- a/Calibration/calibration.h	Thu Jul 12 02:50:34 2018 +0000
+++ b/Calibration/calibration.h	Wed Dec 05 04:07:46 2018 +0000
@@ -7,6 +7,8 @@
 #include "PreferenceWriter.h"
 #include "user_config.h"
 
+#define V_CAL 0.15f;
+
 
 void order_phases(PositionSensor *ps, GPIOStruct *gpio, ControllerStruct *controller, PreferenceWriter *prefs);
 void calibrate(PositionSensor *ps, GPIOStruct *gpio, ControllerStruct *controller, PreferenceWriter *prefs);
--- a/Config/current_controller_config.h	Thu Jul 12 02:50:34 2018 +0000
+++ b/Config/current_controller_config.h	Wed Dec 05 04:07:46 2018 +0000
@@ -7,13 +7,14 @@
 #define K_SCALE 0.0001f             // K_loop/Loop BW (Hz) 0.0042
 #define KI_D 0.0255f                // PI zero, in radians per sample
 #define KI_Q 0.0255f                // PI zero, in radians per sample
-#define V_BUS 24.0f                 // Volts
-#define OVERMODULATION 1.4f         // 1.0 = no overmodulation
+#define V_BUS 35.0f                 // Volts
+#define OVERMODULATION 1.15f         // 1.0 = no overmodulation
 
 #define D_INT_LIM V_BUS/(K_D*KI_D)  // Amps*samples
 #define Q_INT_LIM V_BUS/(K_Q*KI_Q)  // Amps*samples
 
 #define I_MAX 40.0f
+#define I_MAX_FW 0.0f
 
 //Observer//
 #define DT 0.000025f
--- a/Config/hw_config.h	Thu Jul 12 02:50:34 2018 +0000
+++ b/Config/hw_config.h	Wed Dec 05 04:07:46 2018 +0000
@@ -7,9 +7,9 @@
 #define ENABLE_PIN PA_11        // Enable gate drive pin
 #define LED         PC_5        // LED Pin
 #define I_SCALE 0.02014160156f  // Amps per A/D Count
-#define V_SCALE 0.00884f        // Bus volts per A/D Count
-#define DTC_MAX 0.95f          // Max phase duty cycle
-#define DTC_MIN 0.05f          // Min phase duty cycle
+#define V_SCALE 0.00886f        // Bus volts per A/D Count
+#define DTC_MAX 0.94f          // Max phase duty cycle
+#define DTC_MIN 0.0f          // Min phase duty cycle
 #define PWM_ARR 0x8CA           /// timer autoreload value
 
 
--- a/Config/motor_config.h	Thu Jul 12 02:50:34 2018 +0000
+++ b/Config/motor_config.h	Wed Dec 05 04:07:46 2018 +0000
@@ -1,12 +1,12 @@
 #ifndef MOTOR_CONFIG_H
 #define MOTOR_CONFIG_H
 
-#define R_PHASE 0.13f          //Ohms
-#define L_D 0.00003f            //Henries
-#define L_Q 0.00003f            //Henries
-#define KT .075f                 //N-m per peak phase amp, = WB*NPP*3/2
-#define NPP 20                  //Number of pole pairs
-#define GR 6.0f                 //Gear ratio
+#define R_PHASE 0.02f          //Ohms
+#define L_D 0.00002f            //Henries
+#define L_Q 0.00002f            //Henries
+#define KT .08f                 //N-m per peak phase amp, = WB*NPP*3/2
+#define NPP 21                  //Number of pole pairs
+#define GR 1.0f                 //Gear ratio
 #define KT_OUT 0.45f            //KT*GR
 #define WB 0.0024f               //Flux linkage, Webers.  
 
--- a/FOC/foc.cpp	Thu Jul 12 02:50:34 2018 +0000
+++ b/FOC/foc.cpp	Wed Dec 05 04:07:46 2018 +0000
@@ -34,12 +34,22 @@
     /// u,v,w amplitude = v_bus for full modulation depth ///
     
     float v_offset = (fminf3(u, v, w) + fmaxf3(u, v, w))/2.0f;
+    
     *dtc_u = fminf(fmaxf(((u -v_offset)/v_bus + .5f), DTC_MIN), DTC_MAX);
     *dtc_v = fminf(fmaxf(((v -v_offset)/v_bus + .5f), DTC_MIN), DTC_MAX);
-    *dtc_w = fminf(fmaxf(((w -v_offset)/v_bus + .5f), DTC_MIN), DTC_MAX);  
+    *dtc_w = fminf(fmaxf(((w -v_offset)/v_bus + .5f), DTC_MIN), DTC_MAX); 
+    
+    /*
+    sinusoidal pwm
+    *dtc_u = fminf(fmaxf((u/v_bus + .5f), DTC_MIN), DTC_MAX);
+    *dtc_v = fminf(fmaxf((v/v_bus + .5f), DTC_MIN), DTC_MAX);
+    *dtc_w = fminf(fmaxf((w/v_bus + .5f), DTC_MIN), DTC_MAX);
+    */
+     
     
     }
 
+
 void zero_current(int *offset_1, int *offset_2){                                // Measure zero-offset of the current sensors
     int adc1_offset = 0;
     int adc2_offset = 0;
@@ -79,6 +89,7 @@
     controller->d_int = 0;
     controller->v_q = 0;
     controller->v_d = 0;
+
     }
     
 void limit_current_ref (ControllerStruct *controller){
@@ -88,11 +99,8 @@
     }
 
 
-void commutate(ControllerStruct *controller, ObserverStruct *observer, GPIOStruct *gpio, float theta){
-       /// Observer Prediction ///
-       observer->i_d_est += DT*(observer->i_d_dot);
-       observer->i_q_est += DT*(observer->i_q_dot);
-       
+void commutate(ControllerStruct *controller, GPIOStruct *gpio, float theta){
+
        /// Commutation Loop ///
        controller->loop_count ++;   
        if(PHASE_ORDER){                                                                          // Check current sensor ordering
@@ -112,21 +120,8 @@
        //controller->i_q = 0.6666667f*(-s*controller->i_a - (-0.86602540378f*c-.5f*s)*controller->i_b - (0.86602540378f*c-.5f*s)*controller->i_c);
         
         controller->i_q_filt = 0.95f*controller->i_q_filt + 0.05f*controller->i_q;
-        observer->i_d_m = controller->i_d;
-        observer->i_q_m = controller->i_q;
-        
-        observer->e_d = observer->i_d_m - observer->i_d_est;
-        observer->e_q = observer->i_q_m - observer->i_q_est;
-        observer->e_d_int += observer->e_d;
-        observer->e_q_int += observer->e_q;
+        controller->i_d_filt = 0.95f*controller->i_d_filt + 0.05f*controller->i_d;
         
-        observer->i_d_est +=  K_O*observer->e_d + .001f*observer->e_d_int;
-        observer->i_q_est += K_O*observer->e_q + .001f*observer->e_q_int;
-        
-        
-        //float scog12 = FastSin(12.0f*theta);
-        //float scog1 = s;
-        //float cogging_current = 0.25f*scog1 - 0.3f*scog12;
         
         // Filter the current references to the desired closed-loopbandwidth
         // Allows calculation of desired di/dt for inductance, etc
@@ -137,32 +132,42 @@
         controller->did_dt = (controller->i_d_ref_filt - controller->did_dt)/DT;
         controller->diq_dt = (controller->i_q_ref_filt - controller->diq_dt)/DT;
        
+       
+       /// Field Weakening ///
+       /*
+       controller->fw_int += .001*(0.5f*OVERMODULATION*controller->v_bus - controller->v_ref);
+       controller->fw_int = fmaxf(fminf(controller->fw_int, 0.0f), -I_MAX_FW);
+       controller->i_d_ref = controller->fw_int;
+       float i_cmd_mag_sq = controller->i_d_ref*controller->i_d_ref + controller->i_q_ref*controller->i_q_ref;
+       limit_norm(&controller->i_d_ref, &controller->i_q_ref, I_MAX);
+       
+       */
+       
        /// PI Controller ///
        float i_d_error = controller->i_d_ref - controller->i_d;
        float i_q_error = controller->i_q_ref - controller->i_q;//  + cogging_current;
        
        // Calculate feed-forward voltages //
-       float v_d_ff = 2.0f*(0.0f*controller->i_d_ref*R_PHASE + 0.0f*L_D*controller->did_dt - controller->dtheta_elec*L_Q*controller->i_q);   //feed-forward voltages
-       float v_q_ff =  2.0f*(0.0f*controller->i_q_ref*R_PHASE + 0.0f*L_Q*controller->diq_dt + controller->dtheta_elec*(L_D*controller->i_d + 0.0f*WB));
+       float v_d_ff = 2.0f*(1.0f*controller->i_d_ref*R_PHASE  - controller->dtheta_elec*L_Q*controller->i_q);   //feed-forward voltages
+       float v_q_ff =  2.0f*(1.0f*controller->i_q_ref*R_PHASE +  controller->dtheta_elec*(L_D*controller->i_d + 1.0f*WB));
        
        // Integrate Error //
-       controller->d_int += i_d_error;   
-       controller->q_int += i_q_error;
-
-       limit_norm(&controller->d_int, &controller->q_int, V_BUS/(controller->k_q*controller->ki_q));        
-       controller->v_d = controller->k_d*(i_d_error + controller->ki_d*controller->d_int) + v_d_ff;  
-       controller->v_q = controller->k_q*(i_q_error + controller->ki_q*controller->q_int) + v_q_ff; 
+       controller->d_int += controller->k_d*controller->ki_d*i_d_error;   
+       controller->q_int += controller->k_q*controller->ki_q*i_q_error;
+       
+       controller->d_int = fmaxf(fminf(controller->d_int, OVERMODULATION*controller->v_bus), - OVERMODULATION*controller->v_bus);
+       controller->q_int = fmaxf(fminf(controller->q_int, OVERMODULATION*controller->v_bus), - OVERMODULATION*controller->v_bus); 
+       
+       //limit_norm(&controller->d_int, &controller->q_int, OVERMODULATION*controller->v_bus);     
+       controller->v_d = controller->k_d*i_d_error + controller->d_int ;//+ v_d_ff;  
+       controller->v_q = controller->k_q*i_q_error + controller->q_int ;//+ v_q_ff; 
+       
+       controller->v_ref = sqrt(controller->v_d*controller->v_d + controller->v_q*controller->v_q);
        
        limit_norm(&controller->v_d, &controller->v_q, OVERMODULATION*controller->v_bus);       // Normalize voltage vector to lie within curcle of radius v_bus
-       abc(controller->theta_elec + 0.5f*DT*controller->dtheta_elec, controller->v_d, controller->v_q, &controller->v_u, &controller->v_v, &controller->v_w); //inverse dq0 transform on voltages
+       abc(controller->theta_elec + 0.0f*DT*controller->dtheta_elec, controller->v_d, controller->v_q, &controller->v_u, &controller->v_v, &controller->v_w); //inverse dq0 transform on voltages
        svm(controller->v_bus, controller->v_u, controller->v_v, controller->v_w, &controller->dtc_u, &controller->dtc_v, &controller->dtc_w); //space vector modulation
 
-       observer->i_d_dot = 0.5f*(controller->v_d - 2.0f*(observer->i_d_est*R_PHASE - controller->dtheta_elec*L_Q*observer->i_q_est))/L_D;   //feed-forward voltage
-       observer->i_q_dot =  0.5f*(controller->v_q - 2.0f*(observer->i_q_est*R_PHASE  + controller->dtheta_elec*(L_D*observer->i_d_est + WB)))/L_Q;
-       
-       //controller->dtc_u = 0.5f;
-       //controller->dtc_v = 0.6f;
-       //controller->dtc_w = 0.5f;
        if(PHASE_ORDER){                                                         // Check which phase order to use, 
             TIM1->CCR3 = (PWM_ARR)*(1.0f-controller->dtc_u);                        // Write duty cycles
             TIM1->CCR2 = (PWM_ARR)*(1.0f-controller->dtc_v);
@@ -176,17 +181,6 @@
 
        controller->theta_elec = theta;                                          //For some reason putting this at the front breaks thins
        
-
-       if(controller->loop_count >400){
-           //controller->i_q_ref = -controller->i_q_ref;
-          controller->loop_count  = 0;
-           
-           //printf("%.2f  %.2f  %.2f\n\r", controller->i_a, controller->i_b, controller->i_c);
-           //printf("%f\n\r", controller->dtheta_mech*GR);
-           //pc.printf("%f    %f    %f\n\r", controller->i_a, controller->i_b, controller->i_c);
-           printf("%f %f\n\r", v_q_ff, v_d_ff);
-           //pc.printf("%d    %d\n\r", controller->adc1_raw, controller->adc2_raw);
-            }
     }
     
     
@@ -196,10 +190,4 @@
     controller->i_q_ref = torque_ref/KT_OUT;    
     controller->i_d_ref = 0.0f;
     }
-
-
-/*    
-void zero_encoder(ControllerStruct *controller, GPIOStruct *gpio, ){
-    
-    }
-*/    
\ No newline at end of file
+ 
\ No newline at end of file
--- a/FOC/foc.h	Thu Jul 12 02:50:34 2018 +0000
+++ b/FOC/foc.h	Wed Dec 05 04:07:46 2018 +0000
@@ -1,12 +1,12 @@
 #ifndef FOC_H
 #define FOC_H
 
-#include "structs.h"
+#include "../structs.h"
 #include "PositionSensor.h"
 #include "mbed.h"
 #include "hw_config.h"
 #include "math.h"
-#include "math_ops.h"
+#include "../math_ops.h"
 #include "motor_config.h"
 #include "current_controller_config.h"
 #include "FastMath.h"
@@ -18,7 +18,7 @@
 void zero_current(int *offset_1, int *offset_2);
 void reset_foc(ControllerStruct *controller);
 void init_controller_params(ControllerStruct *controller);
-void commutate(ControllerStruct *controller, ObserverStruct *observer, GPIOStruct *gpio, float theta);
+void commutate(ControllerStruct *controller, GPIOStruct *gpio, float theta);
 void torque_control(ControllerStruct *controller);
 void limit_current_ref (ControllerStruct *controller);
 #endif
--- a/PositionSensor/PositionSensor.cpp	Thu Jul 12 02:50:34 2018 +0000
+++ b/PositionSensor/PositionSensor.cpp	Wed Dec 05 04:07:46 2018 +0000
@@ -1,7 +1,7 @@
 
 #include "mbed.h"
 #include "PositionSensor.h"
-#include "math_ops.h"
+#include "../math_ops.h"
 //#include "offset_lut.h"
 //#include <math.h>
 
@@ -25,10 +25,12 @@
     raw = 0;
     }
     
-void PositionSensorAM5147::Sample(){
+void PositionSensorAM5147::Sample(float dt){
     GPIOA->ODR &= ~(1 << 15);
-    raw = spi->write(readAngleCmd);
-    raw &= 0x3FFF;                                                              //Extract last 14 bits
+    //raw = spi->write(readAngleCmd);
+    //raw &= 0x3FFF;   
+    raw = spi->write(0);
+    raw = raw>>1;                                                             //Extract last 14 bits
     GPIOA->ODR |= (1 << 15);
     int off_1 = offset_lut[raw>>7];
     int off_2 = offset_lut[((raw>>7)+1)%128];
@@ -53,15 +55,16 @@
     
     float vel;
     //if(modPosition<.1f && oldModPosition>6.1f){
+
     if((modPosition-oldModPosition) < -3.0f){
-        vel = (modPosition - oldModPosition + 2.0f*PI)*40000.0f;
+        vel = (modPosition - oldModPosition + 2.0f*PI)/dt;
         }
     //else if(modPosition>6.1f && oldModPosition<0.1f){
     else if((modPosition - oldModPosition) > 3.0f){
-        vel = (modPosition - oldModPosition - 2.0f*PI)*40000.0f;
+        vel = (modPosition - oldModPosition - 2.0f*PI)/dt;
         }
     else{
-        vel = (modPosition-oldModPosition)*40000.0f;
+        vel = (modPosition-oldModPosition)/dt;
     }    
     
     int n = 40;
@@ -103,7 +106,7 @@
 void PositionSensorAM5147::ZeroPosition(){
     rotations = 0;
     MechOffset = 0;
-    Sample();
+    Sample(.00025f);
     MechOffset = GetMechPosition();
     }
     
@@ -192,7 +195,7 @@
     //ZTest->write(1);
     }
     
-void PositionSensorEncoder::Sample(){
+void PositionSensorEncoder::Sample(float dt){
     
     }
 
--- a/PositionSensor/PositionSensor.h	Thu Jul 12 02:50:34 2018 +0000
+++ b/PositionSensor/PositionSensor.h	Wed Dec 05 04:07:46 2018 +0000
@@ -2,7 +2,7 @@
 #define POSITIONSENSOR_H
 class PositionSensor {
 public:
-    virtual void Sample(void) = 0;
+    virtual void Sample(float dt) = 0;
     virtual float GetMechPosition() {return 0.0f;}
     virtual float GetMechPositionFixed() {return 0.0f;}
     virtual float GetElecPosition() {return 0.0f;}
@@ -19,7 +19,7 @@
 class PositionSensorEncoder: public PositionSensor {
 public:
     PositionSensorEncoder(int CPR, float offset, int ppairs);
-    virtual void Sample();
+    virtual void Sample(float dt);
     virtual float GetMechPosition();
     virtual float GetElecPosition();
     virtual float GetMechVelocity();
@@ -44,7 +44,7 @@
 class PositionSensorAM5147: public PositionSensor{
 public:
     PositionSensorAM5147(int CPR, float offset, int ppairs);
-    virtual void Sample();
+    virtual void Sample(float dt);
     virtual float GetMechPosition();
     virtual float GetMechPositionFixed();
     virtual float GetElecPosition();
--- a/main.cpp	Thu Jul 12 02:50:34 2018 +0000
+++ b/main.cpp	Wed Dec 05 04:07:46 2018 +0000
@@ -2,6 +2,7 @@
 /// Written by benkatz, with much inspiration from Bayley Wang, Nick Kirkby, Shane Colton, David Otten, and others
 /// Hardware documentation can be found at build-its.blogspot.com
 /// Written for the STM32F446, but can be implemented on other STM32 MCU's with some further register-diddling
+/// Version for the TI DRV8323 Everything Chip
 
 #define REST_MODE 0
 #define CALIBRATION_MODE 1
@@ -37,7 +38,6 @@
 GPIOStruct gpio;
 ControllerStruct controller;
 COMStruct com;
-ObserverStruct observer;
 Serial pc(PA_2, PA_3);
 
 
@@ -59,7 +59,7 @@
 
 void onMsgReceived() {
     //msgAvailable = true;
-    //printf("%.3f   %.3f   %.3f\n\r", controller.theta_mech, controller.dtheta_mech, controller.i_q);
+    printf("%df\n\r", rxMsg.id);
     can.read(rxMsg);  
     if((rxMsg.id == CAN_ID)){
         controller.timeout = 0;
@@ -86,6 +86,7 @@
 
 void enter_menu_state(void){
     drv.disable_gd();
+    //gpio.enable->write(0);
     printf("\n\r\n\r\n\r");
     printf(" Commands:\n\r");
     wait_us(10);
@@ -102,7 +103,6 @@
     printf(" esc - Exit to Menu\n\r");
     wait_us(10);
     state_change = 0;
-    //gpio.enable->write(0);
     gpio.led->write(0);
     }
 
@@ -128,6 +128,7 @@
     
 void enter_torque_mode(void){
     drv.enable_gd();
+    //gpio.enable->write(1);
     controller.ovp_flag = 0;
     reset_foc(&controller);                                                     // Tesets integrators, and other control loop parameters
     wait(.001);
@@ -140,6 +141,7 @@
     
 void calibrate(void){
     drv.enable_gd();
+    //gpio.enable->write(1);
     gpio.led->write(1);                                                    // Turn on status LED
     order_phases(&spi, &gpio, &controller, &prefs);                             // Check phase ordering
     calibrate(&spi, &gpio, &controller, &prefs);                                // Perform calibration procedure
@@ -147,12 +149,14 @@
     wait(.2);
     printf("\n\r Calibration complete.  Press 'esc' to return to menu\n\r");
     drv.disable_gd();
+    //gpio.enable->write(0);
      state_change = 0;
     }
     
 void print_encoder(void){
-    printf(" Mechanical Angle:  %f    Electrical Angle:  %f    Raw:  %d\n\r", spi.GetMechPosition(), spi.GetElecPosition(), spi.GetRawPosition());
-    wait(.05);
+    //printf(" Mechanical Angle:  %f    Electrical Angle:  %f    Raw:  %d\n\r", spi.GetMechPosition(), spi.GetElecPosition(), spi.GetRawPosition());
+    printf("%d\n\r", spi.GetRawPosition());
+    wait(.001);
     }
 
 /// Current Sampling Interrupt ///
@@ -165,7 +169,7 @@
         //volatile int delay;   
         //for (delay = 0; delay < 55; delay++);
 
-        spi.Sample();                                                           // sample position sensor
+        spi.Sample(DT);                                                           // sample position sensor
         controller.adc2_raw = ADC2->DR;                                         // Read ADC Data Registers
         controller.adc1_raw = ADC1->DR;
         controller.adc3_raw = ADC3->DR;
@@ -173,7 +177,7 @@
         controller.theta_mech = (1.0f/GR)*spi.GetMechPosition();
         controller.dtheta_mech = (1.0f/GR)*spi.GetMechVelocity();  
         controller.dtheta_elec = spi.GetElecVelocity();
-        controller.v_bus = 24.0f;//0.95f*controller.v_bus + 0.05f*((float)controller.adc3_raw)*V_SCALE;
+        controller.v_bus = V_BUS;//b0.95f*controller.v_bus + 0.05f*((float)controller.adc3_raw)*V_SCALE;
         ///
         
         /// Check state machine state, and run the appropriate function ///
@@ -198,7 +202,8 @@
                 else{
                 /*
                 if(controller.v_bus>28.0f){         //Turn of gate drive if bus voltage is too high, to prevent FETsplosion if the bus is cut during regen
-                    gpio.enable->write(0);
+                    gpio.
+                    ->write(0);
                     controller.ovp_flag = 1;
                     state = REST_MODE;
                     state_change = 1;
@@ -206,7 +211,7 @@
                     }
                     */  
 
-                torque_control(&controller);    
+                //torque_control(&controller);    
                 if((controller.timeout > CAN_TIMEOUT) && (CAN_TIMEOUT > 0)){
                     controller.i_d_ref = 0;
                     controller.i_q_ref = 0;
@@ -214,24 +219,46 @@
                     controller.kd = 0;
                     controller.t_ff = 0;
                     } 
+                //controller.i_q_ref = 0.0f;
+                //controller.i_d_ref = 0.0f;
+                
                 //controller.i_q_ref = 2.0f;
-                //controller.i_d_ref = 30.0f;
-                commutate(&controller, &observer, &gpio, controller.theta_elec);           // Run current loop
+                //controller.i_d_ref = -30.0f;
+                //controller.kd = .1;
+                //controller.v_des = 25;
+                torque_control(&controller);
+                //controller.i_q_ref = 2.0f;
+                //controller.i_d_ref = -20.0f;
+                commutate(&controller, &gpio, controller.theta_elec);           // Run current loop
                 //TIM1->CCR3 = (PWM_ARR)*(0.5f);                        // Write duty cycles
                 //TIM1->CCR2 = (PWM_ARR)*(0.5f);
                 //TIM1->CCR1 = (PWM_ARR)*(0.5f);
                 controller.timeout += 1;
+
+                //pc.putc(iq);
+                //pc.putc(id);
+                //pc.putc(ang);
+                //pc.printf("\n\r");
                 
                 
                 count++;
+                
                 /*
-                if(count == 4000){
+                if(count == 400){
                      //printf("%d  %d  %.4f  %.4f  %.4f\n\r", controller.adc1_raw, controller.adc2_raw, controller.i_a, controller.i_b, controller.i_c);
-                     printf("%.3f\n\r", controller.dtheta_mech);
+                     printf("%.2f\n\r", 1000.0f*controller.h1_iq_afc_int1);
+                     //pc.putc(id);
+                     //pc.putc(iq);
+                     //pc.putc(ang);
+                     //pc.putc('\n');
+                     //pc.putc('\r');
+                     //printf("%.1f\n", controller.k_q*controller.ki_q*controller.q_int);
                      count = 0;
                      }
                      */
                      
+                    
+                     
                    
                      
             
@@ -288,7 +315,7 @@
                     break;
                 case 'z':
                     spi.SetMechOffset(0);
-                    spi.Sample();
+                    spi.Sample(DT);
                     wait_us(20);
                     M_OFFSET = spi.GetMechPosition();
                     if (!prefs.ready()) prefs.open();
@@ -370,11 +397,11 @@
     wait_us(100);
     drv.write_CSACR(0x0, 0x1, 0x0, CSA_GAIN_40, 0x0, 0x0, 0x0, 0x0, SEN_LVL_1_0);
     wait_us(100);
-    drv.write_OCPCR(TRETRY_4MS, DEADTIME_100NS, OCP_RETRY, OCP_DEG_4US, VDS_LVL_0_75);
+    drv.write_OCPCR(TRETRY_4MS, DEADTIME_200NS, OCP_RETRY, OCP_DEG_4US, VDS_LVL_1_5);
     
     //drv.enable_gd();
     zero_current(&controller.adc1_offset, &controller.adc2_offset);             // Measure current sensor zero-offset
-    //drv.disable_gd();
+    drv.disable_gd();
 
 
     
@@ -426,12 +453,12 @@
 
 
 
-    printf(" %d\n\r", drv.read_register(DCR));
-    wait_us(100);
-    printf(" %d\n\r", drv.read_register(CSACR));
-    wait_us(100);
-    printf(" %d\n\r", drv.read_register(OCPCR));
-    drv.disable_gd();
+    //printf(" %d\n\r", drv.read_register(DCR));
+    //wait_us(100);
+    //printf(" %d\n\r", drv.read_register(CSACR));
+    //wait_us(100);
+    //printf(" %d\n\r", drv.read_register(OCPCR));
+    //drv.disable_gd();
     
     pc.attach(&serial_interrupt);                                               // attach serial interrupt
     
@@ -440,5 +467,13 @@
 
     int counter = 0;
     while(1) {
+        drv.print_faults();
+       wait(.1);
+        if(state == MOTOR_MODE)
+        {
+            //printf("%.3f\n\r", controller.dtheta_mech);
+            //wait(.001);
+        }
+
     }
 }
--- a/math_ops.cpp	Thu Jul 12 02:50:34 2018 +0000
+++ b/math_ops.cpp	Wed Dec 05 04:07:46 2018 +0000
@@ -1,5 +1,5 @@
 
-#include "math_ops.h"
+#include "../math_ops.h"
 
 
 float fmaxf(float x, float y){
@@ -36,14 +36,21 @@
         *y = *y * limit/norm;
         }
     }
+    
+void limit(float *x, float min, float max){
+    *x = fmaxf(fminf(*x, max), min);
+    }
 
 int float_to_uint(float x, float x_min, float x_max, int bits){
+    /// Converts a float to an unsigned int, given range and number of bits ///
     float span = x_max - x_min;
     float offset = x_min;
-    return (int) ((x+offset)*((float)((1<<bits)-1))/span);
+    return (int) ((x-offset)*((float)((1<<bits)-1))/span);
     }
     
+    
 float uint_to_float(int x_int, float x_min, float x_max, int bits){
+    /// converts unsigned int to float, given range and number of bits ///
     float span = x_max - x_min;
     float offset = x_min;
     return ((float)x_int)*span/((float)((1<<bits)-1)) + offset;
--- a/math_ops.h	Thu Jul 12 02:50:34 2018 +0000
+++ b/math_ops.h	Wed Dec 05 04:07:46 2018 +0000
@@ -11,6 +11,7 @@
 float fminf3(float x, float y, float z);
 float roundf(float x);
 void limit_norm(float *x, float *y, float limit);
+void limit(float *x, float min, float max);
 int float_to_uint(float x, float x_min, float x_max, int bits);
 float uint_to_float(int x_int, float x_min, float x_max, int bits);
 
--- a/structs.h	Thu Jul 12 02:50:34 2018 +0000
+++ b/structs.h	Wed Dec 05 04:07:46 2018 +0000
@@ -1,7 +1,6 @@
 #ifndef STRUCTS_H
 #define STRUCTS_H
 
-//#include "CANnucleo.h"
 #include "mbed.h"
 #include "FastPWM.h"
 
@@ -22,7 +21,7 @@
     float v_bus;                                            // DC link voltage
     float theta_mech, theta_elec;                           // Rotor mechanical and electrical angle
     float dtheta_mech, dtheta_elec, dtheta_elec_filt;       // Rotor mechanical and electrical angular velocit
-    float i_d, i_q, i_q_filt;                               // D/Q currents
+    float i_d, i_q, i_q_filt, i_d_filt;                               // D/Q currents
     float v_d, v_q;                                         // D/Q voltages
     float dtc_u, dtc_v, dtc_w;                              // Terminal duty cycles
     float v_u, v_v, v_w;                                    // Terminal voltages
@@ -36,17 +35,18 @@
     int mode;
     int ovp_flag;                                           // Over-voltage flag
     float p_des, v_des, kp, kd, t_ff;                       // Desired position, velocity, gians, torque
+    float v_ref, fw_int;                                     // output voltage magnitude, field-weakening integral
     float cogging[128];
     } ControllerStruct;
 
 typedef struct{
-    float theta_m, theta_est;
-    float thetadot_m, thetadot_est;
-    float i_d_m, i_d_est;
-    float i_q_m, i_q_est;
-    float i_d_dot, i_q_dot;
-    float e_d, e_q;
-    float e_d_int, e_q_int;
-    } ObserverStruct;
+    float h;
+    float k;
+    float phi;
+    float cos_integral;
+    float sin_integral;
+    float afc_out;
+    } AFCStruct;
+
     
 #endif