AC phase cutting MKR1000

I didn't find any code for arduino MKR family, so I put together this program for AC phase cutting by opening triac at specific time.
No timers used, no delays, only one interrupt; 3 buttons to set the output power basically --will keep them in the code curious myself to see whetherthere will be 7 new yt videos and 3 new websites in span of a year using them too.

blessed those who try to clean/simplify/ruggedize this code for benefit of mine too!

#include <Arduino.h>
#include <AcksenButton.h>

#define INTERRUPT_PIN 6

AcksenButton UP_Button(8, ACKSEN_BUTTON_MODE_NORMAL, 120, INPUT_PULLUP);
AcksenButton DOWN_Button(9, ACKSEN_BUTTON_MODE_NORMAL, 120, INPUT_PULLUP);

unsigned long t_zc = 0;
unsigned long t_zc_prev = 0;
unsigned long time_half_period = 0;
unsigned long time_phase_cut = 0;

//by itself this scaler should mean how much of the phase is being cut off
unsigned int perc_scaler = 50;

volatile boolean zc = false;

void zeroCrossing() {
  zc = true;
}

void setup() {
  pinMode(INTERRUPT_PIN, INPUT_PULLUP);
  pinMode(7, OUTPUT);

  attachInterrupt(digitalPinToInterrupt(INTERRUPT_PIN), zeroCrossing, FALLING);

  Serial.begin(9600);
}

bool opened_once = false;
bool zc_loop = false;
void loop() {
  long mcros = micros();

  if (time_phase_cut < mcros && !opened_once) {
    digitalWrite(7, 1);
    opened_once = true;
  } else {
    digitalWrite(7, 0);
  }

  if (zc && perc_scaler > 0) {
    t_zc_prev = t_zc;
    t_zc = mcros;

    time_half_period = t_zc - t_zc_prev;
    time_phase_cut = mcros + time_half_period;

    //'from' values flipped so bigger 'perc_scaler' means more power on the output
    time_phase_cut = map(perc_scaler, 100, 0, mcros, time_phase_cut);

    opened_once = false;
    zc = false;
  }

  //===========================================================

  if (UP_Button.onPressed()) {
    if (perc_scaler < 100)
      perc_scaler += 10;
  }

  if (DOWN_Button.onPressed()) {
    if (perc_scaler > 0)
      perc_scaler -= 10;
  }

  UP_Button.refreshStatus();
  DOWN_Button.refreshStatus();
}

scope screen (there are glitches here and there):

Perhaps if you bless my palms with some green paper stuff...

been there, bro

with SAMD peripherals
https://github.com/JAndrassy/Regulator/blob/master/TriacLib/TriacLib.h

so you require AC to be specific frequency and uses delays

The price was right. :slight_smile:

specific frequency yes. it was just for my project.
delays no. the CPU is not involved after setting up the peripherals.

the interrupt function is not enabled. the pin change interrupt is directed to event system peripheral and propagated to the timer peripheral.

the waitZeroCrossing is an addition so I can switch relays on zero crossing. it enables the interrupt function, waits for zero crossing and then disables the interrupt function again.

1 Like

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.