Skip to content

Commit fe198f1

Browse files
committed
Dev. Changes
Field-Stack Work
1 parent fa0ddf3 commit fe198f1

File tree

14 files changed

+343
-410
lines changed

14 files changed

+343
-410
lines changed

src/SimpleFOC.h

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -108,10 +108,11 @@ void loop() {
108108
#include "drivers/BLDCDriver3PWM.h"
109109
#include "drivers/BLDCDriver6PWM.h"
110110
#include "drivers/StepperDriver4PWM.h"
111+
#include "drivers/StepperDriver8PWM.h"
111112
#include "drivers/StepperDriver2PWM.h"
112-
#include "current_sense/InlineCurrentSense.h"
113-
#include "current_sense/LowsideCurrentSense.h"
114-
#include "current_sense/GenericCurrentSense.h"
113+
//#include "current_sense/InlineCurrentSense.h"
114+
//#include "current_sense/LowsideCurrentSense.h"
115+
//#include "current_sense/GenericCurrentSense.h"
115116
#include "communication/Commander.h"
116117
#include "communication/StepDirListener.h"
117118
#include "communication/SimpleFOCDebug.h"

src/StepperMotor.cpp

Lines changed: 83 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
#include "StepperMotor.h"
22
#include "./communication/SimpleFOCDebug.h"
3+
#include "arm_math.h"
4+
35

46

57
// StepperMotor(int pp)
@@ -187,19 +189,19 @@ int StepperMotor::alignSensor() {
187189
// align the electrical phases of the motor and sensor
188190
// set angle -90(270 = 3PI/2) degrees
189191
setPhaseVoltage(voltage_sensor_align, 0, _3PI_2);
190-
_delay(700);
192+
_delay(2000);
191193
// read the sensor
192194
sensor->update();
193195
// get the current zero electric angle
194196
zero_electric_angle = 0;
195197
zero_electric_angle = electricalAngle();
196-
_delay(20);
198+
_delay(2000);
197199
if(monitor_port){
198200
SIMPLEFOC_DEBUG("MOT: Zero elec. angle: ", zero_electric_angle);
199201
}
200202
// stop everything
201203
setPhaseVoltage(0, 0, 0);
202-
_delay(200);
204+
_delay(1000);
203205
}else SIMPLEFOC_DEBUG("MOT: Skip offset calib.");
204206
return exit_flag;
205207
}
@@ -257,7 +259,7 @@ void StepperMotor::loopFOC() {
257259
electrical_angle = electricalAngle();
258260

259261
// set the phase voltage - FOC heart function :)
260-
setPhaseVoltage(voltage.q, voltage.d, electrical_angle);
262+
setPhaseVoltageCORDIC_LL(voltage.q, voltage.d, electrical_angle);
261263
}
262264

263265
// Iterative function running outer loop of the FOC algorithm
@@ -357,6 +359,8 @@ void StepperMotor::move(float new_target) {
357359
void StepperMotor::setPhaseVoltage(float Uq, float Ud, float angle_el) {
358360
// Sinusoidal PWM modulation
359361
// Inverse Park transformation
362+
////SerialUSB.println("ange_el -> ");
363+
//SerialUSB.println(angle_el);
360364

361365
// angle normalization in between 0 and 2pi
362366
// only necessary if using _sin and _cos - approximation functions
@@ -367,8 +371,18 @@ void StepperMotor::setPhaseVoltage(float Uq, float Ud, float angle_el) {
367371
Ualpha = _ca * Ud - _sa * Uq; // -sin(angle) * Uq;
368372
Ubeta = _sa * Ud + _ca * Uq; // cos(angle) * Uq;
369373

370-
// set the voltages in hardware
374+
//set the voltages in hardware
371375
driver->setPwm(Ualpha, Ubeta);
376+
/*
377+
Serial.print("Ualpha:");
378+
Serial.print(Ualpha, 8);
379+
Serial.print(",");
380+
Serial.print("Ubeta:");
381+
Serial.print(Ubeta, 8);
382+
Serial.println();
383+
384+
*/
385+
372386
}
373387

374388
// Method using FOC to set Uq and Ud to the motor at the optimal angle
@@ -387,8 +401,8 @@ int32_t float_to_q31(float input) {
387401
int32_t q31_value;
388402
float value_f32_sine = 0;
389403
float value_f32_cosine = 0;
390-
float cordic_cosine = 0.0f;
391-
float cordic_sine = 0.0f;
404+
q31_t cordic_cosine;
405+
q31_t cordic_sine;
392406

393407
float wrap_to_1(float x) {
394408
while (x > 1.0f) {
@@ -404,38 +418,84 @@ float wrap_to_1(float x) {
404418
/// @param Uq
405419
/// @param Ud
406420
/// @param angle_el
407-
void StepperMotor::setPhaseVoltageCORDIC(float Uq, float Ud, float angle_el) {
408-
// Sinusoidal PWM modulation
409-
// Inverse Park transformation
410421

411-
// WHO U GONNA CALL? CORDIC ->
422+
#define PI32f 3.141592f
423+
424+
float cordic_sin_value;
425+
float cordic_cos_value;
426+
427+
void StepperMotor::setPhaseVoltageCORDIC_LL(float Uq, float Ud, float angle_el) {
428+
429+
430+
// convert angle flot to CORDICq31 format
431+
uint32_t angle31 = (uint32_t)(angle_el * (1UL << 31) / (1.0f * PI));
412432

413-
q31_value = float_to_q31(angle_el / (2.0f * pi));
433+
/* Write angle and start CORDIC execution */
414434

415-
CORDIC->WDATA = q31_value;
435+
// WHO U GONNA CALL? CORDIC ->
436+
437+
CORDIC->WDATA = angle31;
438+
q31_t cosOutput = (int32_t)CORDIC->RDATA;
439+
440+
// convert q31 result to float
441+
cordic_cos_value = (float)cosOutput / (float)0x80000000;
442+
443+
/* Read sine */
444+
q31_t sinOutput = (int32_t)CORDIC->RDATA;
445+
446+
// convert q31 results to float
447+
cordic_sin_value = (float)sinOutput / (float)0x80000000;
448+
449+
450+
451+
//value_f32_sine = wrap_to_1(value_f32_sine);
452+
//value_f32_cosine = wrap_to_1(value_f32_cosine);
453+
454+
455+
// Inverse park transform
456+
//Ualpha = value_f32_cosine * Ud - value_f32_sine * Uq; // -sin(angle) * Uq;
457+
//Ubeta = value_f32_sine * Ud + value_f32_cosine * Uq; // cos(angle) * Uq;
458+
459+
arm_inv_park_f32(Ud, Uq, &Ualpha, &Ubeta, cordic_sin_value, cordic_cos_value);
460+
461+
462+
463+
// set the voltages in hardware
464+
driver->setPwm(Ualpha, Ubeta);
465+
466+
467+
468+
}
469+
470+
471+
void StepperMotor::setPhaseVoltageCORDIC(float Uq, float Ud, float angle_el) {
472+
473+
474+
uint32_t q1_31_angle = (uint32_t)(angle_el * (1UL << 31) / (1.0f * PI));
475+
476+
// WHO U GONNA CALL? CORDIC ->
477+
CORDIC->WDATA = q1_31_angle;
416478
cordic_sine = CORDIC->RDATA;
417479
cordic_cosine = CORDIC->RDATA;
418480

419481
value_f32_sine = (float)cordic_sine/(float)0x80000000;
420482
value_f32_cosine = (float)cordic_cosine/(float)0x80000000;
421483

422-
if (angle_el < 0){
423484
value_f32_sine = wrap_to_1(value_f32_sine);
424-
value_f32_sine = value_f32_sine * -1;
425-
}
426-
427-
if (angle_el > 0){
428-
value_f32_sine = wrap_to_1(value_f32_sine);
429-
}
430-
431485
value_f32_cosine = wrap_to_1(value_f32_cosine);
432486

487+
433488
// Inverse park transform
434-
Ualpha = value_f32_cosine * Ud - value_f32_sine * Uq; // -sin(angle) * Uq;
435-
Ubeta = value_f32_sine * Ud + value_f32_cosine * Uq; // cos(angle) * Uq;
489+
//Ualpha = value_f32_cosine * Ud - value_f32_sine * Uq; // -sin(angle) * Uq;
490+
//Ubeta = value_f32_sine * Ud + value_f32_cosine * Uq; // cos(angle) * Uq;
491+
492+
arm_inv_park_f32(Ud, Uq, &Ualpha, &Ubeta, value_f32_sine, value_f32_cosine);
436493

437494
// set the voltages in hardware
438495
driver->setPwm(Ualpha, Ubeta);
496+
497+
498+
439499
}
440500

441501

src/StepperMotor.h

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,8 @@ class StepperMotor: public FOCMotor
7979

8080
float Ualpha,Ubeta; //!< Phase voltages U alpha and U beta used for inverse Park and Clarke transform
8181

82+
uint16_t countervalue; //!< counter value for the open loop control TIM3->CNT;
83+
8284
/**
8385
* Method using FOC to set Uq to the motor at the optimal angle
8486
* Heart of the FOC algorithm
@@ -93,10 +95,15 @@ class StepperMotor: public FOCMotor
9395

9496
void setPhaseVoltageCORDIC(float Uq, float Ud, float angle_el) override;
9597

96-
private:
98+
99+
void setPhaseVoltageCORDIC_LL(float Uq, float Ud, float angle_el) override;
100+
101+
int alignSensor();
102+
103+
97104

98105
/** Sensor alignment to electrical 0 angle of the motor */
99-
int alignSensor();
106+
100107
/** Motor and sensor alignment to the sensors absolute 0 angle */
101108
int absoluteZeroSearch();
102109

@@ -117,6 +124,8 @@ class StepperMotor: public FOCMotor
117124
float angleOpenloop(float target_angle);
118125
// open loop variables
119126
long open_loop_timestamp;
127+
128+
private:
120129
};
121130

122131

src/common/base_classes/FOCMotor.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,8 @@ class FOCMotor
142142

143143
virtual void setPhaseVoltageCORDIC(float Uq, float Ud, float angle_el)=0;
144144

145+
virtual void setPhaseVoltageCORDIC_LL(float Uq, float Ud, float angle_el)=0;
146+
145147
// State calculation methods
146148
/** Shaft angle calculation in radians [rad] */
147149
float shaftAngle();
@@ -162,6 +164,7 @@ class FOCMotor
162164
float target; //!< current target value - depends of the controller
163165
float shaft_angle;//!< current motor angle
164166
float electrical_angle;//!< current electrical angle
167+
float electrical_angle2;//!< current electrical angle
165168
float shaft_velocity;//!< current motor velocity
166169
float current_sp;//!< target current ( q current )
167170
float shaft_velocity_sp;//!< current target velocity

src/common/base_classes/Sensor.cpp

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -17,14 +17,14 @@ void Sensor::update() {
1717
/** get current angular velocity (rad/s) */
1818
float Sensor::getVelocity() {
1919
// calculate sample time
20-
float Ts = (angle_prev_ts - vel_angle_prev_ts)*1e-6;
21-
// TODO handle overflow - we do need to reset vel_angle_prev_ts
22-
if (Ts < min_elapsed_time) return velocity; // don't update velocity if deltaT is too small
23-
24-
velocity = ( (float)(full_rotations - vel_full_rotations)*_2PI + (angle_prev - vel_angle_prev) ) / Ts;
25-
vel_angle_prev = angle_prev;
26-
vel_full_rotations = full_rotations;
27-
vel_angle_prev_ts = angle_prev_ts;
20+
bool isCountingUpward = TIM3->CR1 & 0x0010 ? false : true;
21+
22+
uint32_t timer2 = TIM2 -> CCR1;
23+
float velocity = (4 * PI / 65536) * 168000000 / ((float)timer2 - 1.0f);
24+
25+
if (!isCountingUpward) {
26+
velocity = -velocity;}
27+
2828
return velocity;
2929
}
3030

src/common/base_classes/StepperDriver.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,12 @@ float voltage_limit; //!< limiting voltage set to the motor
1919
bool initialized = false; // true if driver was successfully initialized
2020
void* params = 0; // pointer to hardware specific parameters of driver
2121

22+
float dc_1a; //!< currently set duty cycle on phaseA
23+
float dc_1b; //!< currently set duty cycle on phaseB
24+
float dc_1c; //!< currently set duty cycle on phaseC
25+
float dc_1d; //!< currently set duty cycle on phaseC
26+
27+
2228
/**
2329
* Set phase voltages to the hardware
2430
*

src/current_sense/hardware_specific/rp2040/rp2040_mcu.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -241,7 +241,6 @@ void RP2040ADCEngine::start() {
241241

242242
void RP2040ADCEngine::stop() {
243243
adc_run(false);
244-
irq_set_enabled(DMA_IRQ_0, false);
245244
dma_channel_abort(readDMAChannel);
246245
// if (triggerPWMSlice>=0)
247246
// dma_channel_abort(triggerDMAChannel);

src/current_sense/hardware_specific/stm32/stm32l4/stm32l4_utils.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -187,7 +187,7 @@ uint32_t _timerToRegularTRGO(HardwareTimer* timer){
187187
#endif
188188
#ifdef TIM8 // if defined timer 8
189189
else if(timer->getHandle()->Instance == TIM8)
190-
return ADC_EXTERNALTRIG_T8_TRGO;
190+
return ADC_EXTERNALTRIG_T7_TRGO;
191191
#endif
192192
#ifdef TIM15 // if defined timer 15
193193
else if(timer->getHandle()->Instance == TIM15)

src/drivers/BLDCDriver6PWM.cpp

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ int BLDCDriver6PWM::init() {
5555
pinMode(pwmB_l, OUTPUT);
5656
pinMode(pwmC_l, OUTPUT);
5757
if(_isset(enable_pin)) pinMode(enable_pin, OUTPUT);
58-
58+
Serial.println("Setting Pins to Output!");
5959

6060
// sanity check for the voltage limit configuration
6161
if( !_isset(voltage_limit) || voltage_limit > voltage_power_supply) voltage_limit = voltage_power_supply;
@@ -73,6 +73,12 @@ int BLDCDriver6PWM::init() {
7373
params = _configure6PWM(pwm_frequency, dead_zone, pwmA_h,pwmA_l, pwmB_h,pwmB_l, pwmC_h,pwmC_l);
7474
initialized = (params!=SIMPLEFOC_DRIVER_INIT_FAILED);
7575
return params!=SIMPLEFOC_DRIVER_INIT_FAILED;
76+
77+
// set phase state to enabled - if driver was successfully initialized
78+
phase_state[0] = PhaseState::PHASE_ON;
79+
phase_state[1] = PhaseState::PHASE_ON;
80+
phase_state[2] = PhaseState::PHASE_ON;
81+
7682
}
7783

7884

src/drivers/BLDCDriver6PWM.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ class BLDCDriver6PWM: public BLDCDriver
3636
int pwmA_h,pwmA_l; //!< phase A pwm pin number
3737
int pwmB_h,pwmB_l; //!< phase B pwm pin number
3838
int pwmC_h,pwmC_l; //!< phase C pwm pin number
39+
3940
int enable_pin; //!< enable pin number
4041
bool enable_active_high = true;
4142

0 commit comments

Comments
 (0)