M5Atom_airqa/anemostat/AC_dimmer-dmr-0.2.1-master/AC_dimmer-dmr-0.2.1-master/AC_Dimmer/AC_Dimmer/AC_Dimmer.cpp

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;
}
}