jayjay23

Firmware

1,187 posts in this topic

Hi everyone,
Wonderful work you have done here, including the documentation. (Especially I love those great videos on control theory. Nice find.)

I am trying to run latest version of this firmware (modifiedFOC-motorMicroWorks30kmh) on a 1st generation board (I think it's 1st gen... well, it's the one with a single XL7001 12V, 5V regulator). What I want is to try and reproduce similar behaviour as the original Chinese firmware (just on a bench setup, not driving it :)).
I commented out the section, which waited for some potentiometer value in the main.c and if I've understood correctly, what else I should do to get the desired behaviour:
(1) set the balance PID coefficients;
(2) set MOTOR_TYPE accordingly.

I was wondering if anybody could 
(a) say, am I missing something else that I should modify in code;
(b) tell what are PID parameters that have worked for You.

cheers,
Zigmars

0

Share this post


Link to post
Share on other sites
2 hours ago, zii said:

Hi everyone,
Wonderful work you have done here, including the documentation. (Especially I love those great videos on control theory. Nice find.)

Thanks for the feedback. I value a lot the documentation!!
 

2 hours ago, zii said:

I am trying to run latest version of this firmware (modifiedFOC-motorMicroWorks30kmh) on a 1st generation board (I think it's 1st gen... well, it's the one with a single XL7001 12V, 5V regulator).

You need 2nd gen boards for the latest firmware. That boards are only from MicroWorks...
Anyway, can you please share pictures of your board? where did you buy it??

If you are using the same MicroWorks 30B4 board, then your life will be easier.
Anyway, I suggest you to first connect a potentiometer and try run the motor... just after having the motor running, you can move to the balance controller...

Thanks for joining!!

0

Share this post


Link to post
Share on other sites

I attach a photo of my board, I got it around a year ago and I think this one is from MicroWorks.

2 hours ago, electric_vehicle_lover said:

Anyway, I suggest you to first connect a potentiometer and try run the motor... just after having the motor running, you can move to the balance controller...

I tried to do what You suggested and did manage to get motor to run with potentiometer speed control (I did have to set MOTOR_TYPE to MOTOR_TYPE_EUC1). 

To power the board I used a Lab PSU, with a 3A limit (@ 64V) and noticed that: 

  1. at slow speeds there is irregular / not so smooth motion of the motor
  2. in low speed region current is drawn much more aggressively than past some speed threshold, after which the current draw seems to be as good as with original Chinese firmware
  3. going from low speed to higher speed, that threshold (in previous bullet) is at higher speed, than going from higher to lower (some hysteresis)
  4. there is asymmetry such that in one direction the speed threshold for when rotation gets smooth is much higher than in the other

To my thinking, everything except the 4th point could be attributed to the fact that speed/position detection at low speeds isn't very good with either motor-mounted hall sensors or ACS712. What do You think, is that so?

cheers,
Zigmars

IMG_20170706_185327.jpg

0

Share this post


Link to post
Share on other sites

Posted (edited)

4 hours ago, zii said:

I attach a photo of my board, I got it around a year ago and I think this one is from MicroWorks.

Do you know where did you bough it?? because MicroWorks do not have anymore an online shop and I would like to find a source with an EN shop online...

 

4 hours ago, zii said:

I tried to do what You suggested and did manage to get motor to run with potentiometer speed control (I did have to set MOTOR_TYPE to MOTOR_TYPE_EUC1). 

To power the board I used a Lab PSU, with a 3A limit (@ 64V) and noticed that: 

  1. at slow speeds there is irregular / not so smooth motion of the motor
  2. in low speed region current is drawn much more aggressively than past some speed threshold, after which the current draw seems to be as good as with original Chinese firmware
  3. going from low speed to higher speed, that threshold (in previous bullet) is at higher speed, than going from higher to lower (some hysteresis)
  4. there is asymmetry such that in one direction the speed threshold for when rotation gets smooth is much higher than in the other

To my thinking, everything except the 4th point could be attributed to the fact that speed/position detection at low speeds isn't very good with either motor-mounted hall sensors or ACS712. What do You think, is that so?

Good description. I would say the issue is with your motor phases and hall sensors correct sequence... just like I have

#define MOTOR_TYPE_EUC1             0
#define MOTOR_TYPE_EUC2             1
#define MOTOR_TYPE_MICROWORKS_500W_30KMH     2

I would say you need to find the correct angle value at motor very low speed, for each direction.

Do like this:

1. disable the FOC by commenting this line "position_correction_value = (int) correction_value;" and do "position_correction_value = 0".
2. You need to play with MOTOR_ROTOR_DELTA_PHASE_ANGLE_RIGHT value until the motor starts well and run with the lowest current value and noise possible, at low speeds -- after that speed you need to enable FOC again and you will see the difference of enabling FOC at medium and high speeds.

Then do the same for the LEFT direction, because that angle value may be different.

When you have it, maybe you can do a pull request with the changes.

I am very happy to have other developer really put the hands on the code!!!!!!! <3 <3

Edited by electric_vehicle_lover
1

Share this post


Link to post
Share on other sites

@zii, when you the motor running ok, I think you will want to move to the balance controller.

You know that the motor interface is set_pwm_duty_cycle(value);

The balance controller can be implemented on the function balance_controller(); as you can see the code. Right now it have as input the IMU_get_angle_error (); and as output the set_pwm_duty_cycle(value); -- I think the balance controller may need motor current speed and that is not yet implemented as should be needed but I think should be simple to do.

0

Share this post


Link to post
Share on other sites
12 hours ago, zii said:

I commented out the section, which waited for some potentiometer value in the main.c

Be careful!! That is needed because on development you may make a "short-circuit" on the mosfets (like some error on the PWM values) and the board will not boot and you will not be able to flash it easily again... well, maybe just keep it on BOOTLOADER mode so it will not run your bad firmware.

By the way, was simple for you to flash the first firmware? hadn't you to first put the board on bootloader mode to be able to flash the first firmware using SWD??

And the current firmware does not balance!! you will need to implement the balance controller if you want it working :-)

0

Share this post


Link to post
Share on other sites

Posted (edited)

@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

Edited by zii
0

Share this post


Link to post
Share on other sites

Posted (edited)

2 hours ago, zii said:

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. 

  // apply minimum duty_cycle value
  int temp1 = 1000 - MOTOR_MIN_DUTYCYCLE;
  _duty_cycle = MOTOR_MIN_DUTYCYCLE + (((_duty_cycle * temp1) + MOTOR_MIN_DUTYCYCLE) / 1000);

I found that there are a minimum duty_cycle value after the motor start to move, like if there is a gap with low values. This code is to remove that gap and I expect it to improve the quick motor direction change rotation that I think is important for the balance of EUC.

2 hours ago, zii said:
  • 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)

Maybe later I will need to revise that code. I am not working on this project currently but on the EBike firmware that uses STM8 and that have a PWM module that is equal. The STM8 is much more limited and I am learning more and more, the code for motor control is the same and later I will be back to this project and apply any improvements. I did there this code and what I know now:

TIM_TimeBaseStructure.TIM_RepetitionCounter = 1; // will fire the TIMx_UP_IRQHandler at every PWM period (64us)

If RepetitionCounter == 0, will fire every upcount + downcount, so, 2 times every PWM cycle. With RepetitionCounter == 1, just like current code is, just fires in one direction (I don't know which one) and so 1 times every PWM cycle and that this if:

  if (!TIM_DirMode(TIM3))

can be avoided.

2 hours ago, zii said:
  • I don't fully understand the part with #define DO_INTERPOLATION 1, which You have currently implemented in place of an observer.

You can read more after "Initial Motivation: Can the Synchronous Current Regulator be modified to work with
Hall effect sensor inputs, with interpolation?" from Shane Colton documentation: https://eggelectricunicycle.bitbucket.io/EmbeddedFiles/19-SCquals.pdf

I just commit some comments to code to clarify this.

 

2 hours ago, zii said:

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.

I am not expert on git and I think this would be the first pull request on this project. I think you can do anyway a branch in your repo and do the pull request of that branch.

2 hours ago, zii said:

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.

Good!! Waiting for your pull request ;-)

 

2 hours ago, zii said:

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.

Printing every 10th FOC_slow_loop() iteration, if I remember, to not print to much fast because maybe it would negatively affect the FOC_slow_loop controller of the motor. I think this code works ok for a prototype and is ok to develop the balance controller, after that I would revise and improve the code were possible.

 

2 hours ago, zii said:

And for me i_d, i_q values are not stable at all, which I expect to be almost constant.

Please compare with my results:

Also see this message, was the last one were I improved the motor control:

Also see this message, may apply to your motor??

 

Edited by electric_vehicle_lover
0

Share this post


Link to post
Share on other sites

Posted (edited)

@electric_vehicle_lover
Ok, so firstly, I have pushed my adjusted code onto this new branch on my fork of Your code. I named one of the commits such to indicate that it was the one used to get the following plots from SerialPlot. (BTW, as I am using OS X, I had to compile SerialPlot myself, which took me almost a day to find all the problems with libraries, cmake & code).

As I said previously I did rename a few things the "my way"; also the tabs that I use for whitespace somewhat makes it now a bit harder to follow actual diff's not just whitespace changes. 

So... I did try to do similar tests to what You had done and plot motor_rotor_position, interpolation_angle, interpolation_sum and interpolation_angle_step. In the following plot You can see values from when I (with pot) decelerate motor until it goes into reverse direction and keep it there (with practically slowest speed that the motor still rotates). And then in the motor_rotor_position part of the plot You can see how interpolation manages to start and track angle only after single electrical cycle.

5971aee43bc98_ScreenShot2017-07-19at20_16_45.thumb.png.813ba5061ca25768675637c15d9496bb.png

In the next one I tried to torture the interpolation part with rapid pot turning at slow speeds.
5971b22872562_ScreenShot2017-07-19at20_20_23.thumb.png.6d2aae46426c7500ecbed3e2a81af682.png

So after that I also did test similar to Your other plot with id, iq, correction_value, motor_speed and duty_cycle (overlayed & multiplot respectively); as I use power supply with current limit set to 850 mA there are times where You can see that it has kicked in:5971b25bb9306_ScreenShot2017-07-19at20_42_24.thumb.png.8ab9a9e2f3f9acae7094318f2723bc54.png5971b260454a4_ScreenShot2017-07-19at20_43_11.thumb.png.dcd08366542a2e93b3e73e6b5921287f.png

 

Thus far it doesn't seem far from what You got. But now I checked what happens with id, iq values at slow speeds and this is what i got (which I did not expect):
5971c25b89680_ScreenShot2017-07-19at19_11_39.thumb.png.cd552dba7d5e10ef7207030f89db6df0.png

The slower the motor rotates, the greater the amplitude for id, iq oscillation. I did not expect it to be so bad.

In this last plot at the middle time of the time axis the motor has stalled.

5971c25ec0f62_ScreenShot2017-07-19at20_45_38.thumb.png.d218e8865481b0ff86ea4e0377184ea5.png

I remember testing original firmware long ago, and seeing that it manages very smoothly and continuously to slow down wheel with great torque to zero speed (I was applying force with hand). I also remember that it seemed to me that the controller had some minimum speed, below which it would NOT actively regulate (speed would slowly only go down), but it still managed to do the continuous slow-down.

Is it correct to say, that currently set_pwm_duty_cycle(target) is basically a constant torque controller, not a constant speed controller, thus low values of torque (or duty_cycle or potentiometer value) obviously translate to the fact that I can easily hold it and it won't be able to "escape" my hand's hold?

What does everyone else think about this FOC slow speed behaviour?

P.S. I will now try to do some more tests of my own...

 

Edited by zii
1

Share this post


Link to post
Share on other sites
44 minutes ago, zii said:

@electric_vehicle_lover
Ok, so firstly, I have pushed my adjusted code onto this new branch on my fork of Your code. I named one of the commits such to indicate that it was the one used to get the following plots from SerialPlot. (BTW, as I am using OS X, I had to compile SerialPlot myself, which took me almost a day to find all the problems with libraries, cmake & code).

I will be away on holidays on next days, I will see your branch after.

Yeah, but I didn't found better solution than SerialPlot and it is really important that tool, as we can see by your usage.

 

44 minutes ago, zii said:

Thus far it doesn't seem far from what You got. But now I checked what happens with id, iq values at slow speeds and this is what i got (which I did not expect):

The slower the motor rotates, the greater the amplitude for id, iq oscillation. I did not expect it to be so bad.

 

Is it correct to say, that currently set_pwm_duty_cycle(target) is basically a constant torque controller, not a constant speed controller, thus low values of torque (or duty_cycle or potentiometer value) obviously translate to the fact that I can easily hold it and it won't be able to "escape" my hand's hold?

About the oscillations you refer, didn't had time to see in detail your graphs (will do it later) but I guess you are doing your tests with motor with no load. If so, remember that current is very low and should have high noise... IMO hardware have low resolution for current readings and that seem to not be a problem as in real life motor will have a big load/currents. As we can see, with that hardware the motor still runs good, IMO.
But I think you did even more tests that I did by myself and all that you share have great value!!

set_pwm_duty_cycle(target); is not a constant torque controller. To have a torque controller, motor current need to be controlled with feedback, using PID controller. For a speed controller, the same but having speed as input to the PID controller. set_pwm_duty_cycle(target); takes that output on torque controller, when we developed one but I think we will not need a torque controller...

You didn't refer the max current controller on the firmware... please see it and define different values an then try block the motor and see the max current controller working.
But yes, without the max current controller disable, low PWM means low energy on the motor and you should be able to block it.

 

0

Share this post


Link to post
Share on other sites
On 7/17/2017 at 8:39 PM, zii said:

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.

Have you looked at any of the texas instruments MCUs? I found a really good open source FOC for their delfino MCUs. It's set up for a large industrial servo all it really lacks is things like motor detection and hall sensor support. It already has a sliding observer for sensorless FOC but the VESC one may be more advanced. It wouldn't be hard to take some vesc code and turn it into a decent controller for vehicles.

0

Share this post


Link to post
Share on other sites

@zii, I am lazy to merge your branch but I added you as a member on the https://github.com/EGG-electric-unicycle/

Please go ahead and make the changes you think will improve the firmware. Anyway, I am not working on the firmware on this phase but I will keep looking at this forum message and the git commits. I may be back in 2 or 3 months. Thank you.

0

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now