//Mereni energie
//(c) Jan Chroust 2013


#include "C:main.h"

#define EEPROM_SDA  PIN_C4
#define EEPROM_SCL  PIN_C3
//rele v blok sch. REL1 a REL2
#define REL1_IN1  PIN_D6
#define REL1_IN2  PIN_D7
//rele v blok sch. REL5
#define REL2_IN1  PIN_B2
#define REL2_IN2  PIN_B3
//rele v blok sch.REL3
#define REL3_IN1  PIN_A0
#define REL3_IN2  PIN_A1
//rele v blok sch.REL3
#define REL4_IN1  PIN_A2
#define REL4_IN2  PIN_A3

#define NOC  PIN_B1 //pro povoleni moznosti nabijet


#use i2c(master, sda=EEPROM_SDA, scl=EEPROM_SCL)
#use rs232(baud=9600,parity=N,xmit=PIN_C7,rcv=PIN_C6,bits=8) //rcv TXD xmit RXD
#include "BQ34Z100.h"

//BAT3 - pro pohyblivý panel - LION1CELLB-1
//BAT2 - pro fixní panel - LION1CELLB-2
//BAT1 - hlavní baterie - LION1CELLB-3
int16 bat1STAV,bat2STAV,bat3STAV; //zbyvajici eneregie akumulátoru v %
signed int16 bat1PROUD,bat2PROUD,bat3PROUD; //proud akumulatorem
int16 bat1NAP,bat2NAP,bat3NAP; //napeti akumulatoru
signed int16 bat1P,bat2P, bat3P; //vykon z nebo do akumulatoru

 //pro odeslání
signed int16 rozdil;
char baterka[40];


void batMODE(int d) //nastavi rele do prislusneho modu
{
switch (d) {

    case 1:    output_high(REL1_IN2); //pro mereni
               output_high(REL2_IN1);
               output_high(REL3_IN2);
               output_high(REL4_IN2);
               delay_ms(100);
               output_low(REL1_IN1);
               output_low(REL1_IN2);
               output_low(REL2_IN1);
               output_low(REL2_IN2);
               output_low(REL3_IN1);
               output_low(REL3_IN2);
               output_low(REL4_IN1);
               output_low(REL4_IN2);
               
            break;

    case 2:    output_high(REL1_IN2); //dobijeni Hl. clanku z bat3
               output_high(REL2_IN1); 
               output_high(REL3_IN1);
               output_high(REL4_IN2); 
               delay_ms(100);
               output_low(REL1_IN2);
               output_low(REL2_IN1);
               output_low(REL3_IN1);
               output_low(REL4_IN2); 
           break;
           
    case 3:    output_high(REL1_IN2); //dobijeni Hl. clanku z bat2
               output_high(REL2_IN1);
               output_high(REL3_IN2);
               output_high(REL4_IN1);
               delay_ms(100);
               output_low(REL1_IN2);
               output_low(REL2_IN1);
               output_low(REL3_IN2);
               output_low(REL4_IN1);

           break;

    case 4:    output_high(REL1_IN1); //dobijeni Hl. clanku ze sol. clanku
               output_high(REL2_IN1);
               output_high(REL3_IN2);
               output_high(REL4_IN2);
               delay_ms(100);
               output_low(REL1_IN1);
               output_low(REL2_IN1);
               output_low(REL3_IN2);
               output_low(REL4_IN2);  
               

           break;
    case 5:    output_high(REL1_IN2); //vybijeni bat3 do R
               output_high(REL2_IN2); 
               output_high(REL3_IN1);
               output_high(REL4_IN2);
               delay_ms(100);
               output_low(REL1_IN2);
               output_low(REL2_IN2);
               output_low(REL3_IN1);
               output_low(REL4_IN2);

           break;

    case 6:    output_high(REL1_IN2); //vybijeni bat2 do R
               output_high(REL2_IN2);
               output_high(REL3_IN2);
               output_high(REL4_IN1);
               delay_ms(100);
               output_low(REL1_IN2);
               output_low(REL2_IN2);
               output_low(REL3_IN2);
               output_low(REL4_IN1);
  
   default:printf("chyba");

           break; }
        

}


void setHUB(int d) //vstupuje 1-8
//hodnota udava jaky port bude pripojen na master I2C
//zde je nastaveno propojeni jen jedne brany, je mozne propojit i vice bran naraz
{
switch (d) {

    case 1: d=0x01;

           break;

    case 2: d=0x02;

           break;
           
    case 3: d=0x04;

           break;

    case 4: d=0x08;

           break;
    case 5: d=0x10;

           break;

    case 6: d=0x20;

           break;
    case 7: d=0x40;

           break;

    case 8: d=0x80;

           break;
   
   default:printf("chyba");

           break; }
   
   i2c_start();
   I2C_Write(0xE0);
   
   I2C_write(d);
   i2c_stop();           

}

//nacitani potrebnych informaci z modulu s baterii
void batdata(void)
{
   setHUB(1);
   bat1PROUD=batPROUD();
   bat1STAV=batSTAV();
   bat1NAP=batNAP();
   setHUB(2);
   bat2PROUD=batPROUD();
   bat2STAV=batSTAV();
   bat2NAP=batNAP();
   setHUB(3);
   bat3PROUD=batPROUD();
   bat3STAV=batSTAV();
   bat3NAP=batNAP();
   
   bat1P=(bat1PROUD*(((float)bat1NAP/1000)));
   bat2P=(bat2PROUD*(((float)bat2NAP/1000)));
   bat3P=(bat3PROUD*(((float)bat3NAP/1000)));
}


void main()
{
batMODE(1);
float vypocet;

   setup_adc_ports(NO_ANALOGS|VSS_VDD);
   setup_adc(ADC_CLOCK_DIV_2);
   setup_spi(SPI_SS_DISABLED);
   setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
   setup_timer_1(T1_DISABLED);
   setup_timer_2(T2_DISABLED,0,1);
   setup_ccp1(CCP_OFF);
   setup_comparator(NC_NC_NC_NC);// This device COMP currently not supported by the PICWizard

 batMODE(1);


//printf("STAV1 STAV2 STAV3 VYKON1 VYKON2 VYKON3\r\n");
while(TRUE)
{
  
 batdata();  
//nastane pri nedostatku energie v hl. akumulátoru
while(bat1STAV<20)
   {
   //printf("nedostatek energie\r\n");
   if(bat2STAV>10)
      {
      batMODE(3);
      }
   else
      {
      if(bat3STAV>10)
      {
      batMODE(2);
      }
      else
      {
      batMODE(4);
      }
      }
      batdata();
      sprintf(baterka, " %3.0Ld %3.0Ld %3.0Ld %5.0Ld %5.0Ld %5.0Ld %5.0Ld", bat1STAV, bat2STAV, bat3STAV, bat1P, bat2P, bat3P, 0);
      printf(baterka);
      delay_ms(5000); 
    }
 
//osetreni proti prebiti clanku 
 while(bat2STAV>96) 
   {
   //printf("bat2 prebita");
   if(bat1STAV>98)
      {
      batMODE(6); //vybijeni do rezistoru
      }
   else
      {
      batMODE(3); //nabijeni hl. akumulatoru
      }
      
      batdata();  
      sprintf(baterka, " %3.0Ld %3.0Ld %3.0Ld %5.0Ld %5.0Ld %5.0Ld %5.0Ld", bat1STAV, bat2STAV, bat3STAV, bat1P, bat2P, bat3P, 0);
      printf(baterka);
      bat2STAV=bat2STAV-2;
      delay_ms(5000); 
    }
    
while(bat3STAV>96)
   {
   //printf("bat3 prebyta\r\n");
   if(bat1STAV>98)
      {
      batMODE(5); //vybijeni do rezistoru
      }
   else
      {
      batMODE(2); //vybijeni do hl. akumulatoru
      }
      
      batdata(); 
      sprintf(baterka, " %3.0Ld %3.0Ld %3.0Ld %5.0Ld %5.0Ld %5.0Ld %5.0Ld", bat1STAV, bat2STAV, bat3STAV, bat1P, bat2P, bat3P, 0);
      printf(baterka);
      bat3STAV=bat3STAV-2;
      delay_ms(5000);
    }

while(input(NOC)==1) //nastane pri zapadu Slunce
{
//printf("noc\r\n");
batdata();

if(bat1STAV<98) //dobiti hl. akumulatoru
   {
   
   if(bat2STAV>20)
      {
      batMODE(3);
      }
   else
      {
     
      if(bat3STAV>20)
      {
      batMODE(2);
      }
      else
      {
      batMODE(1);
      }
          
      }
   batdata();
   }
else //prebitecna energie do rezistoru
   {
   if(bat2STAV>20)
      {
      batMODE(6);
      }
      else
      {
      if(bat3STAV>20)
      {
      batMODE(5);
      }
      else
      {
      batMODE(1);
      }
      }
   }   

batdata();  
sprintf(baterka, " %3.0Ld %3.0Ld %3.0Ld %5.0Ld %5.0Ld %5.0Ld %5.0Ld", bat1STAV, bat2STAV, bat3STAV, bat1P, bat2P, bat3P, 0);
//sprintf(baterka, "%Ld %Ld %Ld 0 0 0 0" bat1STAV, bat2STAV, bat3STAV);
printf(baterka);
delay_ms(5000);
}
 
   batMODE(1);
   if(bat2P==0) //osetreni deleni nulou
    {
     rozdil=9999;
    }
   else
    {
   vypocet=(((float)bat3P-bat2P)/bat2P)*100; //vypocet rozdilu dodavane enengie dodavane solárnim panelem sledujícím Slunce a fixnim solarnim panelem
   rozdil=(signed int)vypocet;
    }
    
//zaslani namerenych udaju na seriovou linku
   sprintf(baterka, " %3.0Ld %3.0Ld %3.0Ld %5.0Ld %5.0Ld %5.0Ld %5.0Ld", bat1STAV, bat2STAV, bat3STAV, bat1P, bat2P, bat3P, rozdil);
   printf(baterka);
   delay_ms (20000);
 }  
}