diff --git a/Inc/eeprom.h b/Inc/eeprom.h index 85b4cf1c..616edd52 100644 --- a/Inc/eeprom.h +++ b/Inc/eeprom.h @@ -47,7 +47,8 @@ typedef union EEprom_u { uint8_t sine_mode_power; // 45 uint8_t input_type; // 46 uint8_t auto_advance; // 47 - uint8_t reserved_2[4]; //48-51 + uint8_t pwm_dithering; // 48 + uint8_t reserved_2[3]; //49-51 uint8_t tune[124]; // 52-175 struct { uint8_t can_node; // 176 diff --git a/Src/DroneCAN/DroneCAN.c b/Src/DroneCAN/DroneCAN.c index 0bde9e75..d1a42cd6 100644 --- a/Src/DroneCAN/DroneCAN.c +++ b/Src/DroneCAN/DroneCAN.c @@ -152,6 +152,7 @@ static const struct parameter { { "BEEP_VOLUME", T_UINT8, 0, 11, 5, &eepromBuffer.beep_volume}, { "VARIABLE_PWM", T_BOOL, 0, 1, 1, &eepromBuffer.variable_pwm}, { "PWM_FREQUENCY", T_UINT8, 8, 48, 24, &eepromBuffer.pwm_frequency}, + { "PWM_DITHERING", T_UINT8, 0, 200, 0, &eepromBuffer.pwm_dithering}, { "USE_SIN_START", T_BOOL, 0, 1, 0, &eepromBuffer.use_sine_start}, { "COMP_PWM", T_BOOL, 0, 1, 1, &eepromBuffer.comp_pwm}, { "STUCK_ROTOR_PROTECTION", T_BOOL, 0, 1, 1, &eepromBuffer.stuck_rotor_protection}, diff --git a/Src/main.c b/Src/main.c index a7a6d2c9..b1281f1f 100644 --- a/Src/main.c +++ b/Src/main.c @@ -750,6 +750,9 @@ void loadEEpromSettings() // if (!eepromBuffer.comp_pwm) { // eepromBuffer.bi_direction = 0; // } + if (eepromBuffer.pwm_dithering > 128) { + eepromBuffer.pwm_dithering = 0; + } } void saveEEpromSettings() @@ -1240,6 +1243,18 @@ if (!stepper_sine && armed) { #endif } +/* + calculate a PWM dithering value + */ +static uint16_t pwmDither(uint16_t reload, uint16_t dithering) +{ + // simple LCG random number generator + static uint8_t seed; + seed = (((uint32_t)seed) * 1103515245U + 12345U); + int16_t r = (seed % (dithering * 2)) - dithering; + return reload + r; +} + void tenKhzRoutine() { // 20khz as of 2.00 to be renamed duty_cycle = duty_cycle_setpoint; @@ -1408,10 +1423,19 @@ void tenKhzRoutine() fast_accel = 0; } } + + /* + possibly add PWM dithering to reduce impact of harmonics + */ + uint16_t tim1_arr_used = tim1_arr; + if (eepromBuffer.pwm_dithering > 0) { + tim1_arr_used = pwmDither(tim1_arr, eepromBuffer.pwm_dithering); + } + if ((armed && running) && input > 47) { if (eepromBuffer.variable_pwm) { } - adjusted_duty_cycle = ((duty_cycle * tim1_arr) / 2000) + 1; + adjusted_duty_cycle = ((duty_cycle * tim1_arr_used) / 2000) + 1; } else { @@ -1422,7 +1446,7 @@ void tenKhzRoutine() } } last_duty_cycle = duty_cycle; - SET_AUTO_RELOAD_PWM(tim1_arr); + SET_AUTO_RELOAD_PWM(tim1_arr_used); SET_DUTY_CYCLE_ALL(adjusted_duty_cycle); } #endif // ndef brushed_mode