Skip to content

Commit 3cc6933

Browse files
committed
Merge remote-tracking branch 'simplefoc/dev' into dev
2 parents f2ae008 + 37fd4af commit 3cc6933

File tree

15 files changed

+242
-32
lines changed

15 files changed

+242
-32
lines changed

README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,9 @@ Therefore this is an attempt to:
2020
> - bugfixes commander
2121
> - bugfix `voltage_limit` when provided `phase_resistance`
2222
> - bugfix `hall_sensor` examples
23+
> - added examples fot the powershield
24+
> - added initial support for `MagneticSensorPWM`
25+
> - extension of the `Commander` interface
2326
2427

2528
## Arduino *SimpleFOCShield* v2.0.3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
#include <SimpleFOC.h>
2+
3+
4+
/**
5+
* An example to find out the raw max and min count to be provided to the constructor
6+
* SPin your motor/sensor/magnet to see what is the maximum output of the sensor and what is the minimum value
7+
* And replace values 4 and 904 with new values. Once when you replace them make sure there is no jump in the angle reading sensor.getAngle().
8+
* If there is a jump that means you can still find better values.
9+
*/
10+
MagneticSensorPWM sensor = MagneticSensorPWM(2, 4, 904);
11+
void doPWM(){sensor.handlePWM();}
12+
13+
void setup() {
14+
// monitoring port
15+
Serial.begin(115200);
16+
17+
// initialise magnetic sensor hardware
18+
sensor.init();
19+
sensor.enableInterrupt(doPWM);
20+
21+
Serial.println("Sensor ready");
22+
_delay(1000);
23+
}
24+
25+
void loop() {
26+
// display the angle and the angular velocity to the terminal
27+
Serial.print(sensor.pulse_length_us);
28+
Serial.print("\t");
29+
Serial.println(sensor.getAngle());
30+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
#include <SimpleFOC.h>
2+
3+
4+
/**
5+
* Magnetic sensor reading pwm signal on pin 2. The pwm duty cycle is proportional to the sensor angle.
6+
*
7+
* MagneticSensorPWM(uint8_t MagneticSensorPWM, int _min, int _max)
8+
* - pinPWM - the pin that is reading the pwm from magnetic sensor
9+
* - min_raw_count - the smallest expected reading. Whilst you might expect it to be 0 it is often ~5. Getting this wrong results in a small click once per revolution
10+
* - max_raw_count - the largest value read. whilst you might expect it to be 1kHz = 1000 it is often ~910. depending on the exact frequency and saturation
11+
*/
12+
MagneticSensorPWM sensor = MagneticSensorPWM(2, 4, 904);
13+
void doPWM(){sensor.handlePWM();}
14+
15+
void setup() {
16+
// monitoring port
17+
Serial.begin(115200);
18+
19+
// initialise magnetic sensor hardware
20+
sensor.init();
21+
sensor.enableInterrupt(doPWM);
22+
23+
Serial.println("Sensor ready");
24+
_delay(1000);
25+
}
26+
27+
void loop() {
28+
// display the angle and the angular velocity to the terminal
29+
Serial.print(sensor.getAngle());
30+
Serial.print("\t");
31+
Serial.println(sensor.getVelocity());
32+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
#include <SimpleFOC.h>
2+
3+
// software interrupt library
4+
#include <PciManager.h>
5+
#include <PciListenerImp.h>
6+
7+
/**
8+
* Magnetic sensor reading analog voltage on pin which does not have hardware interrupt support. Such as A0.
9+
*
10+
* MagneticSensorPWM(uint8_t MagneticSensorPWM, int _min, int _max)
11+
* - pinPWM - the pin that is reading the pwm from magnetic sensor
12+
* - min_raw_count - the smallest expected reading. Whilst you might expect it to be 0 it is often ~5. Getting this wrong results in a small click once per revolution
13+
* - max_raw_count - the largest value read. whilst you might expect it to be 1kHz = 1000 it is often ~910. depending on the exact frequency and saturation
14+
*/
15+
MagneticSensorPWM sensor = MagneticSensorPWM(A0, 4, 904);
16+
void doPWM(){sensor.handlePWM();}
17+
18+
// encoder interrupt init
19+
PciListenerImp listenerPWM(sensor.pinPWM, doPWM);
20+
21+
void setup() {
22+
// monitoring port
23+
Serial.begin(115200);
24+
25+
// initialise magnetic sensor hardware
26+
sensor.init();
27+
PciManager.registerListener(&listenerPWM);
28+
29+
Serial.println("Sensor ready");
30+
_delay(1000);
31+
}
32+
33+
void loop() {
34+
// display the angle and the angular velocity to the terminal
35+
Serial.print(sensor.getAngle());
36+
Serial.print("\t");
37+
Serial.println(sensor.getVelocity());
38+
}

keywords.txt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ HallSensors KEYWORD1
88
MagneticSensorSPI KEYWORD1
99
MagneticSensorI2C KEYWORD1
1010
MagneticSensorAnalog KEYWORD1
11+
MagneticSensorPWM KEYWORD1
1112
BLDCDriver3PWM KEYWORD1
1213
BLDCDriver6PWM KEYWORD1
1314
BLDCDriver KEYWORD1
@@ -92,6 +93,8 @@ scalar KEYWORD2
9293
pid KEYWORD2
9394
lpf KEYWORD2
9495
motor KEYWORD2
96+
handlePWM KEYWORD2
97+
enableInterrupt KEYWORD2
9598

9699

97100

@@ -119,6 +122,8 @@ sensor_offset KEYWORD2
119122
zero_electric_angle KEYWORD2
120123
verbose KEYWORD2
121124
decimal_places KEYWORD2
125+
phase_resistance KEYWORD2
126+
modulation_centered KEYWORD2
122127

123128

124129

src/common/base_classes/CurrentSense.cpp

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,12 @@ float CurrentSense::getDCCurrent(float motor_electrical_angle){
1717
i_alpha = current.a;
1818
i_beta = _1_SQRT3 * current.a + _2_SQRT3 * current.b;
1919
}else{
20-
i_alpha = 2*(current.a - (current.b - current.c))/3.0;
21-
i_beta = _2_SQRT3 *( current.b - current.c );
20+
// signal filtering using identity a + b + c = 0. Assumes measurement error is normally distributed.
21+
float mid = (1.f/3) * (current.a + current.b + current.c);
22+
float a = current.a - mid;
23+
float b = current.b - mid;
24+
i_alpha = a;
25+
i_beta = _1_SQRT3 * a + _2_SQRT3 * b;
2226
}
2327

2428
// if motor angle provided function returns signed value of the current
@@ -44,9 +48,13 @@ DQCurrent_s CurrentSense::getFOCCurrents(float angle_el){
4448
// if only two measured currents
4549
i_alpha = current.a;
4650
i_beta = _1_SQRT3 * current.a + _2_SQRT3 * current.b;
47-
}else{
48-
i_alpha = 0.6666667*(current.a - (current.b - current.c));
49-
i_beta = _2_SQRT3 *( current.b - current.c );
51+
} else {
52+
// signal filtering using identity a + b + c = 0. Assumes measurement error is normally distributed.
53+
float mid = (1.f/3) * (current.a + current.b + current.c);
54+
float a = current.a - mid;
55+
float b = current.b - mid;
56+
i_alpha = a;
57+
i_beta = _1_SQRT3 * a + _2_SQRT3 * b;
5058
}
5159

5260
// calculate park transform

src/common/base_classes/FOCMotor.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -169,7 +169,7 @@ class FOCMotor
169169
LowPassFilter LPF_current_q{DEF_CURR_FILTER_Tf};//!< parameter determining the current Low pass filter configuration
170170
LowPassFilter LPF_current_d{DEF_CURR_FILTER_Tf};//!< parameter determining the current Low pass filter configuration
171171
PIDController PID_velocity{DEF_PID_VEL_P,DEF_PID_VEL_I,DEF_PID_VEL_D,DEF_PID_VEL_RAMP,DEF_PID_VEL_LIMIT};//!< parameter determining the velocity PID configuration
172-
PIDController P_angle{DEF_P_ANGLE_P,0,0,1e10,DEF_VEL_LIM}; //!< parameter determining the position PID configuration
172+
PIDController P_angle{DEF_P_ANGLE_P,0,0,0,DEF_VEL_LIM}; //!< parameter determining the position PID configuration
173173
LowPassFilter LPF_velocity{DEF_VEL_FILTER_Tf};//!< parameter determining the velocity Low pass filter configuration
174174
LowPassFilter LPF_angle{0.0};//!< parameter determining the angle low pass filter configuration
175175
unsigned int motion_downsample = DEF_MOTION_DOWNSMAPLE; //!< parameter defining the ratio of downsampling for move commad

src/common/defaults.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
#define DEF_PID_CURR_P 3 //!< default PID controller P value
2424
#define DEF_PID_CURR_I 300.0 //!< default PID controller I value
2525
#define DEF_PID_CURR_D 0.0 //!< default PID controller D value
26-
#define DEF_PID_CURR_RAMP 1e11 //!< default PID controller voltage ramp value
26+
#define DEF_PID_CURR_RAMP 0 //!< default PID controller voltage ramp value
2727
#define DEF_PID_CURR_LIMIT (DEF_POWER_SUPPLY) //!< default PID controller voltage limit
2828
#define DEF_CURR_FILTER_Tf 0.005 //!< default currnet filter time constant
2929
#endif

src/common/pid.cpp

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -40,13 +40,15 @@ float PIDController::operator() (float error){
4040
// antiwindup - limit the output variable
4141
output = _constrain(output, -limit, limit);
4242

43-
// limit the acceleration by ramping the output
44-
float output_rate = (output - output_prev)/Ts;
45-
if (output_rate > output_ramp)
46-
output = output_prev + output_ramp*Ts;
47-
else if (output_rate < -output_ramp)
48-
output = output_prev - output_ramp*Ts;
49-
43+
// if output ramp defined
44+
if(output_ramp > 0){
45+
// limit the acceleration by ramping the output
46+
float output_rate = (output - output_prev)/Ts;
47+
if (output_rate > output_ramp)
48+
output = output_prev + output_ramp*Ts;
49+
else if (output_rate < -output_ramp)
50+
output = output_prev - output_ramp*Ts;
51+
}
5052
// saving for the next pass
5153
integral_prev = integral;
5254
output_prev = output;

src/communication/Commander.cpp

Lines changed: 52 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -170,10 +170,10 @@ void Commander::motor(FOCMotor* motor, char* user_command) {
170170
}
171171
break;
172172
case CMD_MOTION_TYPE:
173-
printVerbose(F("Motion: "));
173+
printVerbose(F("Motion:"));
174174
switch(sub_cmd){
175175
case SCMD_DOWNSAMPLE:
176-
printVerbose(F("downsample: "));
176+
printVerbose(F(" downsample: "));
177177
if(!GET) motor->motion_downsample = value;
178178
println((int)motor->motion_downsample);
179179
break;
@@ -224,6 +224,38 @@ void Commander::motor(FOCMotor* motor, char* user_command) {
224224
if(!GET) (bool)value ? motor->enable() : motor->disable();
225225
println(motor->enabled);
226226
break;
227+
case CMD_PWMMOD:
228+
// PWM modulation change
229+
printVerbose(F("PWM Mod | "));
230+
switch (sub_cmd){
231+
case SCMD_PWMMOD_TYPE: // zero offset
232+
printVerbose(F("type: "));
233+
if(!GET) motor->foc_modulation = (FOCModulationType)value;
234+
switch(motor->foc_modulation){
235+
case FOCModulationType::SinePWM:
236+
println(F("SinePWM"));
237+
break;
238+
case FOCModulationType::SpaceVectorPWM:
239+
println(F("SVPWM"));
240+
break;
241+
case FOCModulationType::Trapezoid_120:
242+
println(F("Trap 120"));
243+
break;
244+
case FOCModulationType::Trapezoid_150:
245+
println(F("Trap 150"));
246+
break;
247+
}
248+
break;
249+
case SCMD_PWMMOD_CENTER: // centered modulation
250+
printVerbose(F("center: "));
251+
if(!GET) motor->modulation_centered = value;
252+
println(motor->modulation_centered);
253+
break;
254+
default:
255+
printError();
256+
break;
257+
}
258+
break;
227259
case CMD_RESIST:
228260
// enable/disable
229261
printVerbose(F("R phase: "));
@@ -271,15 +303,15 @@ void Commander::motor(FOCMotor* motor, char* user_command) {
271303
break;
272304
case 2: // get voltage d
273305
printVerbose(F("Vd: "));
274-
println(motor->voltage.q);
306+
println(motor->voltage.d);
275307
break;
276308
case 3: // get current q
277309
printVerbose(F("Cq: "));
278310
println(motor->current.q);
279311
break;
280312
case 4: // get current d
281313
printVerbose(F("Cd: "));
282-
println(motor->current.q);
314+
println(motor->current.d);
283315
break;
284316
case 5: // get velocity
285317
printVerbose(F("vel: "));
@@ -289,6 +321,22 @@ void Commander::motor(FOCMotor* motor, char* user_command) {
289321
printVerbose(F("angle: "));
290322
println(motor->shaft_angle);
291323
break;
324+
case 7: // get all states
325+
printVerbose(F("all: "));
326+
print(motor->target);
327+
print(";");
328+
print(motor->voltage.q);
329+
print(";");
330+
print(motor->voltage.d);
331+
print(";");
332+
print(motor->current.q);
333+
print(";");
334+
print(motor->current.d);
335+
print(";");
336+
print(motor->shaft_velocity);
337+
print(";");
338+
println(motor->shaft_angle);
339+
break;
292340
default:
293341
printError();
294342
break;

0 commit comments

Comments
 (0)