AC-Dimmer VS. binary_sensor : interrupt priority and problems

“AC-Dimmer Component” driving mode causes too much EMI noise.
To turn the load on/off… I have to use a different strategy.

What I see, is an instability in the interrupt of the zero_cross input pin.
Spikes are acceptable when WiFi communication is not connected… but become a problem when WiFi connection is established; or when the AP turns on.

When the AP is active, gaps of up to 500ms are created.

What is the best way to proceed?
Create a native library like AC-Dimmer or fix the yaml code in some way?

binary_sensor:

  - platform: gpio 
    pin:
      #allow_other_uses: true
      number: GPIO15    #GPIO36
      inverted: True

    id: zero_cross_pin
    internal: True
    on_press: 
      then:
        #- output.toggle:  OUT_TEST
        - lambda: !lambda |-

            #define duty_level	11
            #define step_load_N	20

            // TimeBase = 200ms
            const uint8_t load_step[duty_level][step_load_N] =
            {
              { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },	// 0%
              { 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },   // 10%
              { 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0 },   // 20%
              { 1, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0 },   // 30%
              { 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0 },   // 40%
              { 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0 },   // 50%
              { 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 0, 0 },   // 60%
              { 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 0, 0 },   // 70%
              { 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1 },   // 80%
              { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0 },   // 90%
              { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },   // 100%
            };
            
            static uint16_t  out_CH4      = 0;
            static uint16_t  pattern_step = 0;
            static uint8_t   out_test_s   = 0;

			//=====================================================
			// ONLY for TEST
			//=====================================================
            if( out_test_s == 0 )
            {
                out_test_s = 1;
                id(OUT_TEST).turn_on();
            } else {
                out_test_s = 0;
                id(OUT_TEST).turn_off();
            }
            //=====================================================

            grid_present = 20;    // Rilevato Zero Cross

			//=====================================================
			if( output_value[3] == 0 ) {
				out_CH4 = 0;
				pattern_step = 0;
				id(OUT_CH4).turn_off();
				
			} else {
			
				if( pattern_step == 0 ) {
					out_CH4 = (uint8_t) floor( output_value[3] *10 );
					
					// controllo di sicurezza...
					if( out_CH4 >= duty_level ) out_CH4 = duty_level -1;
				}
				
				if( load_step[out_CH4][pattern_step] == 0 ) {
					id(OUT_CH4).turn_off();
				} else {
					id(OUT_CH4).turn_on();
				}
				
				if( ++pattern_step >= step_load_N ) pattern_step = 0;
			}
			//=====================================================

Triac control with zero cross is quite intense job, I decided to take care of it with separate esp that communicates with esphome through http api. Works well.

In the next PCB I make, I will probably use two different microcontrollers: ESP32 (for connectivity) + STM32 (for low-level control).

Currently the board/PCB only has one ESP32. I thought I would have no problem with a dual core. “Native AC-Dimmer Control” works well without glitches.

I’m sure that working on the low level, the problem will be solved… but I was hoping for a fix in yaml or lambdas.

Besides “binary_sensor”, are there any other ways to trigger interrupts on the input pins
with high priority?