
#include <ModbusRtu.h>
#include <DallasTemperature.h>
#include <EEPROM.h>
#include <SPI.h>
#include <INA226_WE.h>
#include <OneWire.h>

#define ID  11 // serial data ID - you can change to other
#define Vpwr 2 // AD2 input ps voltage
#define Vchar 0 // AD0 input charging voltage
#define Vbat 4 // AD4 battery voltage

#define LFin 4 // green charged
#define LCharge 6 // charge current On - yellow
#define LIn 8 // red low Vin
#define POWenable 7 // charging transistor FET

#define I2C_ADDRESS_1 0x40 // U3 - charg.current
#define I2C_ADDRESS_2 0x41 // U5 - output current

// for use with PWM charging mode
#define FULL 255
#define HALF 128
#define QUARTER 64
#define OFF 0

#define ONE_WIRE_BUS 32 // temp.sensor

int x;
int y, current=510, z;

// these two variables can be changes
// for differing on/off times.
int chargeOn = 100, Lch = 0; // charge on time
int cnt = 0, charge_status = 0; // charge off time
int charg_type = 3, read_analog_sel = 0, analog_num = 0, try_amps = 0, trx_vchrg = 0, trx_vpwr = 0, trx_vbat = 0, dig1, dig2;
int  rel_type1 = 0, pwr_inp_status = 0;
int rs485pintx = 18, rs485pinrx = 19, param_val6, param_val7, param_val8, param_val9, param_val10, param_val11, param_val12, param_val13, save_param3, save_param4;
int param_val14, param_val15, param_val16, param_val17, param_val18, param_val19, param_val20, param_val21, param_val22, param_val23, param_val24, param_val25;
byte rs485rec = LOW, rs485tra = HIGH, button_start=HIGH;
int save_param, save_param2, ch_cur, nab_prud, param_val0, param_val1, param_val2, param_val3, param_val4, param_val5;
int pout_val0, pout_val1, pout_val2, pout_val3, pout_val4, pout_val5, rel1_stat, dig7_stat=0, dig8_stat=0, dig9_stat=0, wat_press, valve1, valve2;
int dig7_opt, dig8_opt, dig9_opt,batt_count, batt_type, an_poz1, an_poz1_dec, an_poz2, an_poz2_dec, an_poz3, an_poz3_dec;
int rel1_type, an_val1, an_val2, an1_type, an2_type, an1_coef, an2_coef;
float batt_min=12.0, shift_coef1, batt_norm=12.0, curr_calc1, an1c, an2c, max_curr_batt=1.0, test_amp=1.0;
int batt_min_set=120, batt_min_send, ds_bus=32, dig1_in=0, dig2_in=0, chrg_rel=0, out_rel=0, inp_rel=0, rel_out_off=0, time_on=0, aut_reg_curr=10, battery_test=0;
int state1 = HIGH;      
int reading1;           
int previous1 = LOW;
long time1 = 0;    
long debounce1 = 50; 
int state2 = HIGH;      
int reading2;   
int previous2 = LOW;
long time2 = 0;       
long debounce2 = 50;
int state3 = HIGH; 
int reading3;           
int previous3 = LOW; 
long time3 = 0;        
long debounce3 = 50;   
int state4 = HIGH;    
int reading4;           
int previous4 = LOW;   
long time4 = 0;        
long debounce4 = 50;   

boolean ta_save = false, button_stat=false, mot2=false, mot2_stat=false;
int trx_amp_chrg, trx_amp_out, stat_mot1=0, stat_mot2=0, map_cur=0, sms_alarm=0, sms_alarm_res=0, out_relay=0, binary_in=0;
int dig1_type, dig2_type, param_val26, param_val27, param_val28, param_val29, param_val30, param_val31, bin_spec=0, bin_val1=0, bin_val2=0;
int param_val32, param_val33, param_val34, trx_temp_box;
float cool_box_val=0.0,temp_ds=50.0, temp_dallas=0.0;
float amVolt, ampers, an_value;
int8_t state = 0;
int l_act=0, nOD, batt_test_result=0;
float real_val4, bar_set1, bar_set2, vbat_val=0.0, vin_val=0.0, vpwr_val=0.0;
unsigned long startCalc = millis ();
unsigned long interval1 = 200;
long prev_millis1 = millis();
long prev_millis2 = millis();
long prev_millis3 = millis();
long prev_millis4 = millis();
long prev_millis5 = millis();
long prev_millis6 = millis();
long prev_millis7 = millis();
long prev_millis8 = millis();
long deb_millis1 = 30000; // starts charge relay after 30 sec of volt.present
long deb_millis2 = 10000; // close charge relay after 10 sec volt.lost
long deb_millis3 = 60000;// aku discharged - OFF after 60sec
long deb_millis4 = 60000;// close- Off out relay for 60sec
long deb_millis5 = 10000;// aku discharged - SMS/warning - 10sec
long deb_millis6 = 60000;// aku check capacity - period
long deb_millis7 = 300000;// aku testing time - period  5min
long deb_millis8 = 200;// charging period
int curr_calc=0, calc_cnt=0, pwr_total_sum=0;
float curr_charge = 0.0;
float curr_output = 0.0, pwr_total=0.0;
float currVal1=0.0,currVal2=0.0;
boolean batt_ok_test=false, batt_test_run=false, batt_test_volt1=false, batt_test_volt2=false, batt_test_block=false, demand=false;
float batt_check_start=0.0, batt_check_end=0.0;


int cp = 730; // charge point variable - 24V version

Modbus slave(ID, 1, 3); // 1:RX1-19,TX1-18 .. 2:RX2-17,TX2-16 .. 3:RX3-15,TX3-14
uint16_t au16data[48];

OneWire oneWire(ONE_WIRE_BUS);

DallasTemperature sensors(&oneWire);

INA226_WE ina226_1 = INA226_WE(I2C_ADDRESS_1); // charg. meas. adr 40 I2C
INA226_WE ina226_2 = INA226_WE(I2C_ADDRESS_2); // output meas. adr 45 I2C

void setup() {

slave.begin(57600);
//Serial.begin(9600);
//Serial.setTimeout(2000);

  pinMode(LIn, OUTPUT); // LED finnaly charged
  pinMode(LFin, OUTPUT); // LED charging
  pinMode(LCharge, OUTPUT); // LED error
  pinMode(POWenable, OUTPUT); // transistor PWM
  pinMode(2, OUTPUT); // PWRS relay
  pinMode(3, OUTPUT); // serial data EN pin
  pinMode(5, OUTPUT); // output 24V relay
  pinMode(9, OUTPUT); // FAN PWM out
  pinMode(11, OUTPUT); // Relay Ext on board(OUT 11)
  pinMode(47, INPUT); // dig input 1 on board
 pinMode(48, INPUT); // dig input 2 on board
 pinMode(32, INPUT); // DS18b20 on board
 pinMode(36, OUTPUT); // charging relay
 pinMode(30, OUTPUT); // CPU relay

  digitalWrite(LIn, LOW); // set LOW in all charging parameters bellow
  digitalWrite(LFin, LOW);
  digitalWrite(LCharge, LOW);
  digitalWrite(POWenable, LOW);

  digitalWrite(2, LOW); // PS relay start session
  inp_rel=1;



  if (EEPROM.read(1) > 0 && EEPROM.read(1) <= 5) { // charging mode in memory
    charg_type = EEPROM.read(1);
  } else {
    charg_type = 1; // half default
  }
   
if (EEPROM.read(2) > 0 && EEPROM.read(2) <= 255) { // min batt value
    batt_min_set = EEPROM.read(2);
    batt_min = map(batt_min_set,0,255,50,305)/10.0;
    batt_min_send = map(batt_min_set,0,255,50,305);
  } else {
    batt_min_set = 110; // min value of battery, when CPU go OFF, standard set
    batt_min = 22.0;
    batt_min_send = map(batt_min_set,0,255,50,305);
  }
  if (EEPROM.read(3) > 0 && EEPROM.read(3) <= 4) { // battery count
    batt_count = EEPROM.read(3);
  } else {
    batt_count = 2; // battery count preselected
  }
   if (EEPROM.read(4) > 0 && EEPROM.read(4) <= 15) { // battery type 
    batt_type = EEPROM.read(4);
  } else {
    batt_type = 8; // preselected battery type 12V 28Ah
  }

  if (EEPROM.read(5) >= 0 && EEPROM.read(5) <= 15) {
    rel_type1 = EEPROM.read(5);
  } // relay type
    
    
  if (EEPROM.read(6) >= 0 && EEPROM.read(6) <= 10) {
    dig1_type = EEPROM.read(6);
  } // binary input 1
  if (EEPROM.read(7) >= 0 && EEPROM.read(7) <= 10) {
    dig2_type = EEPROM.read(7);
  } // binary input 2

   if (EEPROM.read(8) >= 0 && EEPROM.read(8) <= 10) {
    an1_type = EEPROM.read(8);
  } // analog input 1

   if (EEPROM.read(9) >= 0 && EEPROM.read(9) <= 10) {
    an2_type = EEPROM.read(9);
  } // analog input 2

 if (EEPROM.read(10) >= 0 && EEPROM.read(10) <= 250) {
    an1_coef = EEPROM.read(10);
    an1c = an1_coef/1000.0; // coefficient for analog inp1
  }
  if (EEPROM.read(11) >= 0 && EEPROM.read(11) <= 250) {
    an2_coef = EEPROM.read(11);
    an2c = an2_coef/1000.0; // coefficient for analog inp2
  }

  if (EEPROM.read(12) >= 0 && EEPROM.read(12) <= 6) {
    batt_test_result = EEPROM.read(12);
  }else{ 
  batt_test_result = 0;
}

  if (batt_type<= 3 && batt_count==1){
batt_norm = 7.0;
max_curr_batt = 0.7;
test_amp=1.0;
  } else if (batt_type<= 3 && batt_count==2){
 batt_norm = 13.7;
 max_curr_batt = 1.0;
 test_amp=1.2;
} else if (batt_type == 4 && batt_count==1){
  batt_norm = 13.7;   
  max_curr_batt = 0.3;
  test_amp=0.5;
}  else if (batt_type == 4 && batt_count==2){
  batt_norm = 27.2; 
  max_curr_batt = 0.5;  
  test_amp=0.7;
}  else if (batt_type == 5 && batt_count==1){
  batt_norm = 13.7;  
  max_curr_batt = 0.5; 
  test_amp=0.8;
}  else if (batt_type == 5 && batt_count==2){
  batt_norm = 27.2;  
  max_curr_batt = 0.7; 
  test_amp=1.0;
} else if (batt_type == 6 && batt_count==1){
  batt_norm = 13.7;  
  max_curr_batt = 0.5; 
  test_amp=1.3;
}  else if (batt_type == 6 && batt_count==2){
  batt_norm = 27.2;  
  max_curr_batt = 0.7; 
  test_amp=1.6;
}else if (batt_type == 8 && batt_count==1){
  batt_norm = 13.7; 
  max_curr_batt = 1.5; 
  test_amp=1.8; 
} else if (batt_type == 8 && batt_count==2){
  batt_norm = 27.2; 
  max_curr_batt = 1.8;  
  test_amp=2.0;
}


Wire.begin();

ina226_1.init();//charging meas.init
ina226_2.init();// output meas.init

ina226_1.setResistorRange(0.1, 5.0);
ina226_2.setResistorRange(0.0035, 40.0);

ina226_1.setCorrectionFactor(1.05);
 ina226_2.setCorrectionFactor(1.79);

 
  ina226_1.waitUntilConversionCompleted();
  ina226_2.waitUntilConversionCompleted();

  sensors.setWaitForConversion(false);

  delay(100);

  /* SMS alarms :
1 - low voltage on charger
2 - low voltage of battery
3 - battery discharged
4 - battery disconnected - fuse blowed
5 - battery check info
6 - battery test running
  */
 
}

int AnalogAvg(int numpin){
 int average = 0;
 for (int i=0; i < 50; i++) {
 average = average + analogRead(numpin);
 }
 average = average/50;
return average;
}// analog stabilise

float CurrentAvg1(){
float aver1 = 0;
 currVal1 = ina226_1.getCurrent_A();//charging meas.

 for (int j=0; j < 10; j++) {
 aver1 = aver1 + currVal1;
 }
  test_amp=1.6;
 aver1 = aver1/10;
return aver1;
}

float CurrentAvg2(){
float aver2 = 0;

 currVal2 = ina226_2.getCurrent_A();//output meas.

for (int k=0; k < 10; k++) {
 aver2 = aver2 + currVal2;
 }
 aver2 = aver2/10;
return aver2;
}


void loop() {

 
 state = slave.poll(au16data, 48); 

 //Serial.println((String)state);
                                   
 getDataSerial();

 //curr_charge = ina226_1.getCurrent_A();
 //curr_output = ina226_2.getCurrent_A(); 

 curr_charge = CurrentAvg1();
 curr_output = CurrentAvg2();

  an_val1 = AnalogAvg(3); 
  an_val2 = AnalogAvg(5);
 
  dig1 = digitalRead(47);
  dig2 = digitalRead(48);

  sensors.requestTemperatures();
temp_dallas = sensors.getTempCByIndex(0);
trx_temp_box = round(temp_dallas*10);

if (temp_dallas>40){ // fan PWM output
analogWrite(9,map(round(temp_dallas),40,60,180,250)); 
}else if (temp_dallas<40){
analogWrite(9,LOW);
}

// ******* battery testing on demand //

if (battery_test==1 && vbat_val>(batt_norm/1.12) && curr_output>=test_amp){
 batt_test_run = true;
 demand = true;
 } 

// ****** battery testing with period//
if (batt_ok_test==true && vbat_val>(batt_norm/1.12) && curr_output>=test_amp && batt_test_result<6){
batt_test_run=true;
}else{
batt_test_run = false; 
batt_test_volt1=false;
batt_test_volt2=false;
}

if (sms_alarm_res==1){
  if (sms_alarm<5){
  sms_alarm=0;  
  }
  }

if (batt_test_run == true){
if ((millis () - prev_millis6 >= deb_millis6) or demand==true){
  sms_alarm = 5;
digitalWrite(2,HIGH); // PS relay - disconnect
inp_rel=0;
digitalWrite(36,LOW);
batt_test_block=true;
if (batt_test_volt1==false){
batt_check_start=vbat_val;
batt_test_volt1=true;  
}

if (millis () - prev_millis7 >= deb_millis7){
if (batt_test_volt2==false){
batt_check_end=vbat_val;
batt_test_volt2=true;  
}
if ((batt_check_start-batt_check_end)>(batt_norm/10)){
sms_alarm = 6; 
EEPROM.write(12,6);
demand=false;
}
if ((batt_check_start-batt_check_end)<=(batt_norm/8)){
sms_alarm = 0; 
EEPROM.write(12,0);
demand=false;
}

if (batt_test_block==true){
batt_test_volt1=false;
batt_test_volt2=false;
deb_millis6 = 2073600000;
batt_test_run = false;
digitalWrite(2, LOW); // PS relay - connect
inp_rel=1;
batt_test_block=false;
}
} /*else { // end of millis7
sms_alarm = 6; // not yet applicable
}*/
}else {
prev_millis7 = millis();  
}
}else{
if (batt_test_result==6){
sms_alarm = 6;  
}
prev_millis6 = millis();
}

  if (out_relay==1){
rel_out_off=1;
    } 

  if (dig1_type==0){
  bin_val1=0;  
  } else if (dig1_type==1){
  if (dig1==1){
bin_val1= 0;
  } else {
 bin_val1=1;   
  } 
   
  }else if (dig1_type==2){
  if (dig1==1){
bin_val1= 1;
  } else{
 bin_val1=0;   
  } 
  }// end DIG1

  if (dig2_type==0){
  bin_val2=0;  
  }else if (dig2_type==1){
  if (dig2==1){
bin_val2= 0;
  } else{
 bin_val2=1;   
  } 
   
  }else if (dig2_type==2){
  if (dig2==1){
bin_val2= 1;
  } else{
 bin_val2=0;   
  } 
  }// end DIG1


    
    if (dig7_opt == 14) {
    if (dig8_opt == 15) { 

if (cool_box_val >= temp_ds){
 
  dig7_stat = 1;
  }
 if (cool_box_val < (temp_ds-8.0)){
  
  dig7_stat = 0;
  } 
    }   
    if (dig9_opt == 15) {  

if (cool_box_val >= temp_ds){
 
  dig7_stat = 1;
  }
 if (cool_box_val < (temp_ds-8.0)){

  dig7_stat = 0;
  }
    }  
    }// dig7_opt

    if (dig8_opt == 14) {
    if (dig7_opt == 15) {
    

if (cool_box_val >= temp_ds){
 
  dig8_stat = 1;
  }
 if (cool_box_val < (temp_ds-8.0)){
 
  dig8_stat = 0;
  }
    }   
    if (dig9_opt == 15) {
    
if (cool_box_val >= temp_ds){
  
  dig8_stat = 1;
  }
 if (cool_box_val < (temp_ds-8.0)){
 
  dig8_stat = 0;
  }
    }  
    }// dig8_opt

    if (dig9_opt == 14) {
    if (dig7_opt == 15) {
     

if (cool_box_val >= temp_ds){
  
  dig9_stat = 1;
  }
 if (cool_box_val < (temp_ds-8.0)){
 
  dig9_stat = 0;
  }
    }   
    if (dig8_opt == 15) {
      
if (cool_box_val >= temp_ds){
 
  dig9_stat = 1;
  }
 if (cool_box_val < (temp_ds-8.0)){
 
  dig9_stat = 0;
  }
    }  
    }// dig9_opt
  
 
  x = analogRead(Vchar);//bat raw value
  y = analogRead(Vbat); // chrg input pwr raw value
  z = analogRead(Vpwr); // main pwr raw value
  int vbat_trx = map(y,0,1023,0,383);
  trx_vbat = vbat_trx;
  int vin_trx = map(x,0,1023,0,383);
  trx_vchrg = vin_trx;
   int vpwr_trx = map(z,0,1023,0,383);
  trx_vpwr = vpwr_trx;
  vbat_val = vbat_trx/10.0;
  vin_val = vin_trx/10.0;
  vpwr_val = vpwr_trx/10.0;

  if (save_param4 == 8) {
    EEPROM.write(5, pout_val0); // settings type of Rel1 action
    EEPROM.write(6, param_val26); // dig1_type
    EEPROM.write(7, param_val27); // dig2_type
    EEPROM.write(8, param_val12); // an1_type
    EEPROM.write(9, param_val13); // an2_type
    EEPROM.write(10, param_val16); // an1_coef
    EEPROM.write(11, param_val17); // an2_coef
    delay(200);
  
    asm volatile ("  jmp 0"); //soft reset-restart
  }// externaly analog type set via modbus

  if (save_param == 3) {
    int param_val0_set = map(param_val0,50,305,0,255);
    EEPROM.write(1, param_val3); // charging type
    EEPROM.write(2, param_val0_set); // batt_min volt
    EEPROM.write(3, param_val1); // batt_count
    EEPROM.write(4, param_val2); // batt_type
    delay(100);
       asm volatile ("  jmp 0"); //soft reset-restart
    
  }// externaly charging settings via modbus

  // ---------------------- IN/OUT settings

  if (vin_val>=(batt_norm/1.15) or vbat_val>=(batt_norm/1.20)){ 
  digitalWrite(30,HIGH);
  digitalWrite(5,HIGH);
}
if ((vin_val>=(batt_norm/1.15) or charge_status<=1)&& vpwr_val>=vbat_val){ // check input voltage for charging

if (batt_test_block==false){
if (millis () - prev_millis1 >= deb_millis1){
digitalWrite(36,HIGH); // start charge relay afte 30s of voltage present (Vin>26V), if you have used 12V battery, change compare value vin_val>=14 
chrg_rel = 1;
}
}else{
prev_millis1 = millis();  
}
prev_millis2 = millis();
}else if (vin_val<(batt_norm/1.25) or vpwr_val<vbat_val){ //  
  if (millis () - prev_millis2 >= deb_millis2){
digitalWrite(36,LOW); // close charge relay afte 10s voltage lost  
chrg_rel = 0;
if (batt_test_block==false){
sms_alarm = 1;
} 
}
prev_millis1 = millis();
}else if ((vin_val>=(batt_norm/1.25) && vbat_val<batt_norm) or charge_status==2){
  if (millis () - prev_millis2 >= deb_millis2){
digitalWrite(36,LOW); // close charge relay afte 10s voltage lost  
chrg_rel = 0;
sms_alarm = 4;  // battery not connected
}
prev_millis1 = millis();
}
/////// ..... SERIAL DEBUG INFORMATION

 /*Serial.println((String)"vin_val = "+vin_val);
  Serial.println((String)"vbat_val = "+vbat_val);
   Serial.println((String)"batt_min = "+batt_min);
  Serial.println((String)"trx_vbat = "+trx_vbat);
  Serial.println((String)"trx_vchrg = "+trx_vchrg);
  Serial.println((String)"trx_vpwr = "+trx_vpwr);
    Serial.println((String)"trx_amp_chrg = "+trx_amp_chrg);
  Serial.println((String)"current_charge= "+curr_charge);
  Serial.println((String)"current_output= "+curr_output);
  Serial.println((String)"curr_calc1= "+curr_calc1);
  Serial.println((String)"curr_calc= "+curr_calc);
  Serial.println((String)"map_cur= "+map_cur);
  Serial.println((String)"charg_type = "+charg_type);
  Serial.println((String)"an_val1 = "+an_val1);
  Serial.println((String)"an_val2 = "+an_val2);
  Serial.println("--------------------");*/
/*
  Serial.println("--------------------");
   Serial.print("x: ");
   Serial.println(x);
   Serial.print("y: ");
   Serial.println(y);
  Serial.println("--------------------");
   Serial.print("cp: ");
   Serial.println(cp);
  Serial.println("--------------------");
  */
  /*Serial.println((String)"vbat_val = "+vbat_val);
  Serial.println((String)"current_output= "+curr_output);
  Serial.print("batt_ok_test - ");
  Serial.println(batt_ok_test,DEC);
  Serial.print("batt_test_run - ");
  Serial.println(batt_test_run,DEC);
  Serial.print("batt_test_block - ");
  Serial.println(batt_test_block,DEC);
  Serial.print("batt_test_volt1 - ");
  Serial.println(batt_test_volt1,DEC);
  Serial.print("batt_test_volt2 - ");
  Serial.println(batt_test_volt2,DEC);
  Serial.println((String)"batt_test_result = "+batt_test_result);
  Serial.println((String)"batt_norm = "+batt_norm);
  Serial.println("--------------------");*/
  
  /*Serial.println((String)"analog1 = "+analog1);
  Serial.println((String)"analog2 = "+analog2);}
  Serial.println((String)"analog3 = "+analog3);
  Serial.println((String)"analog4 = "+analog4);*/
  
 /*
  Serial.println((String)"an_val1 = "+an_val1);
  Serial.println((String)"an_val2 = "+an_val2);
  Serial.println("--------------------");*/
  
  
 /*
  Serial.println((String)"rel_type1 = "+rel_type1);
  Serial.println((String)"hour_end = "+hour_end);
  Serial.println((String)"min_end = "+min_end);
  Serial.println((String)"charge_status = "+charge_status);
  Serial.println((String)"pwr_inp_status = "+pwr_inp_status);
  Serial.println("--------------------"); */


  

    if (rel_type1 == 0) { // UNUSED RELAY selection
      digitalWrite(11, LOW);
      rel1_stat=0;
    }// out1=1

if (rel_type1 == 1) { // RELAY for RC
if (binary_in==1){
digitalWrite(11, HIGH);
      rel1_stat=1;  
} else if(binary_in==0){
      digitalWrite(11, LOW);
      rel1_stat=0;
      }
    }// out1=1

if (rel_type1 == 2) { // EXT.relay for  DS18b20 acting

}

    if (rel_type1==3){// relay for impulse switch type with DIG1 input
 if (bin_val1 == HIGH && previous1 == LOW && millis() - time1 > debounce1) {
    if (state1 == HIGH)
      state1 = LOW;
    else
      state1 = HIGH;

    time1 = millis();    
  }
  digitalWrite(11, state1);
  rel1_stat=state1;
  previous1 = dig1;
   
  }// out1

      if (rel_type1==4){// relay for impulse switch type with DIG2 input
 if (bin_val2 == HIGH && previous1 == LOW && millis() - time1 > debounce1) {
    if (state1 == HIGH)
      state1 = LOW;
    else
      state1 = HIGH;

    time1 = millis();    
  }
  digitalWrite(11, state1);
  rel1_stat=state1;
  previous1 = dig1;
   
  }// out1






if (((vbat_val>0 && vbat_val<batt_min) && pwr_inp_status==0)){ // relay action based on discconection on battery low status
if (millis () - prev_millis5 >= deb_millis5){
sms_alarm = 3;  


/*if (millis () - prev_millis3 >= deb_millis3){ // temporary disabled to check problems
      digitalWrite(5, LOW);
      digitalWrite(30,LOW);
      out_rel=0;
     
}*/
}

}else if (rel_out_off==0 && ((pwr_inp_status==1 && vbat_val>batt_min) or vbat_val>batt_min)) { // starting application and charging relays/components on conditions
prev_millis3 = millis ();
prev_millis5 = millis ();
prev_millis4 = millis ();
      digitalWrite(5, HIGH);
      digitalWrite(30,HIGH);
      out_rel=1;

 } else if (rel_out_off==1){
  digitalWrite(5,LOW);
out_rel=0;
if (millis () - prev_millis4 >= deb_millis4){

      digitalWrite(5, HIGH);
      out_rel=1;
    rel_out_off=0; 
    
} else{
long odcit = millis() - prev_millis4;
time_on = (deb_millis4-odcit)/1000;
 }  
}  


  if (pwr_inp_status == 0) {
    digitalWrite(LCharge, LOW);
    charge_status = 2;
    analogWrite(POWenable, OFF);
      
        trx_amp_chrg=0; 

pwr_total = (vbat_val-0.8)*curr_output;
pwr_total_sum = round(pwr_total*10);
trx_amp_out=round(curr_output*100); 
      
  }

  if (pwr_inp_status==1){
pwr_total = (vin_val-0.8)*curr_output;
pwr_total_sum = round(pwr_total*10);
trx_amp_out=round(curr_output*100);
}

  if (cnt == 0) {
    
    if (vbat_val<(batt_norm/1.35)) {
      analogWrite(POWenable, OFF);
      digitalWrite(LCharge, LOW);
      charge_status = 2;
    }
  }

  // red LED
  if (vin_val<(batt_norm/1.1)) {
    digitalWrite(LIn, HIGH);
    pwr_inp_status = 0;
    analogWrite(POWenable, OFF);
  } else {
    digitalWrite(LIn, LOW);
    pwr_inp_status = 1;
  }
  // red LED on indicates low or no input voltage

  // green LED
  if (vbat_val>batt_norm) {
    digitalWrite(LFin, HIGH);
    Lch = 1;
    digitalWrite(LCharge, LOW); // Charge LED off
    analogWrite(POWenable, OFF);
    charge_status = 0;
    batt_ok_test = true;
  } else if (vbat_val<(batt_norm/1.1)) {
    digitalWrite(LFin, LOW);
    Lch = 0;
  }
  // LED on means battery is charged

  /*if (pwr_inp_status == 0) { // disabled for testing
    chargeOn = 30;
  } else {
    chargeOn = (cp - y) * 5;
  }*/

  // Serial.print("chon = ");
  //Serial.println(chargeOn);

if ((vin_val > vbat_val) && (vbat_val < batt_norm) && (vin_val>=batt_norm))  {
/*
 */ 
    // check input voltage and voltage on battery
    // turn on charge cycle if voltage input
    // good AND battery voltage low.

    if ((vbat_val > (batt_norm/1.35)) && vbat_val < batt_norm/1.05)   { // turn on voltage to battery

        // turn on charge LED
        digitalWrite(LCharge, HIGH);
        // charge switching transistor
        // can be pulse-width modulated
        // four values are OFF, QUARTER, HALF, FULL and AUTOMAT
        // This uses DP3.
      
              

if (millis () - prev_millis8 >= deb_millis8){

 prev_millis8 = millis();
 charge_status = 0;

  } else {

 if (charg_type == 1) {

aut_reg_curr = map(curr_charge, max_curr_batt,max_curr_batt+0.5, 180,0);
analogWrite(POWenable, aut_reg_curr);
charge_status = 1;
//}
}
        if (charg_type == 2) {
          analogWrite(POWenable, FULL);
          charge_status = 1;
        }
        if (charg_type == 3) {
          analogWrite(POWenable, HALF);
          charge_status = 1;
        }
        if (charg_type == 4) {
          analogWrite(POWenable, QUARTER);
          charge_status = 1;
        }
        if (charg_type == 5) {
          analogWrite(POWenable, OFF);
          charge_status = 0;
        }

        /*Serial.print(temp);
          Serial.print("    I out = ");
          Serial.print((temp - 506) * .0283);
          Serial.println(" amps. ");*/
      }// charging period

}
  } // end if
  

 /* if (cnt >= chargeOn) { // disabled for testing
    
    analogWrite(POWenable, OFF);  // turn off MOSFET
    cnt = 0;
    delay(10);
  } else {
    cnt++;
  }*/
  // turn off charge enable

  trx_amp_chrg=round(curr_charge*100);

}

void getDataSerial(){
  // operational data
 au16data[0] = sms_alarm; // errors to SMS
 au16data[1] = trx_amp_chrg; // transmitt chrg ampers
 au16data[2] = trx_amp_out; // transmitt out ampers
 au16data[3] = trx_vbat; //transmitt batt.voltage
 au16data[4] = trx_vchrg; //transmitt charger voltage
au16data[5] = trx_vpwr; //transmitt ps input voltage
 au16data[6] = charge_status;
au16data[7] = pwr_inp_status;
au16data[8] = rel1_stat;
au16data[9] = an_val1;
au16data[10] = an_val2;
au16data[11] = dig1;
 au16data[12] = dig2;
 au16data[13] = chrg_rel;
 au16data[14] = out_rel;
 au16data[15] = trx_temp_box;
 au16data[16] = pwr_total_sum;
 au16data[17] = time_on;
 au16data[18] = inp_rel;
 au16data[19] = 0;//rez
//data nastaveni - read
au16data[20] = an1_type;
au16data[21] = an2_type;
au16data[22] = an1_coef;
au16data[23] = an2_coef;
au16data[24] = rel_type1;
au16data[25] = dig1_type;
 au16data[26] = dig2_type;
 au16data[27] = batt_min_send; //minimal battery voltage to power OFF CPU electronics
 au16data[28] = batt_count;
 au16data[29] = batt_type;
 au16data[30] = charg_type;
 
 //settings data to node red via modbus
param_val0 = au16data[31]; // batt_min voltage
param_val1 = au16data[32]; // batt_count
param_val2 = au16data[33]; // batt_type
param_val3 = au16data[34]; // charge_type
save_param = au16data[35]; // saving 40-43
pout_val0 = au16data[36]; //rel1 function
param_val26 = au16data[37]; //dig1_type
param_val27 = au16data[38]; //dig2_type
param_val12 = au16data[39]; //An1_type
param_val13 = au16data[40]; //An2_type
param_val16 = au16data[41]; //An1_coef
param_val17 = au16data[42]; //An2_coef
save_param4 = au16data[43]; // saving 46-51

//remote commands from node red
sms_alarm_res = au16data[44]; //reset a SMS alarm to 0
out_relay = au16data[45]; //relay_out off
battery_test = au16data[46]; //battery_test
binary_in = au16data[47]; //digital/binary
}
