Austin Brown
/
MikeEtekController
Mike Etek Controller
Revision 1:94193b31f0ee, committed 2019-04-06
- Comitter:
- austinbrown124
- Date:
- Sat Apr 06 02:16:12 2019 +0000
- Parent:
- 0:9edd6ec0f56a
- Commit message:
- first commit
Changed in this revision
diff -r 9edd6ec0f56a -r 94193b31f0ee FOC/foc.cpp --- a/FOC/foc.cpp Sat May 20 21:42:20 2017 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,161 +0,0 @@ - -#include "foc.h" - -//#include "FastMath.h" -//using namespace FastMath; - - -void abc( float theta, float d, float q, float *a, float *b, float *c){ - ///Phase current amplitude = lengh of dq vector/// - ///i.e. iq = 1, id = 0, peak phase current of 1/// - - *a = d*cosf(theta) + q*sinf(theta); - *b = d*cosf((2.0f*PI/3.0f)+theta) + q*sinf((2.0f*PI/3.0f)+theta); - *c = d*cosf((-2.0f*PI/3.0f)+theta) + q*sinf((-2.0f*PI/3.0f)+theta); - } - -void dq0(float theta, float a, float b, float c, float *d, float *q){ - ///Phase current amplitude = lengh of dq vector/// - ///i.e. iq = 1, id = 0, peak phase current of 1/// - - *d = (2.0f/3.0f)*(a*cosf(theta) + b*cosf((2.0f*PI/3.0f)+theta) + c*cosf((-2.0f*PI/3.0f)+theta)); - *q = (2.0f/3.0f)*(a*sinf(theta) + b*sinf((2.0f*PI/3.0f)+theta) + c*sinf((-2.0f*PI/3.0f)+theta)); - } - -void svm(float v_bus, float u, float v, float w, float *dtc_u, float *dtc_v, float *dtc_w){ - ///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)*0.5f/v_bus + ((DTC_MAX-DTC_MIN)/2)), DTC_MIN), DTC_MAX); - *dtc_v = fminf(fmaxf(((v - v_offset)*0.5f/v_bus + ((DTC_MAX-DTC_MIN)/2)), DTC_MIN), DTC_MAX); - *dtc_w = fminf(fmaxf(((w - v_offset)*0.5f/v_bus + ((DTC_MAX-DTC_MIN)/2)), DTC_MIN), DTC_MAX); - - } - -void zero_current(int *offset_1, int *offset_2){ - int adc1_offset = 0; - int adc2_offset = 0; - int n = 1024; - for (int i = 0; i<n; i++){ - ADC1->CR2 |= 0x40000000; - wait(.001); - adc2_offset += ADC2->DR; - adc1_offset += ADC1->DR; - } - *offset_1 = adc1_offset/n; - *offset_2 = adc2_offset/n; - } - -void reset_foc(ControllerStruct *controller){ - controller->q_int = 0; - controller->d_int = 0; - } - - -void commutate(ControllerStruct *controller, GPIOStruct *gpio, float theta){ - - controller->loop_count ++; - if(gpio->phasing){ - controller->i_b = I_SCALE*(float)(controller->adc2_raw - controller->adc2_offset); //Calculate phase currents from ADC readings - controller->i_a = I_SCALE*(float)(controller->adc1_raw - controller->adc1_offset); - } - else{ - controller->i_b = I_SCALE*(float)(controller->adc1_raw - controller->adc1_offset); //Calculate phase currents from ADC readings - controller->i_a = I_SCALE*(float)(controller->adc2_raw - controller->adc2_offset); - } - controller->i_c = -controller->i_b - controller->i_a; - - - dq0(controller->theta_elec, controller->i_a, controller->i_b, controller->i_c, &controller->i_d, &controller->i_q); //dq0 transform on currents - - ///Cogging Compensation Lookup/// - //int ind = theta * (128.0f/(2.0f*PI)); - //float cogging_current = controller->cogging[ind]; - //float cogging_current = 1.0f*cos(6*theta); - ///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; - //float v_d_ff = 2.0f*(2*controller->i_d_ref*R_PHASE); //feed-forward voltage - //float v_q_ff = 2.0f*(2*controller->i_q_ref*R_PHASE + controller->dtheta_elec*WB*0.8165f); - controller->d_int += i_d_error; - controller->q_int += i_q_error; - - //v_d_ff = 0; - //v_q_ff = 0; - - limit_norm(&controller->d_int, &controller->q_int, V_BUS/(K_Q*KI_Q)); - //controller->d_int = fminf(fmaxf(controller->d_int, -D_INT_LIM), D_INT_LIM); - //controller->q_int = fminf(fmaxf(controller->q_int, -Q_INT_LIM), Q_INT_LIM); - - - controller->v_d = K_D*i_d_error + K_D*KI_D*controller->d_int;// + v_d_ff; - controller->v_q = K_Q*i_q_error + K_Q*KI_Q*controller->q_int;// + v_q_ff; - - //controller->v_d = v_d_ff; - //controller->v_q = v_q_ff; - - limit_norm(&controller->v_d, &controller->v_q, controller->v_bus); - - abc(controller->theta_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 - - //gpio->pwm_u->write(1.0f-controller->dtc_u); //write duty cycles - //gpio->pwm_v->write(1.0f-controller->dtc_v); - //gpio->pwm_w->write(1.0f-controller->dtc_w); - - //bing1 = (controller->dtc_u); - //bing2 = (controller->dtc_v); - //bing3 = (controller->dtc_w); - /* - //if(gpio->phasing){ - TIM1->CCR1 = 0x1194*(1.0f-controller->dtc_u); - TIM1->CCR2 = 0x1194*(1.0f-controller->dtc_v); - TIM1->CCR3 = 0x1194*(1.0f-controller->dtc_w); - } - else{ - TIM1->CCR3 = 0x1194*(1.0f-controller->dtc_u); - TIM1->CCR1 = 0x1194*(1.0f-controller->dtc_v); - TIM1->CCR2 = 0x1194*(1.0f-controller->dtc_w); - }*/ - //gpio->pwm_u->write(1.0f - .05f); //write duty cycles - //gpio->pwm_v->write(1.0f - .05f); - //gpio->pwm_w->write(1.0f - .1f); - //TIM1->CCR1 = 0x708*(1.0f-controller->dtc_u); - //TIM1->CCR2 = 0x708*(1.0f-controller->dtc_v); - //TIM1->CCR3 = 0x708*(1.0f-controller->dtc_w); - 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("%d %f\n\r", ind, cogging_current); - //printf("%f\n\r", controller->theta_elec); - //pc.printf("%f %f %f\n\r", controller->i_a, controller->i_b, controller->i_c); - //pc.printf("%f %f\n\r", controller->i_d, controller->i_q); - //pc.printf("%d %d\n\r", controller->adc1_raw, controller->adc2_raw); - } - } - -/* -void zero_encoder(ControllerStruct *controller, GPIOStruct *gpio, ){ - - } -*/ - -void voltageabc( float theta, float d, float q, float *a, float *b, float *c){ - ///Phase current amplitude = lengh of dq vector/// - ///i.e. iq = 1, id = 0, peak phase current of 1/// - - *a = sinf(theta); - *b = sinf((2.0f*PI/3.0f)+theta); - *c = sinf((-2.0f*PI/3.0f)+theta); - } - - - - - - - \ No newline at end of file
diff -r 9edd6ec0f56a -r 94193b31f0ee FOC/foc.h --- a/FOC/foc.h Sat May 20 21:42:20 2017 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,19 +0,0 @@ -#ifndef FOC_H -#define FOC_H - -#include "structs.h" -#include "PositionSensor.h" -#include "mbed.h" -#include "math.h" -#include "math_ops.h" -#include "motor_config.h" -#include "current_controller_config.h" - -void abc(float theta, float d, float q, float *a, float *b, float *c); -void dq0(float theta, float a, float b, float c, float *d, float *q); -void svm(float v_bus, float u, float v, float w, float *dtc_u, float *dtc_v, float *dtc_w); -void zero_current(int *offset_1, int *offset_2); -void reset_foc(ControllerStruct *controller); -void commutate(ControllerStruct *controller, GPIOStruct *gpio, float theta); -void voltageabc(float theta, float d, float q, float *a, float *b, float *c); -#endif \ No newline at end of file
diff -r 9edd6ec0f56a -r 94193b31f0ee FastPWM.lib --- a/FastPWM.lib Sat May 20 21:42:20 2017 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1 +0,0 @@ -https://developer.mbed.org/users/benkatz/code/FastPWM3/#51c979bca21e
diff -r 9edd6ec0f56a -r 94193b31f0ee Inverter/Inverter.cpp --- a/Inverter/Inverter.cpp Sat May 20 21:42:20 2017 +0000 +++ b/Inverter/Inverter.cpp Sat Apr 06 02:16:12 2019 +0000 @@ -1,96 +1,111 @@ +#include "Inverter.h" -#include "mbed.h" -#include "hw_pins.h" -//#include "hw_config.h" -#include "structs.h" -#include "FastPWM.h" + + +//Condensing all hardware related variables into just this file. +//This includes all the register diddling, assigning duty cycles, etc. +//should probably have a class called "inverter" but thats a lot of effort + +Inverter::Inverter(){ -void Init_PWM(GPIOStruct *gpio){ - printf("\nStarting Hardware Function\n\r"); + } + +void Inverter::Init_PWM(void){ - RCC->AHB1ENR |= RCC_AHB1ENR_GPIOCEN; // enable the clock to GPIOC - RCC->APB1ENR |= 0x00000001; // enable TIM2 clock - RCC->APB2ENR |= RCC_APB2ENR_TIM1EN; // enable TIM1 clock + printf("\nStarting Hardware PWM\n\r"); - GPIOC->MODER |= (1 << 10); // set pin 5 to be general purpose output for LED + RCC->AHBENR |= RCC_AHBENR_GPIOAEN; // enable the clock to GPIOA + RCC->APB2ENR |= RCC_APB2ENR_TIM1EN; // enable TIM1 clock - //gpio->enable = new DigitalOut(ENABLE_PIN); - gpio->pwm_ul = new FastPWM(PIN_AL); - gpio->pwm_vl = new FastPWM(PIN_BL); - gpio->pwm_wl = new FastPWM(PIN_CL); - gpio->pwm_uh = new FastPWM(PIN_AH); - gpio->pwm_vh = new FastPWM(PIN_BH); - gpio->pwm_wh = new FastPWM(PIN_CH); - - gpio->phasing = 1; - - //ISR Setup - - NVIC_EnableIRQ(TIM1_UP_TIM10_IRQn); //Enable TIM1 IRQ + //PWM Setup + TIM1->CCMR1 |= 0x0070; // Enable output compare 1 PWM mode 2 (inverted for low side shunts) + TIM1->CCER |= TIM_CCER_CC1E; // enable outputs 1 + //no dead time needed! + TIM1->BDTR |= TIM_BDTR_MOE; //main output enable = 1 + TIM1->PSC = 0x0; // no prescaler + TIM1->ARR = PWM_ARR; // set auto reload, 20 khz + TIM1->CR1 |= TIM_CR1_ARPE; // autoreload on, + RCC->CFGR3 |= RCC_CFGR3_TIM1SW; // bump tim1 up to 144MHz - TIM1->DIER |= TIM_DIER_UIE; // enable update interrupt - TIM1->CR1 = 0x40; // CMS = 10, interrupt only when counting up - TIM1->CR1 |= TIM_CR1_UDIS; - TIM1->CR1 |= TIM_CR1_ARPE; // autoreload on, - TIM1->RCR |= 0x001; // update event once per up/down count of tim1 + //hardware pin setup + GPIOA->MODER |= GPIO_MODER_MODER8_1 ; + GPIOA->AFR[1] |= 0x00000006; // PA8 to alternate function 6 + + //interrupt generation + NVIC_EnableIRQ(TIM1_UP_TIM16_IRQn); //Enable TIM1 IRQ //dafuq is this TIM16 BS? + TIM1->DIER |= TIM_DIER_UIE; // enable update interrupt + TIM1->CR1 |= 0x40; //CMS = 10, interrupt only when counting up + TIM1->RCR |= 0x001; // update event once per up/down count of tim1 TIM1->EGR |= TIM_EGR_UG; - - //PWM Setup - TIM1->DIER |= TIM_DIER_UIE; // enable update interrupt - TIM1->CR1 = 0x40;//CMS = 10, interrupt only when counting up - - TIM1->CR1 |= TIM_CR1_ARPE; // autoreload on, - TIM1->RCR |= 0x001; // update event once per up/down count of tim1 - TIM1->EGR |= TIM_EGR_UG; - - - //PWM Setup - TIM1->PSC = 0x0; // no prescaler, timer counts up in sync with the peripheral clock - TIM1->ARR = 0x1194; // 20 Khz - //TIM1->BDTR |= TIM_BDTR_MOE; - //TIM1->BDTR |= TIM_BDTR_OSSI; - //TIM1->BDTR |= TIM_BDTR_OSSR; - TIM1->BDTR |= 0xBF; - TIM1->CCER |= TIM_CCER_CC1E | TIM_CCER_CC1NE | TIM_CCER_CC2E | TIM_CCER_CC2NE | TIM_CCER_CC3E | TIM_CCER_CC3NE; - //TIM1->CCER |= ~TIM_CCER_CC1NP; //Interupt when low side is on. - //TIM1->CCER |= TIM_CCER_CC1NP; - TIM1->CR1 |= TIM_CR1_CEN; - + TIM1->CR1 |= TIM_CR1_CEN; //go! } -void Init_ADC(void){ +void Inverter::Init_ADC(void){ // ADC Setup - RCC->APB2ENR |= RCC_APB2ENR_ADC2EN; // clock for ADC2 - RCC->APB2ENR |= RCC_APB2ENR_ADC1EN; // clock for ADC1 - RCC->AHB1ENR |= RCC_AHB1ENR_GPIOCEN; // Enable clock for GPIOC - - ADC->CCR = 0x00000006; // Regular simultaneous mode only - ADC1->CR2 |= ADC_CR2_ADON;//0x00000001; // ADC1 ON - ADC1->SQR3 = 0x000000A; // use PC_0 as input this is the V phase - ADC2->CR2 |= ADC_CR2_ADON;//0x00000001; // ADC1 ON - ADC2->SQR3 = 0x0000000B; // use PC_1 as input. This is the U phase - GPIOC->MODER |= 0x0000000f; // Alternate function, PC_0, PC_1 are analog inputs + RCC->AHBENR |= RCC_AHBENR_GPIOAEN; + RCC->AHBENR |= RCC_AHBENR_GPIOBEN; + RCC->AHBENR |= RCC_AHBENR_ADC12EN; // clock for ADC1 and 2 enable + //RCC->AHBENR |= RCC_AHBENR_GPIOAEN; //page 149 on the ref manual + + ADC12_COMMON->CCR |= 0x20001; // Regular simultaneous mode plus injected conversions + + + //for board 3 + ADC1->SQR1 = 0x40; // use PA_0 as input, ADC1 in1 + ADC2->SQR1 = 0x40; // use PA_4 as input, ADC2 in1 + GPIOA->MODER |= 0x00000303; // Alternate function, PA_0, PA_4 are analog inputs - } + ADC1->SMPR1 = 32; //19.5 adc cock cycles for sample + ADC2->SMPR1 = 32; //19.5 adc cock cycles for sample. + + ADC2->CR |= ADC_CR_ADEN; + ADC1->CR |= ADC_CR_ADEN; + + wait_ms(10); -void Init_DAC(void){ - RCC->APB1ENR |= 0x20000000; // Enable clock for DAC - DAC->CR |= 0x00000001; // DAC control reg, both channels ON - GPIOA->MODER |= 0x00000300; // PA04 as analog output - } +} + -void Init_All_HW(GPIOStruct *gpio){ + + +void Inverter::Init(){ wait_ms(100); Init_ADC(); wait(0.1); + Init_PWM(); - //Init_DAC(); - wait(0.1); + } - Init_PWM(gpio); +void Inverter::zero_current(){ + int adc1_offset_s = 0; + int adc2_offset_s = 0; + int n = 1024; + for (int i = 0; i<n; i++){ + ADC1->CR |= ADC_CR_ADSTART; + //wait_us(5); + for (volatile int t = 0; t < 16; t++) {} + adc2_offset_s += ADC2->DR; + adc1_offset_s += ADC1->DR; + } + adc1_offset = adc1_offset_s/n; + adc2_offset = adc2_offset_s/n; + + } - } \ No newline at end of file +void Inverter::ADCsync() { + //EXTEN[1:0] = 01 + //EXTSEL[3:0] = 1010 + + //this code works to slave to center of TIM1 update + ADC1->CFGR |= ADC_CFGR_EXTEN_0 | ADC_CFGR_EXTEN_1; + ADC1->CFGR |= ADC_CFGR_EXTSEL_3 | ADC_CFGR_EXTSEL_1; + TIM1->CR2 |= TIM_CR2_MMS2_1; + ADC1->CR |= ADC_CR_ADSTART; +} + + + \ No newline at end of file
diff -r 9edd6ec0f56a -r 94193b31f0ee Inverter/Inverter.h --- a/Inverter/Inverter.h Sat May 20 21:42:20 2017 +0000 +++ b/Inverter/Inverter.h Sat Apr 06 02:16:12 2019 +0000 @@ -1,12 +1,31 @@ -#ifndef HW_PINS_H -#define HW_PINS_H +#ifndef INVERTER_H +#define INVERTER_H #include "mbed.h" +#include "inv_config.h" #include "structs.h" -void Init_PWM(GPIOStruct *gpio); -void Init_ADC(void); -void Init_DAC(void); -void Init_All_HW(GPIOStruct *gpio); + + + +class Inverter { +public: + Inverter(); + + void Init_PWM(void); + void Init_ADC(void); + void ADCsync(void); + void Init(void); + + void zero_current(); + + int adc1_raw, adc2_raw; + int adc1_offset, adc2_offset; + +private: + + + +}; #endif \ No newline at end of file
diff -r 9edd6ec0f56a -r 94193b31f0ee Inverter/inv_config.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Inverter/inv_config.h Sat Apr 06 02:16:12 2019 +0000 @@ -0,0 +1,13 @@ +#ifndef INV_CONFIG_H +#define INV_CONFIG_H + + + +#define I_SCALE 0.02014160156f // Amps per A/D Count +#define PWM_ARR 6400 +//#define PWM_ARR 2560 +// 1/(.002*1*20*4096/3.3) + + + +#endif \ No newline at end of file
diff -r 9edd6ec0f56a -r 94193b31f0ee PositionSensor/PositionSensor.cpp --- a/PositionSensor/PositionSensor.cpp Sat May 20 21:42:20 2017 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,272 +0,0 @@ - -#include "mbed.h" -#include "PositionSensor.h" -//#include "offset_lut.h" -//#include <math.h> -/* -PositionSensorAM5147::PositionSensorAM5147(int CPR, float offset, int ppairs){ - //_CPR = CPR; - _CPR = CPR; - _ppairs = ppairs; - ElecOffset = offset; - rotations = 0; - spi = new SPI(PC_12, PC_11, PC_10); - spi->format(16, 1); - spi->frequency(5000000); - cs = new DigitalOut(PA_15); - cs->write(1); - readAngleCmd = 0xffff; - MechOffset = 0; - modPosition = 0; - oldModPosition = 0; - oldVel = 0; - raw = 0; - } - -void PositionSensorAM5147::Sample(){ - cs->write(0); - raw = spi->write(readAngleCmd); - raw &= 0x3FFF; //Extract last 14 bits - cs->write(1); - int angle = raw + offset_lut[raw>>7]; - if(angle - old_counts > _CPR/2){ - rotations -= 1; - } - else if (angle - old_counts < -_CPR/2){ - rotations += 1; - } - - old_counts = angle; - oldModPosition = modPosition; - modPosition = ((6.28318530718f * ((float) angle))/ (float)_CPR); - position = (6.28318530718f * ((float) angle+(_CPR*rotations)))/ (float)_CPR; - MechPosition = position - MechOffset; - float elec = ((6.28318530718f/(float)_CPR) * (float) ((_ppairs*angle)%_CPR)) - ElecOffset; - if(elec < 0) elec += 6.28318530718f; - else if(elec > 6.28318530718f) elec -= 6.28318530718f ; - ElecPosition = elec; - - float vel; - if(modPosition<.1f && oldModPosition>6.1f){ - vel = (modPosition - oldModPosition + 6.28318530718f)*40000.0f; - } - else if(modPosition>6.1f && oldModPosition<0.1f){ - vel = (modPosition - oldModPosition - 6.28318530718f)*40000.0f; - } - else{ - vel = (modPosition-oldModPosition)*40000.0f; - } - - int n = 16; - float sum = vel; - for (int i = 1; i < (n); i++){ - velVec[n - i] = velVec[n-i-1]; - sum += velVec[n-i]; - } - velVec[0] = vel; - MechVelocity = sum/(float)n; - ElecVelocity = MechVelocity*_ppairs; - } - -int PositionSensorAM5147::GetRawPosition(){ - return raw; - } - -float PositionSensorAM5147::GetMechPosition(){ - return MechPosition; - } - -float PositionSensorAM5147::GetElecPosition(){ - return ElecPosition; - } - -float PositionSensorAM5147::GetMechVelocity(){ - return MechVelocity; - } - -void PositionSensorAM5147::ZeroPosition(){ - rotations = 0; - MechOffset = GetMechPosition(); - } - -void PositionSensorAM5147::SetElecOffset(float offset){ - ElecOffset = offset; - } - -int PositionSensorAM5147::GetCPR(){ - return _CPR; - } - - -void PositionSensorAM5147::WriteLUT(int new_lut[128]){ - memcpy(offset_lut, new_lut, sizeof(offset_lut)); - } - -*/ -PositionSensorEncoder::PositionSensorEncoder(int CPR, float offset, int ppairs) { - _ppairs = ppairs; - _CPR = CPR; - _offset = offset; - MechPosition = 0; - out_old = 0; - oldVel = 0; - raw = 0; - - // Enable clock for GPIOA - __GPIOA_CLK_ENABLE(); //equivalent from hal_rcc.h - - GPIOA->MODER |= GPIO_MODER_MODER6_1 | GPIO_MODER_MODER7_1 ; //PA6 & PA7 as Alternate Function /*!< GPIO port mode register, Address offset: 0x00 */ - GPIOA->OTYPER |= GPIO_OTYPER_OT_6 | GPIO_OTYPER_OT_7 ; //PA6 & PA7 as Inputs /*!< GPIO port output type register, Address offset: 0x04 */ - GPIOA->OSPEEDR |= GPIO_OSPEEDER_OSPEEDR6 | GPIO_OSPEEDER_OSPEEDR7 ; //Low speed /*!< GPIO port output speed register, Address offset: 0x08 */ - GPIOA->PUPDR |= GPIO_PUPDR_PUPDR6_1 | GPIO_PUPDR_PUPDR7_1 ; //Pull Down /*!< GPIO port pull-up/pull-down register, Address offset: 0x0C */ - GPIOA->AFR[0] |= 0x22000000 ; //AF02 for PA6 & PA7 /*!< GPIO alternate function registers, Address offset: 0x20-0x24 */ - GPIOA->AFR[1] |= 0x00000000 ; //nibbles here refer to gpio8..15 /*!< GPIO alternate function registers, Address offset: 0x20-0x24 */ - - // configure TIM3 as Encoder input - // Enable clock for TIM3 - __TIM3_CLK_ENABLE(); - - TIM3->CR1 = 0x0001; // CEN(Counter ENable)='1' < TIM control register 1 - TIM3->SMCR = TIM_ENCODERMODE_TI12; // SMS='011' (Encoder mode 3) < TIM slave mode control register - TIM3->CCMR1 = 0x0101; // CC1S='01' CC2S='01' < TIM capture/compare mode register 1, maximum digital filtering - TIM3->CCMR2 = 0x0000; // < TIM capture/compare mode register 2 - TIM3->CCER = 0x0011; // CC1P CC2P < TIM capture/compare enable register - TIM3->PSC = 0x0000; // Prescaler = (0+1) < TIM prescaler - TIM3->ARR = CPR; // IM auto-reload register - - TIM3->CNT = 0x000; //reset the counter before we use it - - // Extra Timer for velocity measurement - - __TIM2_CLK_ENABLE(); - TIM3->CR2 = 0x030; //MMS = 101 - - TIM2->PSC = 0x03; - //TIM2->CR2 |= TIM_CR2_TI1S; - TIM2->SMCR = 0x24; //TS = 010 for ITR2, SMS = 100 (reset counter at edge) - TIM2->CCMR1 = 0x3; // CC1S = 11, IC1 mapped on TRC - - //TIM2->CR2 |= TIM_CR2_TI1S; - TIM2->CCER |= TIM_CCER_CC1P; - //TIM2->CCER |= TIM_CCER_CC1NP; - TIM2->CCER |= TIM_CCER_CC1E; - - - TIM2->CR1 = 0x01; //CEN, enable timer - - TIM3->CR1 = 0x01; // CEN - ZPulse = new InterruptIn(PA_5); - ZSense = new DigitalIn(PA_5); - //ZPulse = new InterruptIn(PB_0); - //ZSense = new DigitalIn(PB_0); - ZPulse->enable_irq(); - ZPulse->rise(this, &PositionSensorEncoder::ZeroEncoderCount); - //ZPulse->fall(this, &PositionSensorEncoder::ZeroEncoderCountDown); - ZPulse->mode(PullDown); - flag = 0; - - - //ZTest = new DigitalOut(PC_2); - //ZTest->write(1); - } - -void PositionSensorEncoder::Sample(){ - - } - - -float PositionSensorEncoder::GetMechPosition() { //returns rotor angle in radians. - int raw = TIM3->CNT; - float unsigned_mech = (6.28318530718f/(float)_CPR) * (float) ((raw)%_CPR); - return (float) unsigned_mech;// + 6.28318530718f* (float) rotations; -} - -float PositionSensorEncoder::GetElecPosition() { //returns rotor electrical angle in radians. - int raw = TIM3->CNT; - float elec = ((6.28318530718f/(float)_CPR) * (float) ((_ppairs*raw)%_CPR)) - _offset; - if(elec < 0) elec += 6.28318530718f; - return elec; -} - - - -float PositionSensorEncoder::GetMechVelocity(){ - - float out = 0; - float rawPeriod = TIM2->CCR1; //Clock Ticks - int currentTime = TIM2->CNT; - if(currentTime > 2000000){rawPeriod = currentTime;} - float dir = -2.0f*(float)(((TIM3->CR1)>>4)&1)+1.0f; // +/- 1 - float meas = dir*180000000.0f*(6.28318530718f/(float)_CPR)/rawPeriod; - if(isinf(meas)){ meas = 1;} - out = meas; - //if(meas == oldVel){ - // out = .9f*out_old; - // } - - - oldVel = meas; - out_old = out; - int n = 16; - float sum = out; - for (int i = 1; i < (n); i++){ - velVec[n - i] = velVec[n-i-1]; - sum += velVec[n-i]; - } - velVec[0] = out; - return sum/(float)n; - } - -float PositionSensorEncoder::GetElecVelocity(){ - return _ppairs*GetMechVelocity(); - } - -void PositionSensorEncoder::ZeroEncoderCount(void){ - if (ZSense->read() == 1 & flag == 0){ - if (ZSense->read() == 1){ - GPIOC->ODR ^= (1 << 4); - TIM3->CNT = 0x000; - //state = !state; - //ZTest->write(state); - GPIOC->ODR ^= (1 << 4); - //flag = 1; - } - } - } - -void PositionSensorEncoder::ZeroPosition(void){ - - } - -void PositionSensorEncoder::ZeroEncoderCountDown(void){ - if (ZSense->read() == 0){ - if (ZSense->read() == 0){ - GPIOC->ODR ^= (1 << 4); - flag = 0; - float dir = -2.0f*(float)(((TIM3->CR1)>>4)&1)+1.0f; - if(dir != dir){ - dir = dir; - rotations += dir; - } - - GPIOC->ODR ^= (1 << 4); - - } - } - } -void PositionSensorEncoder::SetElecOffset(float offset){ - - } - -int PositionSensorEncoder::GetRawPosition(void){ - return 0; - } - -int PositionSensorEncoder::GetCPR(){ - return _CPR; - } - - -void PositionSensorEncoder::WriteLUT(int new_lut[128]){ - memcpy(offset_lut, new_lut, sizeof(offset_lut)); - }
diff -r 9edd6ec0f56a -r 94193b31f0ee PositionSensor/PositionSensor.h --- a/PositionSensor/PositionSensor.h Sat May 20 21:42:20 2017 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,65 +0,0 @@ -#ifndef POSITIONSENSOR_H -#define POSITIONSENSOR_H -class PositionSensor { -public: - virtual void Sample(void) = 0; - virtual float GetMechPosition() {return 0.0f;} - virtual float GetElecPosition() {return 0.0f;} - virtual float GetMechVelocity() {return 0.0f;} - virtual float GetElecVelocity() {return 0.0f;} - virtual void ZeroPosition(void) = 0; - virtual int GetRawPosition(void) = 0; - virtual void SetElecOffset(float offset) = 0; - virtual int GetCPR(void) = 0; - virtual void WriteLUT(int new_lut[128]) = 0; -}; - - -class PositionSensorEncoder: public PositionSensor { -public: - PositionSensorEncoder(int CPR, float offset, int ppairs); - virtual void Sample(); - virtual float GetMechPosition(); - virtual float GetElecPosition(); - virtual float GetMechVelocity(); - virtual float GetElecVelocity(); - virtual void ZeroPosition(void); - virtual void SetElecOffset(float offset); - virtual int GetRawPosition(void); - virtual int GetCPR(void); - virtual void WriteLUT(int new_lut[128]); -private: - InterruptIn *ZPulse; - DigitalIn *ZSense; - //DigitalOut *ZTest; - virtual void ZeroEncoderCount(void); - virtual void ZeroEncoderCountDown(void); - int _CPR, flag, rotations, _ppairs, raw; - //int state; - float _offset, MechPosition, MechOffset, dir, test_pos, oldVel, out_old, velVec[16]; - int offset_lut[128]; -}; -/* -class PositionSensorAM5147: public PositionSensor{ -public: - PositionSensorAM5147(int CPR, float offset, int ppairs); - virtual void Sample(); - virtual float GetMechPosition(); - virtual float GetElecPosition(); - virtual float GetMechVelocity(); - virtual int GetRawPosition(); - virtual void ZeroPosition(); - virtual void SetElecOffset(float offset); - virtual int GetCPR(void); - virtual void WriteLUT(int new_lut[128]); -private: - float position, ElecPosition, ElecOffset, MechPosition, MechOffset, modPosition, oldModPosition, oldVel, velVec[16], MechVelocity, ElecVelocity; - int raw, _CPR, rotations, old_counts, _ppairs; - SPI *spi; - DigitalOut *cs; - int readAngleCmd; - int offset_lut[128]; - -};*/ - -#endif \ No newline at end of file
diff -r 9edd6ec0f56a -r 94193b31f0ee ServoInput/ServoInput.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ServoInput/ServoInput.cpp Sat Apr 06 02:16:12 2019 +0000 @@ -0,0 +1,91 @@ +#include "mbed.h" +#include "ServoInput.h" + +//Takes servo inputs on PA2 + +ServoTimer::ServoTimer() { + + RCC->APB2ENR |= RCC_APB2ENR_TIM15EN; // enable TIM2 clock + + __GPIOA_CLK_ENABLE(); //PA2 TIM15 Servo Input + + GPIOA->MODER |= GPIO_MODER_MODER2_1; //PA2 as Alternate Function + GPIOA->OTYPER |= GPIO_OTYPER_OT_2; //PA2 as Inputs + GPIOA->OSPEEDR |= GPIO_OSPEEDER_OSPEEDR2; //Low speed + GPIOA->PUPDR |= GPIO_PUPDR_PUPDR2_1; //Pull Down + //GPIOA->AFR[0] |= 0x00000900 ; //AF0 + GPIOA->AFR[0] |= 0x00000900 ; //AF0 but Mbed is messed up. + GPIOA->AFR[0] &= ~0x00000600 ; //AF0 but Mbed is messed up. + GPIOA->AFR[1] |= 0x00000000 ; //AF1 + + __TIM15_CLK_ENABLE(); + + TIM15->PSC = 71; //timer counts a 1Mhz + + + //TIM15->SMCR = 0b0000000001000100; //TS = 100 (edge detection), SMS = 100 (trigger on counter reset) + //TIM15->OR |= 0x2; + + //setting it up in PWM input capture mode + //set CR1 to input mode? + + TIM15->SMCR = 0b0000000001010100; //TS = 101 (input 1 detection), SMS = 100 reset mode + + + TIM15->CCMR1 |= 0x200; // CC2S = 10, IC2 mapped to TI1 + TIM15->CCMR1 |= 0x1; // CC1S = 01, IC1 mapped to TI1 + TIM15->CCER |= TIM_CCER_CC1E | TIM_CCER_CC2E; // Enable OC1 and OC2 + TIM15->CCER |= TIM_CCER_CC2P | TIM_CCER_CC2NP; // set TI1FP2 to active on falling edge + + TIM15->CCMR1 |= TIM_CCMR1_IC1F_3; //enable some filtering + + TIM15->CR1 = 0x01; + + trash_input_count = 2; + oldCCR1 = 0; + servo_sig = 0; + + + +} + +void ServoTimer::update_servo_input() { + + if (TIM15->CNT > 40000) {TIM15->CNT = 40000; trash_input_count=30;} //pin stuck in some state + + + if (((TIM15->SR)>>1) & (0x01)) { //if an edge has recently occurred + + if ((TIM15->CCR2 < 2000)&(TIM15->CCR2 > 800)) { + //servo_sig = 0.95f*servo_sig + 0.05f*(float)TIM15->CCR2; + + trash_input_count = trash_input_count - 2; + + if (trash_input_count < 20) { + servo_sig = TIM15->CCR2; + } + } + else { + trash_input_count++; + } + } + + + + + + if (trash_input_count>=20) { servo_sig = 800; } + + if (trash_input_count>=30) { trash_input_count=20; } + if (trash_input_count<=0) { trash_input_count=0; } + +} + +int ServoTimer::get_servo_input() { + return servo_sig; +} + +int ServoTimer::get_trash_input() { + return trash_input_count; +} +
diff -r 9edd6ec0f56a -r 94193b31f0ee ServoInput/ServoInput.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ServoInput/ServoInput.h Sat Apr 06 02:16:12 2019 +0000 @@ -0,0 +1,27 @@ +#ifndef SERVOINPUT_H +#define SERVOINPUT_H + +#include "mbed.h" + + +class ServoTimer { +public: + ServoTimer(); + void update_servo_input(); + int get_trash_input(); + int get_servo_input(); + +private: + + int trash_input_count; + int oldCCR1; + int servo_sig; + +}; + + +#endif + + + +
diff -r 9edd6ec0f56a -r 94193b31f0ee fw_config.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/fw_config.h Sat Apr 06 02:16:12 2019 +0000 @@ -0,0 +1,32 @@ +#ifndef FW_CONFIG_H +#define FW_CONFIG_H + +//hardware stuff +#define R_S 0.027f //Ohms +#define L_S 0.00004f //Henries + + + +//current controler settings +#define KP 0.20f // Volts/Amp +#define KI 0.03f // 1/samples + + +#define V_BUS 24.0f // Volts, actual bus voltage +#define MAX_AMPS 100.0f + +#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 DT 0.00005f +#define F_SW 20000 + + +#define DTC_MAX 0.95f // Max phase duty cycle, determines current sensor read time +#define DTC_MIN 0.02f // Min phase duty cycle + + + +#endif +
diff -r 9edd6ec0f56a -r 94193b31f0ee hw_setup/current_controller_config.h --- a/hw_setup/current_controller_config.h Sat May 20 21:42:20 2017 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,21 +0,0 @@ -#ifndef CURRENT_CONTROLLER_CONFIG_H -#define CURRENT_CONTROLLER_CONFIG_H - -#define K_D .05f // Volts/Amp -#define K_Q .05f // Volts/Amp -#define KI_D 0.04f // 1/samples -#define KI_Q 0.04f // 1/samples -#define V_BUS 24.0f // Volts - -#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 DTC_MAX 0.95f // Max phase duty cycle -#define DTC_MIN 0.05f // Min phase duty cycle - -#define I_SCALE 0.02014160156f // Amps per A/D Count -// 1/(.002*1*20*4096/3.3) - - - -#endif
diff -r 9edd6ec0f56a -r 94193b31f0ee hw_setup/hw_pins.h --- a/hw_setup/hw_pins.h Sat May 20 21:42:20 2017 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,13 +0,0 @@ -#ifndef HW_PINS_H -#define HW_PINS_H - -#define PIN_AL PA_8 -#define PIN_BL PA_9 -#define PIN_CL PA_10 -#define PIN_AH PB_13 //U, the top fet -#define PIN_BH PB_14 -#define PIN_CH PB_15 //W, the bottom fet with no shunt amp - - - -#endif \ No newline at end of file
diff -r 9edd6ec0f56a -r 94193b31f0ee hw_setup/motor_config.h --- a/hw_setup/motor_config.h Sat May 20 21:42:20 2017 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,16 +0,0 @@ -#ifndef MOTOR_CONFIG_H -#define MOTOR_CONFIG_H - -//#define R_PHASE 0.105f //Ohms -//#define L_D 0.00003f //Henries -//#define L_Q 0.00003f //Henries -//#define KT .07f //N-m per peak phase amp (= RMS amps/1.5) -#define POLE_PAIRS 7 //Number of pole pairs - -//#define WB KT/NPP //Webers. - -#define ENC_TICKS_PER_REV 8192 - - - -#endif
diff -r 9edd6ec0f56a -r 94193b31f0ee main.cpp --- a/main.cpp Sat May 20 21:42:20 2017 +0000 +++ b/main.cpp Sat Apr 06 02:16:12 2019 +0000 @@ -1,241 +1,236 @@ #include "mbed.h" -#include "PositionSensor.h" -#include "structs.h" + +#include "fw_config.h" +#include "math_ops.h" +#include "Inverter.h" +#include "ServoInput.h" + + +/* + + +PA2 goes to servo input + +PA3-7, PA0-1 goes to analog input (on of those) -#include "Inverter.h" -//#define PI 3.14159f +use two of either PA8, 9, 10, +slaved with PA7, PB0, PB1 + +PA7 and PA8 for high and low sides + +PB6, 7 used for serial +PA13, 14, reset used for programming -#include "foc.h" +some other random pin used for LED +some other random pin used for clockpin, for debugging + + +====== +pins finally used by mike: +PA2: RC PWM +PA5: clockpin +PA8: gate drive +*/ -DigitalOut clockpin(PC_12); -//AnalogIn pot_in(PC_3); + + +DigitalOut clockpin(PA_5); +DigitalOut led1(PB_1); +DigitalIn gpio1(PA_6); + +//DigitalIn gpio2(PA_2); // controller modes #define REST_MODE 0 -#define OLSINE 1 -#define ONEUPTWODOWN 2 -#define VMODESINE 3 -//#define BEN_CALIBRATION_MODE 1 -#define TORQUE_MODE 4 -//#define PD_MODE 5 -//#define SETUP_MODE 6 -//#define ENCODER_MODE 7 - +#define VOLTAGE_MODE 1 +#define CURRENT_MODE 2 + -GPIOStruct gpio; -ControllerStruct controller; +volatile int count = 0; +volatile int main_int_count = 0; +volatile unsigned int main_int_clock = 0; + +int controller_state = 0; -//float fake_theta = 0.0; -float theta1 = 0.0f; -//float theta_offset = 4.708f; -//float theta_offset = 3.38f; -//float theta_offset = 4.97f; -float theta_offset = 4.8f; +Serial pc(PB_6, PB_7); +Inverter inverter; +ServoTimer servoinp; -int bing1 = 0; -int bing2 = 0; -int bing3 = 0; + +float a1 = 0.0f; +float a2 = 0.0f; + -int var1 = 0; -int var2 = 0; +float current = 0.0f; +float current_raw = 0.0f; +float servo_cmd = 0.0f; -float a = 0.0f; -float b = 0.0f; -float c = 0.0f; -volatile int count = 0; - -int controller_state = ONEUPTWODOWN;//VMODESINE; +int servo_low = 890; +int servo_high = 1800; +int servo_range = servo_high - servo_low; -Serial pc(PA_2, PA_3); -PositionSensorEncoder encoder(ENC_TICKS_PER_REV, 0, POLE_PAIRS); // Main 20khz loop Interrupt /// -/// This runs at 20 kHz, regardless of of the mode the controller is in, because it is triggered by hw timers /// -extern "C" void TIM1_UP_TIM10_IRQHandler(void) { - //clockpin = 1; + +extern "C" void TIM1_UP_TIM16_IRQHandler(void) { if (TIM1->SR & TIM_SR_UIF ) { + + main_int_count++; + main_int_clock++; + + // + //current_raw = float(ADC1->DR) - float(inverter.adc1_offset); + current_raw = float(ADC1->DR) - 2000; + //current_raw = float(ADC1->DR)); + //current = current_raw*0.1f; //depends on shunts + + inverter.adc2_raw = ADC2->DR; + inverter.adc1_raw = ADC1->DR; + clockpin = 1; + servoinp.update_servo_input(); - ///Sample current always /// - ADC1->CR2 |= 0x40000000; //Begin sample and conversion - //volatile int delay; - //for (delay = 0; delay < 55; delay++); - controller.adc2_raw = ADC2->DR; - controller.adc1_raw = ADC1->DR; - - - /// Check state machine state, and run the appropriate function /// - //printf("%d\n\r", state); switch(controller_state){ case REST_MODE: //nothing - if(count > 1000){ + TIM1->CCR1 = 6400; + count++; + if(count > 20000){ count = 0; - printf("Rest Mode"); - printf("\n\r"); + led1 = !led1; } - break; + servo_cmd = servoinp.get_servo_input(); + + break; + - case OLSINE: // open loop sines + case VOLTAGE_MODE: + + servo_cmd = servoinp.get_servo_input(); - //theta1+= 0.1f*pot_in; - theta1+= 0.001f; - if (theta1 > 2*PI) { theta1-=(2*PI); } - - //trigger clock pin sychronous with electrical revolutions - if (theta1 > PI) { clockpin = 1; } - else {clockpin = 0;} + TIM1->CCR1 = 6400 - constrain((servo_cmd-880)*8.0f , 0, 6150); //0 to 96% duty cycle - a = cosf(theta1)/2 + 0.5f; - b = cosf(( 2.0f*PI/3.0f)+theta1)/2 + 0.5f; - c = cosf((-2.0f*PI/3.0f)+theta1)/2 + 0.5f; - - TIM1->CCR1 = 0x1194*(a); - TIM1->CCR2 = 0x1194*(b); - TIM1->CCR3 = 0x1194*(c); - break; + if(count > 10000){ count = 0; } + + break; + + case CURRENT_MODE: - case ONEUPTWODOWN: // one up, two down - - a = 0.8f; - b = 0.2f; - c = 0.2f; + servo_cmd = servoinp.get_servo_input(); + /* + float current_setpoint = (servo_cmd-880)/100; //0 to 10 amps + if (current > current_setpoint) { + //set bridge state to LOW + TIM1->CCR1 = 6100; + } + else { + TIM1->CCR1 = 300; + }*/ + - count++; - if(count > 500){ - count = 0; - //printf("%f ",encoder.GetElecPosition()); + // servo inputs go from 880 to 1700 + + // the constant in the next line is set 1800/servo_range + //float current_setpoint_raw = (servo_cmd-servo_low)*2.25f; //scales 800 range to 1800 + float current_setpoint_raw = constrain((servo_cmd-servo_low)*2.0f , 0, 800); //scales 800 range to 1800 + if (current_raw > current_setpoint_raw) { + //set bridge state to LOW + TIM1->CCR1 = 6400; + } + else { + TIM1->CCR1 = 250; } - TIM1->CCR1 = 0x1194*(a); - TIM1->CCR2 = 0x1194*(b); - TIM1->CCR3 = 0x1194*(c); - break; - - case VMODESINE: // position mode sines - theta1 = encoder.GetElecPosition() + theta_offset; - - if (theta1 > 2*PI) { - theta1-=(2*PI); + if ((servo_cmd < servo_low) & (current_raw < 200) & (current_raw > -200)) { + TIM1->CCR1 = 6400; } - - //trigger clock pin sychronous with electrical revolutions - if (encoder.GetElecPosition() > PI) { clockpin = 1; } - else {clockpin = 0;} - - a = cosf(theta1)/2 + 0.5f; - b = cosf(( 2.0f*PI/3.0f)+theta1)/2 + 0.5f; - c = cosf((-2.0f*PI/3.0f)+theta1)/2 + 0.5f; - - TIM1->CCR1 = 0x1194*(a); - TIM1->CCR2 = 0x1194*(b); - TIM1->CCR3 = 0x1194*(c); - //remove this code later - //print Q and D values - count++; - // Run current loop - //spi.Sample(); // Sample position sensor - if(count > 1000){ - count = 0; - //printf("%f ",controller.i_q); - //printf("%f ",controller.i_d); - //printf("\n\r"); - } + if(count > 10000){ count = 0; } - break; - - case TORQUE_MODE: - - // Run torque control - count++; - controller.theta_elec = encoder.GetElecPosition() + theta_offset; - commutate(&controller, &gpio, controller.theta_elec); // Run current loop - //spi.Sample(); // Sample position sensor - if(count > 1000){ - count = 0; - //readCAN(); - //controller.i_q_ref = ((float)(canCmd-1000))/100; - controller.i_q_ref = 2; - //pc.printf("%f\n\r ", controller.theta_elec); + break; - //printf("%i ",controller.adc1_raw); - //printf("%i \n\r ",controller.adc2_raw); - } - } - - - ///* - - controller.theta_elec = encoder.GetElecPosition() + theta_offset; - commutate(&controller, &gpio, controller.theta_elec); - - - - //*/ + + } } + //b = TIM1->CNT; TIM1->SR = 0x0; - //clockpin = 0; // reset the status register + clockpin = 0; // reset the status register } int main() { - //float meas; - pc.baud(115200); - printf("\nStarting Hardware\n"); - Init_All_HW(&gpio); + wait_ms(200); + pc.baud(256000); + printf("\rStarting Hardware\n"); + gpio1.mode(PullUp); + - zero_current(&controller.adc1_offset, &controller.adc2_offset); // Setup PWM, ADC, GPIO + inverter.Init(); // Setup PWM, ADC + wait(0.1); + controller_state = REST_MODE; + wait(0.1); + inverter.zero_current(); wait(0.1); + pc.printf("ADCs zeroed at "); + pc.printf("%i, %i \n",inverter.adc1_offset,inverter.adc2_offset); + wait(0.1); + inverter.ADCsync(); + + + //controller_state = VOLTAGE_MODE; + controller_state = CURRENT_MODE; + while(1) { - //printf("AnalogIn example\n"); - //printf("%f ",a); - //printf("\n"); - wait(0.1); - - if (0==0) { - //printf("%i ", TIM3->CNT); - - printf("%f ",encoder.GetElecPosition()); - //printf("%f ",encoder.GetMechPosition()); - - printf("%f ",theta_offset); + + wait_us(2); - printf("%i ",controller.adc1_raw); - printf("%i ",controller.adc2_raw); - - printf("%i ",controller.adc1_offset); - printf("%i ",controller.adc2_offset); + while (1==1) { + + wait_us(30); + + pc.printf("%f, ", servo_cmd); - printf("%f ",controller.i_q); - printf("%f ",controller.i_d); + pc.printf("%f, ", current_raw); - printf("%f ",controller.i_a); - printf("%f ",controller.i_b); - - //printf("%f ",controller.theta_elec); + pc.printf("%f, ", float(inverter.adc1_offset)); + pc.printf("%f, ", a1); + pc.printf("%f, ", a2); - - printf("\n\r"); - + //printf("%i, ", b3); + //printf("%i, ", b4); + + //pc.printf("%i, ", TIM15->CNT); + //pc.printf("%x ", GPIOA->AFR[0]); + + pc.printf("%i, ", ADC1->DR); + pc.printf("%i, ", ADC2->DR); + //printf(" %i, %i %i", a1, a2, a3); + //if (gpio2) {pc.printf("low ");} + pc.printf("\r"); + + } - - - - + } } + + + + + + +
diff -r 9edd6ec0f56a -r 94193b31f0ee math_ops/math_ops.cpp --- a/math_ops/math_ops.cpp Sat May 20 21:42:20 2017 +0000 +++ b/math_ops/math_ops.cpp Sat Apr 06 02:16:12 2019 +0000 @@ -25,3 +25,20 @@ *y = *y * limit/norm; } } + +void limit_abs(float *x, float limit){ + limit = abs(limit); + if(*x > limit){ + *x = limit; + } + if(*x < -limit){ + *x = -limit; + } + } + +float constrain(float x, float bot, float top){ + x = (((x)>(top))?(top):(x)); + x = (((x)<(bot))?(bot):(x)); + return x; +} + \ No newline at end of file
diff -r 9edd6ec0f56a -r 94193b31f0ee math_ops/math_ops.h --- a/math_ops/math_ops.h Sat May 20 21:42:20 2017 +0000 +++ b/math_ops/math_ops.h Sat Apr 06 02:16:12 2019 +0000 @@ -10,5 +10,7 @@ float fmaxf3(float x, float y, float z); float fminf3(float x, float y, float z); void limit_norm(float *x, float *y, float limit); +void limit_abs(float *x, float limit); +float constrain(float x, float bot, float top); #endif
diff -r 9edd6ec0f56a -r 94193b31f0ee mbed.bld --- a/mbed.bld Sat May 20 21:42:20 2017 +0000 +++ b/mbed.bld Sat Apr 06 02:16:12 2019 +0000 @@ -1,1 +1,1 @@ -https://mbed.org/users/mbed_official/code/mbed/builds/97feb9bacc10 \ No newline at end of file +http://mbed.org/users/mbed_official/code/mbed/builds/fb8e0ae1cceb \ No newline at end of file
diff -r 9edd6ec0f56a -r 94193b31f0ee structs.h --- a/structs.h Sat May 20 21:42:20 2017 +0000 +++ b/structs.h Sat Apr 06 02:16:12 2019 +0000 @@ -1,48 +1,28 @@ #ifndef STRUCTS_H #define STRUCTS_H -//#include "CANnucleo.h" #include "mbed.h" -#include "FastPWM.h" - -typedef struct{ - DigitalOut *enable; - FastPWM *pwm_ul, *pwm_vl, *pwm_wl, *pwm_uh, *pwm_vh, *pwm_wh; - int phasing; - } GPIOStruct; - -typedef struct{ - - }COMStruct; typedef struct{ - int adc1_raw, adc2_raw; - float i_a, i_b, i_c; + + float i_motor; float v_bus; - float theta_mech, theta_elec; - float dtheta_mech, dtheta_elec; - float i_d, i_q; - float v_d, v_q; - float dtc_u, dtc_v, dtc_w; - float v_u, v_v, v_w; - float d_int, q_int; - int adc1_offset, adc2_offset; - float i_d_ref, i_q_ref; + float v_output; int loop_count; int mode; - float cogging[128]; - } ControllerStruct; + } HardwareStruct; + + + + typedef struct{ - float vel_1; - float vel_1_old; - float vel_1_est; - float vel_2; - float vel_2_old; - float vel_2_est; - float ts; - float est; - } VelocityEstimatorStruct; + int can_dead_count; + float throttle_frac; + int status; + } CommandStruct; + + #endif