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

SOLVED: TRIAC delayed-trigger compensation routine for ESP32(-S3) (DSP-119) #76

Open
f4lc0n-asm opened this issue Nov 12, 2023 · 2 comments

Comments

@f4lc0n-asm
Copy link

f4lc0n-asm commented Nov 12, 2023

This is a highly optimized TRIAC delayed-trigger compensation routine for ESP32(-S3).
It compensates the TRIAC trigger time so that the power delivered to resistive load is changing linearly when the original TRIAC trigger time is also changing linearly.

Input: Relative delay of TRIAC trigger (0: start of half-sine wave up to 1: end of half-sine wave)
Output: Linearized relative delay (0 up to 1, 0 when input < 0, 1 when input > 1, NaN when input is NaN)
Relative error of power delivered to resistive load: < 1e-5

Cycles: 14-186 (includes CALL8, close to upper bound most of the time unless special input cases mentioned above)
Instructions: 10-142 (includes CALL8, close to upper bound most of the time unless special input cases mentioned above)

Comment:
The power delivered with TRIAC to a resistive load during a half sinewave is simply Integrate[Sin[x]^2, x], which yields x/2 - 1/4 Sin[2 x] (indefinite integral - needs to be converted to definite one from x to Pi).
Linearization eq.: Reduce[(Pi/2 - (x/2 - 1/4 Sin[2 x]))/(Pi/2) == 1 - y/Pi, {x, y}] yields y == x - Sin[2 x]/2. But InverseFunction[Function[x, x - Sin[2 x]/2]] will get you nowhere :/
That is why I created this simple and most importantly fast routine!
Ring up your prodigy mathematician acquaintances - maybe, they will be able to devise an infinite series for the inverse function and conveniently truncate it when the required precision is met.

I am attaching the sources. Use 7-Zip to extract them from the 7-Zip archive. Feel free to incorporate them into this project. Let me know if you need me to tweak the ASM source.

Cheers!

f4lc0n

dcomp_v1.2.zip

Fixed: Function description in plin.s.

Added: PLin function - same as DComp, but the input is the required relative output power (from 0 to 1).

Added: Graphs for DComp and PLin compensation functions - see the tiny PDF files.

Added: C source for Xtensa GCC folks since the C -Ofast floating-point code is an unmitigated disaster. The ASM version as a whole is 2× faster than C -Ofast!!! This is thanks to the highly optimized floating-point code at the end of the ASM routine, which is more than 3× faster than C -Ofast!!! To conclude, the Xtensa GCC is pretty good at optimizing integer code - e.g. if(c<minc) minc=c; is translated into just 1 ASM instruction MIN, which is both apt and cool! On the other hand, GCC quickly runs out of floating-point registers and starts using the stack with dire consequences for speed. Please tell the Xtensa GCC folks this is the one area really deserving their attention!!! Thanks.

Added: ESP32(-S3) target and instruction count in ASM and C source comments

Updated: Cycle count in ASM source comments

@github-actions github-actions bot changed the title SOLVED: TRIAC delayed-trigger compensation routine SOLVED: TRIAC delayed-trigger compensation routine (DSP-119) Nov 12, 2023
@TD-er
Copy link

TD-er commented Nov 12, 2023

Why in assembly?
Is this compatible with all ESP32 platforms?
It looks like it is a big lookup table, so I can imagine it is fast.
But still that doesn't explain why it has to be in assembly code.

Also I guess it would be nice to have a bit more explanation about the actual use case and what makes this a requirement for that use case.

@f4lc0n-asm
Copy link
Author

f4lc0n-asm commented Nov 12, 2023

The ASM version is 2× faster than C -Ofast!!! Since it extensively uses Xtensa FPU, it is compatible with ESP32 and ESP32-S3. It is suitable for cases when you want to linearly control the power delivered to a load connected to AC mains or any sinus power source in general, which can have much higher frequency - hence the need for speed…

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants