control pid de la temperatura de varios terrarios

He encontrado un código muy bien hecho, que incluye una librería TimerOne que esta en este blog

Tiene la curva de brillo para hacer que luzca lineal
Usa tu misma interrupción y en
int output [] = { // assign a pin for each channel.
10, // Output 0
3, // output 1
5, // output 2
0, // output 3
0, // output 4
0, // output 5
0, // output 6
0, // output 7
};

Eliges el pin a usar, aca esta con el 4 para la salida 0 pero usa el 10 si quieres.
He puesto un NroDimmer 1 que limita el uso a solo un dimmer que es tu caso. Esta pensando para 8.

A ver si te sirve y se porta bien.
Aca cito las ventajas
Cruce por cero como el tuyo, de hecho usa la misma electrónica de cruce por cero.
Interrupción de tiempo variable que obtiene una curva lineal con el brillo. La potencia es cuadrática por lo tanto requieres de esto para que luzca como un brillo progresivo y parejo.
Tienes comandos via puerto serie como en tu caso, curiosamente ubicados ... EN EL LOOP como yo te habia sugerido.
que comandan todo

 /*
    by Gromain59
    Translated By Mike Deuschle
    mike.dausch@gmail.com

    Material part:
    - Triac driven by a digital output via an optocoupler
    - AC opto-coupler for detecting the zero crossing of phase

    Software part:
    - A hardware interrupt input 2 at the zero crossing of phase
    - A software interrupt that occurs between 100us and 1400us.
    => Interrupt interval is variable to obtain a light curve by linear orders, because of the shape of the sinusoidal signal.
    we have:
    1. Detection of the transition to zero on input 2
    2. execution of detection_zero (): processing channel with a setpoint of 0% and 100%
    3. deactivating hardware interrupt, enabling the software interrupt on the basis of delay [0]
    4. interrupt after delay [c2] ?s (c2 = 0)
    5. execution of controle_canaux ()
    => Index increment c2
    and if c2 is greater than 49, then this is the last cycle
    => Turn OFF of all channels
    => Activate the hardware interrupt
    otherwise:
    => Activation of output channels with 98% to record (either a 469?s delay) or if
    => Interrupt reconfiguration of time with another delay, delay [c2]

    To change the setpoint of a channel, you must send via the serial monitor a frame of the form:
    " D/0/45/F"
    => Space
    => "D" to indicate the start of the frame
    => "/" As separator
    => The affected channel (0 to 7 here)
    => "/" As separator
    => The desired level (from 0% to 100%)
    => "/" As separator
    => "F" to indicate the end of the frame

    Once the frame received, the function sscanf is responsible for retrieving data.
    It converts the received record levels (0 to 50 levels)

    Resources:
    http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1230333861/30 for first test
    http://www.hoelscher-hi.de/hendrik/english/dimmer.htm for electronics
    http://www.abcelectronique.com/bigonoff/domocan.php?par=3efd4 for electronics and soft (PIC)
    arduino forum

    */

    #include <TimerOne.h>   // for the interruption time http://www.arduino.cc/playground/Code/Timer1
    #include <stdio.h>   // for the treatment of the frame containing the change orders

    #define NroDimmers 1
    // timeout value for the reception of the frame
    int tps_max_lecture = 200; // reading code, counter max between all the characters of a code
    int tps_max_carte = 1000; // max meter between reception of a character

DimmerAC.ino (9.31 KB)