@electric_vehicle_lover
OK, I got the motor running smoothly quite easily by the procedure You stated - manually calibrate MOTOR_ROTOR_DELTA_PHASE_ANGLE_RIGHT and the ...LEFT one as well. Here are the values that worked for me: #if MOTOR_TYPE == MOTOR_TYPE_EUC1
#define MOTOR_ROTOR_DELTA_PHASE_ANGLE_RIGHT 5
#define MOTOR_ROTOR_DELTA_PHASE_ANGLE_LEFT -52 About Your question regarding my purchase of the board(s)... I'll tell a little more of my backstory:
Almost a year ago I was asked if I could develop electronics and firmware for something similar to electric unicycle, so I was given few of these boards. As I, quite frankly, did not estimate correctly the time this all would take (given, I'm also studying at university, and have not previously done PMSM control), I have not finished the project to this day.
In the year, however, I did try to port the VESC code to non-ChibiOS STM32F4 ("bare metal"), read a lot of publications/materials about FOC control, state observers, SVM, PMSM. So, about STM32 flashing - as I remember I also wired JLink programmer to NRST pin of the MCU. So there was no problem with that back then. Now I don't need that NRST pin, as I had to fix a non-working board from multiple non-working, thus I used hot air to resolder the same MCU I used a year ago.
So now I read your code more thoroughly and most of it makes sense to me. In few places I didn't understand what was the idea of that part of the code.
For example, pwm_duty_cycle_controller.c:420-421 - what is the idea behind this re-calculation.
in the PWM_PERIOD_INTERRUPT() interrupt, I tried to follow the TIM3 setup code, and it seemed to me that it was configured to fire event only a single time per upcount + downcount (so as no if(...) would be required), and I can confirm with an LED and oscilloscope, that it indeed fires only once per 50us cycle. (Actually it did fire twice if I did turn the LED off after TIM_ClearITPendingBit(TIM3, TIM_IT_Update); , but that seems understandable)
I don't fully understand the part with #define DO_INTERPOLATION 1, which You have currently implemented in place of an observer.
To my understanding (and correct me if I'm wrong), duty_cycle (by your naming convention) sets the SVM PWM amplitude, which effectively sets the power that should go to the motor, and by turning potentiometer to some value, MCU just tries to put current 90 degrees ahead of the current motor angle, such that all the power goes into torque, so effectively, it just tries to run it as fast as the friction and electrical losses cancel the power put into it. And (disregarding two possible directions) for low potentiometer values, it will rotate slower, because the losses are lower and for higher potentiometer values it will rotate faster as the losses become higher.
(BTW, I'd call duty_cycle something like "power" / "amplitude", as the actual duty cycle of the PWM changes as per SVM).
Moreover, I tried cleaning up / refactoring some of the code for me personally to be easier to follow. I could do a pull request (like this), but I did not create a new branch... What should I do? I would appreciate some help in this, if possible.
Little bit about what I noticed in the code:
About the SVM waveform: I saw that it was not generated to cover full amplitude of 0 to 1800. Also, the 0th element of array is not 900, so at angle 0, the SVM angle is not 0. In my SVM version I corrected these things. I think that this corresponds to " -1 " you have in https://github.com/EGG-electric-unicycle/firmware-gen2_boards/blob/modifiedFOC-motorMicroWorks30kmh/motor_foc.c#L145here.
Also, there were some if-else statements, for which if and else parts did the same thing. And that same code copied 3 times with 1 parameter change (I did put it into inline function).
And then I checked, what You were printing out in every 10th FOC_slow_loop() iteration. And for me i_d, i_q values are not stable at all, which I expect to be almost constant.
Cheers,
Zigmars