TorAllex ©:И вот что ещё. Оперируем целыми полупериодами, т.е. при напряжении сети 220 В имеем шаг регулировки 2,2 В. Не грубовато получится?
 Да, грубо. У меня мощность в процентах как наследие, нужно сделать шаг меньше - 0.5% скажем. Впрочем совсем уж жесткий предзахлеб я не использую.
Алсо, скетч ниже.
#include <DallasTemperature.h>
#include <avr/delay.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <OneWire.h>
#include <math.h>
LiquidCrystal_I2C lcd(0x3f,16,2);
OneWire oneWire(7);
DallasTemperature sensors(&oneWire);
DeviceAddress columnSensor = {0x28, 0xFF, 0x21, 0x32, 0x8C, 0x16, 0x03, 0x4F};
DeviceAddress headSensor = {0x28, 0xFF, 0x4D, 0x22, 0x93, 0x16, 0x04, 0xD1};
#define ABTN 8
#define BBTN 9
#define CBTN 10
#define DBTN 11
#define SIGNAL_PIN 6
void setup()
{
  lcd.init();
  lcd.backlight();
  //Serial.begin(9600);
  lcd.setCursor(0, 1);
  lcd.print("Setup");
  pinMode(13, OUTPUT);
  pinMode(SIGNAL_PIN, OUTPUT);
  pinMode(ABTN, INPUT_PULLUP);
  pinMode(BBTN, INPUT_PULLUP);
  pinMode(CBTN, INPUT_PULLUP);
  pinMode(DBTN, INPUT_PULLUP);
  digitalWrite(SIGNAL_PIN, HIGH);
  while (pollButtons() < 1) {}
  digitalWrite(SIGNAL_PIN, LOW);
  ADMUX |= (1<<REFS0);
  ADCSRA |= (1<<ADPS2)|(1<<ADPS1)|(1<<ADPS0); //Use prescale factor 16 -> ADC clock is 500kHz
  ADCSRA |= (1 << ADATE); // Enable auto-triggering
  ADCSRA |= (1<<ADIE); //Enable ADC conversion complete interrupt
  ADCSRA |= (1<<ADEN); //Enable the ADC
  ADCSRA |= (1<<ADSC); //Start first conversion in Free-running mode
  //ADMUX = ADMUX | B00000001;
  ADMUX |= (1<<MUX0);
  pinMode(13, OUTPUT);
  EICRA |= (1<<ISC00)|(1<<ISC01);
  EIMSK |= (1 << INT0);
  //OCR0A = 100;
  //TIMSK0 |= (1<<OCIE0A);
  sensors.begin();
  sensors.setWaitForConversion(false);
  sensors.setResolution(columnSensor, 12);
  sensors.setResolution(headSensor, 12);
  sensors.requestTemperatures();
  delay(1000);
  sei();
}
int8_t pollButtons()
{
  uint8_t pins[] = {ABTN, BBTN, CBTN, DBTN};
  static unsigned long ms = 0;
  if ((millis() - ms) > 100)
  {
    for (uint8_t i = 0; i < sizeof(pins); i++)
    {
      if (digitalRead(pins[i]) == LOW)
      {
        ms = millis();
        return pins[i];
      }
    }
  }
  return -1;
}
#define V_RATIO 0.783
volatile uint32_t rmsS = 0;
volatile uint16_t rmsN = 0;
ISR(ADC_vect)
{
  if (rmsN < 10000)
  {
    int16_t sample = ADCW - 512;
    rmsS += (uint32_t)sample * (uint32_t)sample;
    rmsN++;
  }
}
volatile uint8_t pwmCalc = 50;
ISR(INT0_vect)
{
  static uint8_t mod = 0;
  mod += pwmCalc;
  if (mod >= 100)
  {
    mod -= 100;
    digitalWrite(13, HIGH);
  }
  else
  {
    digitalWrite(13, LOW);
  }
}
void loop()
{
  bool refreshLcd = true;
  static uint16_t comp = 0;
  static uint8_t pwmSet = 0;
  static uint32_t dsms = 0;
  switch (pollButtons())
  {
    case ABTN:
    {
      if (comp > 0) comp -= 10;
      break;
    }
    case BBTN:
    {
      if (comp < 1000) comp += 10;
      break;
    }
    case CBTN:
    {
      if (pwmSet > 0) pwmSet--;
      break;
    }
    case DBTN:
    {
      if (pwmSet < 100) pwmSet++;
      break;
    } 
    default:
      refreshLcd = false;
      break;
  }
  static double voltage;
  if (rmsN == 10000)
  {
    voltage = V_RATIO * sqrt(rmsS / rmsN);
    rmsS = 0;
    rmsN = 0;
    double calc = (230.0 / voltage) * pwmSet;
    if (calc > 100)
      calc = 100;
    pwmCalc = (uint8_t)round(calc);
  }
  static double headT, columnT;
  if ((millis() - dsms) > 1000)
  {
    headT = sensors.getTempC(headSensor);
    columnT = sensors.getTempC(columnSensor);
    sensors.requestTemperatures();
    dsms = millis();
    refreshLcd = true;
    if ( (comp > 0) && (abs(columnT - headT) > (double)(comp / 100.0)) )
    {
      digitalWrite(SIGNAL_PIN, HIGH);
    }
    else
    {
      digitalWrite(SIGNAL_PIN, LOW);
    }
  }
  if (refreshLcd)
  {
    lcd.setCursor(0, 1);
    lcd.print(pwmSet);
    lcd.print(" ");
    lcd.print(pwmCalc);
    lcd.print("  ");
    lcd.print(voltage, 1);
    lcd.print("        ");
  
    lcd.setCursor(0, 0);
    lcd.print(headT);
    lcd.print(" ");
    lcd.print(columnT);
    lcd.print(" ");
    lcd.print(comp / 100.0, 1);
    lcd.print(" ");
  }
}
 
						
Два полиэтиленовых бидона по 41 л.
Скаммерческий дистиллятор с укреплением.
РК 28/1700
Регулятор - термометр на ардуино с функцией пищания.