Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Nonlinear output #87

Closed
readerror67 opened this issue Aug 15, 2015 · 16 comments
Closed

Nonlinear output #87

readerror67 opened this issue Aug 15, 2015 · 16 comments

Comments

@readerror67
Copy link

Hello sskaug,

I have been doing some testing and noticed something quite odd. The top end of the output hits a somewhat nonlinear ramp at the end of the PWM range (pics below). I tested the same hardware with SK and it does not exhibit the jump. Also something else I have noticed was the actual PWM range set within BLHeliSuite does not seem to correspond to the range used while running.

The examples below, I had set 1032 minimum, 1992 maximum but it seemed to peak and plateau much before that point.

Tested on DYS 20A (SK and BL) and RG20A (BL):
http://rotorbench.com/ESC/Summary/esc_summary_thrust.html

image

image

@sskaug
Copy link
Collaborator

sskaug commented Aug 15, 2015

I've seen these thrust curves that you have posted on RCG, really great data!

The top end of the RG20 is much worse than I expected, and the fact that it maxes out before 1992 indicates that there is maybe a bug in the throttle cal compensation? I'll look into it. Maybe you could test with the default throttle range?

The SN20 curve looks much better, and more like what I expected. The deadtimes used for fet switchin come into play in the top end. For almost full throttle, you have to turn off the power fet and wait before turning on the damping fet. And then turn off the damping fet and wait before turning on the power fet. The smaller the wait times, the smoother the transition to full power.I think BLHeli is maybe more conservative on wait times than SimonK. And maybe also a little bit less efficient in the use of MCU cycles.

It would be interesting to see curves for various settings of dither.

@readerror67
Copy link
Author

I can test the default range, not a problem.

As for the dithering, I had not messed with that since I wasn't 100% sure what it did exactly (not read up on that new feature yet). If you have some values you want me to try I can run them today.

@sskaug
Copy link
Collaborator

sskaug commented Aug 16, 2015

Dithering gives some randomness to the motor pwm output, in order to smooth out problematic rpm areas (where motor commutation harmonics hit the pwm frequency) and also to smooth out the transition to full power.

Default dither is set to 7. It would be interesting to see dither off, and also some higher dither, particularly 15. I think in most systems a dither of 31 gives noticeable effects from the noise that the dithering adds.

@readerror67
Copy link
Author

Hey sskaug,

I have some more testing done (RG20A, new smaller version).
I reset the settings to to defaults, including PWM settings (disabled TX calibration also, not needed).
I noticed that the motor actually starts spinning at 1122us rather than 1148us and it still seems to be maxing out far before the 1832 range with that crazy ramping towards the end. The dithering looks pretty neat and seems to shift the 'end' a bit though:

image

image

image

http://rotorbench.com/RG20/

@sskaug
Copy link
Collaborator

sskaug commented Aug 17, 2015

Really interesting data with the dither. It sure does smooth out the step to full throttle, as intended.

I have also looked more into the reason why the top is below 1800, instead of at 1832.
There is probably a small error from the oscillator not being calibrated correctly, but this error is probably below 1%. Also, there are some rounding effects that are somewhere below 1%.
Then there is a bug in the throttle gain calculation, where I use 128 instead of 125. This gives an error of 2.4% and is probably the major discrepancy. I will fix this in the next rev :).

Also came to think of another reason why SimonK on the SN20A being smoother on the top, that probably has to do with the high side fets being slower to turn on, and therefore do not brake much at the top. While BLHeli (rev14) has better braking (also at the top:)).

@sim-
Copy link

sim- commented Aug 18, 2015

Hello! Yay testing! :)

I also have some tricky code that skips CPWM when the off time plus overhead (including dead-time) makes it impossible to fit: https://github.com/sim-/tgy/blob/3c96966c6/tgy.asm#L2881 ...but I don't see how this would result in more braking force on BLHeli, since it's just filling in the gap between where it would have to stretch out the same duty or jump to full power. Since the duty is so close to 100% anyway, it's still spending most of the time pinning the voltage. I'd presume that people testing braking force would be doing so with a much lower value.

I was going to set up a drill chuck on a motor to measure the spin-down time between both, and was just going to try with the lowest value that isn't idle (closest to 100% complementary), but maybe it should be compared across the whole PWM range. Not sure what else could be making a difference here.

@sskaug
Copy link
Collaborator

sskaug commented Aug 18, 2015

Simon, good to see you here. And yay, good to see test results :).

I didn't know you skip CPWM (damping) when there is not room, is that part of a standard build? If so, it looks like it works well :). I have thought of going that route too, but didn't as I thought the variation in fet switching delays would lead to performance variations, and also the code execution time could also easily steel any performance gains. So I did the dither route, which also has the benefit of smoothing out odd areas anywhere in the throttle curve.

But when I said that damping was better on BLHeli, I was thinking of the change done in rev14 on the high side fet switching, where the high side is turned on before(!) the low side is turned off. On some ESCs only, that is, like the SN/BL20A, that have a slow to turn on high side driver. Although not quantitatively measured, I think the consensus is that braking improves (all over the speed range).

Have you seen this: http://www.rcgroups.com/forums/showthread.php?t=1835486 (forget the regenerative braking term, I should have used active braking :))
I used the onboard DAC (of a SiLabs) to output the current speed. Maybe that can be done on Atmel too?

@sim-
Copy link

sim- commented Aug 18, 2015

Hi Steffen! Yes, ReadError is doing some useful stuff here. :)

The CPWM skipping when not enough time has been standard since 2013-04-24 release, commit fa7737183e8cca13e80c5312158c4ce1f881b9cf. Not that probably anybody noticed or even use COMP_PWM because of the lack of config tool situation. :( Yeah, I tried to pull out all but a bit test in the PWM interrupt and do the rest in the duty calculation routines to avoid too much overhead there.

Ahh, certainly supporting negative dead-times would improve braking! A little dangerous, perhaps.. :) With NCP5911 and similar drivers being so cheap, it would be nice if everybody used them now instead of discrete driving bits. One thing that detracted me from doing negative dead-time before is the switching time depending on voltage because of the discrete components. I guess you probably aim for somewhere that doesn't blow up for the worst case. :)

DAC on an Atmel? You must be dreaming. :) There is a commutation sync pulse output which can be enabled (MOTOR_DEBUG), but yeah... What is ReadError doing? External RPM measurement, I guess? I did some similar plotting (to check linearity) a a few years ago (http://0x.ca/sim/esc/thrust_bench/), but I only logged thrust. (http://0x.ca/sim/esc/thrust_bench/thrust_bench.c combined with http://www.ebay.com/itm/161777769316). Step response and latency measurements would certainly be interesting!

@sskaug
Copy link
Collaborator

sskaug commented Aug 18, 2015

So, seems the CPWM skipping works really well, then :).

The typical Atmel high side driver uses a resistor pullup to turn on, and is really slow. Also, if the high side is turned on late, the motor output has already risen (due to freewheeling) while the gate is held low. So you actually charge the gate negative before starting to turn it on. Which makes it really slow.

Of course I was afraid of cross conduction, but I tested several ESCs on several voltages, and was a bit conservative on the timing overlap, the worst case (at least that I found) margin between low off and high on is still some 1us plus. There is also a definitive benefit from this in that the ESC runs cooler on partial load due to the improved AFW.

Have you seen the FVT Littlebee? It's SiLabs and uses dedicated drivers. Really neat and small and will hopefully prove to be reliable. And there are more nice small ESCs coming as well with dedicated drivers :).

DAC on Atmel - yeah, realize that was just dreaming.

@rs2k
Copy link

rs2k commented Aug 18, 2015

I'm keeping a close eye on this conversation. 👍

@readerror67
Copy link
Author

Hey sskaug,

Thanks for fixing the PWM stuff, do you have a patch I can try?

As for braking, I am getting some stuff together to compare the different ESC models and firmware braking capabilities:
image

Its similar to what Simon was saying, basically an aluminum flywheel with slots for IR sensors to count rotations, the extra mass should make the ESCs work for it a bit. I figured I could slowly spool up to a set RPM then instantly reduce it and count the time it takes to reach nominal RPM for the the newly set PWM.

@sskaug
Copy link
Collaborator

sskaug commented Aug 20, 2015

Cool! That flywheel should challenge the braking capabilities.
Braking will also vary significantly between motors, probably primarily due to variations in internal resistance.
You have an email I can send code to? For which ESC?

@readerror67
Copy link
Author

teherror67@gmail.com would be good. I am using the RG20 ESC, but if the patch works for all I can compile it for the other ones I am going to test (bs_nfet and dys_nfet)

@rs2k
Copy link

rs2k commented Aug 20, 2015

Be careful to make sure your motors don't get too hot on those flywheels. They get a lot of cooling from a prop.

@readerror67
Copy link
Author

Yea will keep an eye on that, I dont plan on actually running the motor too long in a single interval, just a super slow climb to a set pwm or RPM point and then an abrupt descent to a set PWM value. Will encase everything since this disk can probably mess some things up if it comes free.

@sskaug
Copy link
Collaborator

sskaug commented Sep 16, 2015

Greatly improved on rev 14.1, with skipping of damping fet switching.

@sskaug sskaug closed this as completed Sep 16, 2015
saidinesh5 added a commit to saidinesh5/BLHeli that referenced this issue Dec 24, 2020
Thanks to https://github.com/RamonMartins/BLHeli_S-Startup-Tones

music_gs4:
	mov	Temp3, bitdump#58 ;length of tone
	mov Temp4, bitdump#29 ;number of delay loop1 cycles (tone frequency)
	mov Temp5, JazzMaverick#2  ;number of delay loop2 cycles (large step?)
	jmp music

music_as4:
	mov	Temp3, bitdump#58
	mov Temp4, bitdump#29
	mov Temp5, JazzMaverick#2
	jmp music

music_f1:
	mov	Temp3, bitdump#222
 								;length
of tone
	mov Temp4, bitdump#110
	mov Temp5, JazzMaverick#2

;one ms ;frequency of tone 1=500, 2=1000, 3=1500
	jmp music

music_f2:
	mov	Temp3, bitdump#132
 								;length
of tone
	mov Temp4, bitdump#43
	mov Temp5, JazzMaverick#3

;one ms ;frequency of tone 1=500, 2=1000, 3=1500
	jmp music

music_f3:
	mov	Temp3, bitdump#132
 								;length
of tone
	mov Temp4, bitdump#29
	mov Temp5, JazzMaverick#2

;one ms ;frequency of tone 1=500, 2=1000, 3=1500
	jmp music

music_f4:
	mov	Temp3, bitdump#88 ;44
	mov Temp4, bitdump#172
	mov Temp5, JazzMaverick#2
	jmp music

music_g4:
	mov	Temp3, bitdump#98 ;49
	mov Temp4, bitdump#110
	mov Temp5, JazzMaverick#2
	jmp music

music_c:
	mov	Temp3, bitdump#65
	mov Temp4, bitdump#182
	mov Temp5, JazzMaverick#1
	jmp music

music_d2:
	mov	Temp3, bitdump#146 ;73
	mov Temp4, bitdump#140
	mov Temp5, JazzMaverick#1
	jmp music

music_ds:
	mov	Temp3, bitdump#78
	mov Temp4, bitdump#121
	mov Temp5, JazzMaverick#1
	jmp music

music_e:
	mov	Temp3, bitdump#82
	mov Temp4, bitdump#103
	mov Temp5, JazzMaverick#1
	jmp music

music_f:
	mov	Temp3, bitdump#87
	mov Temp4, bitdump#86
	mov Temp5, JazzMaverick#1
	jmp music

music_g:
	mov	Temp3, bitdump#196 ;98
	mov Temp4, bitdump#55
	mov Temp5, JazzMaverick#1

music:
	mov A, Temp5
	push ACC

	BcomFET_on

; BcomFET on
	ApwmFET_on

; ApwmFET on
	mov	A, Beep_Strength
	djnz	ACC, $

	ApwmFET_off

; ApwmFET off
	BcomFET_off

; BcomFET off
	pop ACC
	mov Temp5, A
	mov Temp2, A

; Make copy of Temp5 to work with (Temp2)
	mov A, Temp4
	mov Temp6, A
music_O_loop:

; Outer loop
	mov	Temp1, bitdump#23

; Number of times to repeat inner delay loop
music_M_loop:

; Middle loop
	clr	A
 	djnz	ACC, $

; Inner loop (42.7us - 1024 cycles)
	djnz	Temp1, music_M_loop
	djnz	Temp2, music_O_loop

wait_150us:
	mov		A, bitdump#30

;5us wait
	djnz	ACC, $
	djnz	Temp6, wait_150us
	djnz	Temp3, music
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants