Skip to content

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

Open
@f4lc0n-asm

Description

@f4lc0n-asm

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

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions