High Speed Loops and Interrupts

Hi Everyone,

So i’m currently looking at a project that now needs to have some ac dimming involved. Looking through the forum it seems that using a Triac and something like this code would work

int AC_LOAD = D5;    // Output to Opto Triac pin
int dimming = 128;  // Dimming level (0-128)  0 = ON, 128 = OFF
void setup()
  pinMode(AC_LOAD, OUTPUT);// Set AC Load pin as output
  attachInterrupt(A1, zero_cross_int, RISING);  
void zero_cross_int()  //function to be fired at the zero crossing to dim the light
  int dimtime = (65*dimming);    // For 60Hz =>65    
  delayMicroseconds(dimtime);    // Wait till firing the TRIAC
  digitalWrite(AC_LOAD, HIGH);   // Fire the TRIAC
  delayMicroseconds(8.33);         // triac On propogation delay (for 60Hz use 8.33)
  digitalWrite(AC_LOAD, LOW);    // No longer trigger the TRIAC (the next zero crossing will swith it off) TRIAC

void loop()  {
  for (int i=5; i <= 128; i++){

My current project uses 2 mcp23017 to provide additional inputs and outputs as well as adding in the following to speed the system up


The loop on my system is as follows and can take up to 134ms to complete (based on the timing variables) and i have a few functions that are called every 100ms which take around 8ms to respond

void loop() {
    unsigned long now = millis();
	if ((now - lastRun) >= 100) {
		lastRun = now;
		unsigned long timerstart = millis();
		int switchstatetemp = mcp1.digitalRead(7);
		int pirstatetemp = mcp1.digitalRead(0);
		mcpread = millis() - timerstart;
        if( mcpread > mcpreadlong ){
            mcpreadlong = mcpread;
        if( mcpread < mcpreadshort ){
            mcpreadshort = mcpread;
		if( switchstate != switchstatetemp ){ // Read switch status
            if( switchstatetemp == HIGH ){
                mcp1.digitalWrite(8, HIGH);
            } else {
                mcp1.digitalWrite(8, LOW);
            switchstate = switchstatetemp;
        if( pirstate != pirstatetemp ){ // Read PIR status
            if( pirenabled == 2 ){
                if( pirstatetemp == LOW ){
                    mcp1.digitalWrite(10, HIGH);
                } else {
                    mcp1.digitalWrite(10, LOW);
                    pirlasttriggered = Time.local();
                pirstate = pirstatetemp;
    looptime = millis() - now;
    if( looptime > looptimelong ){
        looptimelong = looptime;
    if( looptime < looptimeshort ){
        looptimeshort = looptime;

What i would like to do is keep the following code in place but also add code for the triac to use mcp23017 outputs (running at 400kHZ so i’m hoping a 2.5 microsecond response) to control 16 dimmable lights. Right now i’m trying to see if it is even possible as i’m not sure it is.

My main concern is that the main loop code and functions will block the interrupt function from running resulting in a bad result

My approach would be to connect a pin from a zero crossing detector on the main input line to the particle and set up the interrupt as above. However instead of controlling 1 output i would send an mcp command out and delay based on set dimming ranges, for example 100%, 95%, 90%, 85%, 0%

I would then group the mcp commands depending on the dimming set for each output and run the final delay before switching the triac off

It may be possible but with so many delays in the code i’m concerned things will begin to conflict. Can anyone give me any ideas of the performance and any issues i should expect from this?