253 lines
5.0 KiB
C++
253 lines
5.0 KiB
C++
//20.02.2019
|
|
//by Reptiloid software
|
|
|
|
#include "Arduino.h"
|
|
#include "AC_Dimmer.h"
|
|
|
|
#define DIMM_MAX 5
|
|
#define AC_FREQ 50
|
|
#define MAX_HEAT_DIV 10
|
|
|
|
//======================================
|
|
|
|
#define ZERO_VAL 19850
|
|
#define K 77
|
|
|
|
#define SSR 0
|
|
#define DIMM 1
|
|
#define HEAT 2
|
|
|
|
//=======================================
|
|
|
|
struct dimmer
|
|
{
|
|
unsigned char flag;
|
|
unsigned char val;
|
|
unsigned char pin;
|
|
unsigned char SSR_state;
|
|
unsigned char heat_val;
|
|
};
|
|
|
|
struct sort
|
|
{
|
|
unsigned char val;
|
|
unsigned char pin;
|
|
};
|
|
|
|
|
|
//==========================================
|
|
|
|
volatile unsigned char cnt;
|
|
volatile unsigned char dims;
|
|
volatile unsigned char lim;
|
|
volatile unsigned char not_z;
|
|
volatile unsigned char heat_cnt = 0;
|
|
|
|
dimmer dimmer[DIMM_MAX];
|
|
sort sort_vals[DIMM_MAX];
|
|
sort sort[DIMM_MAX*2];
|
|
|
|
//===============================================
|
|
|
|
|
|
|
|
|
|
void Dimmer_init_begin()
|
|
{
|
|
TCCR1A=0;
|
|
TCCR1B=2;
|
|
TIMSK1=1;
|
|
|
|
EICRA=3;
|
|
EIMSK=1;
|
|
EIFR=1;
|
|
|
|
for(unsigned char i=0; i<DIMM_MAX; i++)
|
|
{
|
|
dimmer[i].pin = 0xff;
|
|
dimmer[i].val = 0;
|
|
dimmer[i].flag = SSR;
|
|
dimmer[i].SSR_state = 0;
|
|
}
|
|
|
|
for(unsigned char i=0; i<DIMM_MAX*2; i++)
|
|
{
|
|
sort[i].pin = 0xff;
|
|
}
|
|
}
|
|
|
|
|
|
void Dimmer_pin_assign(unsigned char dim_num, unsigned char dim_pin)
|
|
{
|
|
dimmer[dim_num].pin = dim_pin;
|
|
}
|
|
|
|
|
|
void Dimmer_init_end()
|
|
{
|
|
unsigned char j=0;
|
|
|
|
for(unsigned char i=0; i<DIMM_MAX; i++)
|
|
{
|
|
if(dimmer[i].pin != 0xff)
|
|
{
|
|
sort_vals[j].pin = dimmer[i].pin;
|
|
j++;
|
|
pinMode(dimmer[i].pin, OUTPUT);
|
|
}
|
|
}
|
|
|
|
dims = j;
|
|
}
|
|
|
|
|
|
|
|
|
|
void tim_form()
|
|
{
|
|
unsigned char j;
|
|
|
|
not_z = 0;
|
|
for(j = 0; (sort_vals[j].val == 0 && j < dims); j++) not_z++;
|
|
|
|
lim = dims - not_z;
|
|
sort[lim*2-1] = sort_vals[dims-1];
|
|
|
|
for(j=0; j<lim-1; j++)
|
|
{
|
|
sort[lim*2-2-j].val = sort_vals[dims-1-j].val - sort_vals[dims-j-2].val;
|
|
sort[lim*2-2-j].pin = sort_vals[dims-j-2].pin;
|
|
}
|
|
|
|
sort[lim-1].val = 255 - sort_vals[dims-1].val + sort_vals[not_z].val;
|
|
sort[lim-1].pin = sort_vals[dims-1].pin;
|
|
|
|
for(j = 0; j<lim-1; j++)
|
|
{
|
|
sort[j] = sort[j+lim];
|
|
}
|
|
}
|
|
|
|
|
|
void SSR_switch(unsigned char dim_num, unsigned char state)
|
|
{
|
|
Dimm_value(dim_num, 0);
|
|
|
|
dimmer[dim_num].flag = SSR;
|
|
dimmer[dim_num].SSR_state = state;
|
|
|
|
if(state == 0) digitalWrite(dimmer[dim_num].pin, 0);
|
|
}
|
|
|
|
|
|
void Dimm_value(unsigned char dim_num, unsigned char power)
|
|
{
|
|
if(power > 240) power = 240;
|
|
|
|
dimmer[dim_num].flag = DIMM;
|
|
dimmer[dim_num].val = power;
|
|
unsigned char j;
|
|
|
|
for(unsigned char i = 0; i<dims; i++)
|
|
if(sort_vals[i].pin == dimmer[dim_num].pin)
|
|
{
|
|
if(power > sort_vals[i+1].val && i<dims-1)
|
|
{
|
|
for(j = 1; ((power > sort_vals[i+j].val) && (i+j<dims)); j++)
|
|
{
|
|
sort_vals[i+j-1] = sort_vals[i+j];
|
|
}
|
|
|
|
sort_vals[i+j-1].val = power;
|
|
sort_vals[i+j-1].pin = dimmer[dim_num].pin;
|
|
}
|
|
else if(power < sort_vals[i-1].val && i>0)
|
|
{
|
|
for(j = 1; ((power < sort_vals[i-j].val) && (i-j>=0)); j++)
|
|
{
|
|
sort_vals[i-j+1] = sort_vals[i-j];
|
|
}
|
|
|
|
sort_vals[i-j+1].val = power;
|
|
sort_vals[i-j+1].pin = dimmer[dim_num].pin;
|
|
}
|
|
else sort_vals[i].val = power;
|
|
|
|
i = dims;
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void Heater(unsigned char dim_num, unsigned char heat_power)
|
|
{
|
|
Dimm_value(dim_num, 0);
|
|
|
|
dimmer[dim_num].flag = HEAT;
|
|
dimmer[dim_num].heat_val = heat_power;
|
|
|
|
if(heat_power == 0) digitalWrite(dimmer[dim_num].pin, 0);
|
|
}
|
|
|
|
|
|
//======================================================================
|
|
|
|
|
|
ISR(INT0_vect)
|
|
{
|
|
if(sort_vals[dims-1].val != 0 && dims > 0)
|
|
{
|
|
tim_form();
|
|
cnt=lim*2-1;
|
|
TCNT1 = 0xffff - (ZERO_VAL - K*sort[cnt].val);
|
|
}
|
|
|
|
for(unsigned char i = 0; i<DIMM_MAX; i++)
|
|
{
|
|
if(dimmer[i].flag != DIMM)
|
|
{
|
|
if(dimmer[i].flag == HEAT)
|
|
{
|
|
if(dimmer[i].heat_val > heat_cnt) digitalWrite(dimmer[i].pin, 1);
|
|
else digitalWrite(dimmer[i].pin, 0);
|
|
}
|
|
else
|
|
{
|
|
if(dimmer[i].SSR_state > 0) digitalWrite(dimmer[i].pin, 1);
|
|
}
|
|
}
|
|
}
|
|
|
|
if(heat_cnt < MAX_HEAT_DIV-1) heat_cnt++;
|
|
else heat_cnt = 0;
|
|
|
|
}
|
|
|
|
|
|
ISR(TIMER1_OVF_vect)
|
|
{
|
|
if(sort_vals[dims-1].val != 0 && dims > 0)
|
|
{
|
|
|
|
digitalWrite(sort[cnt].pin, 1);
|
|
delayMicroseconds(30);
|
|
digitalWrite(sort[cnt].pin, 0);
|
|
|
|
while(sort[cnt-1].val == 0)
|
|
{
|
|
cnt--;
|
|
digitalWrite(sort[cnt].pin, 1);
|
|
delayMicroseconds(30);
|
|
digitalWrite(sort[cnt].pin, 0);
|
|
}
|
|
|
|
cnt--;
|
|
TCNT1 = 0xffff - K*sort[cnt].val;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|