// ********************************************************************
// VIATOR LIGHT 1.0
// by Giuseppe De Lorenzo
// 30 gennaio 2016
//---------------------------------------------------------------------
// MONITOR PER INVERTER MPP 4048
// Permette la lettura dei dati, inviando i comandi QMOD e QPIGS
//
// Per maggiori info : http://www.homoandroidus.com/viator
//
//*********************************************************************

// tutto cio che concerne la sezione RS232 ****************
// http://blog.startingelectronics.com/how-to-use-arduino-serial-ports/

// IMPORTANTE !!!
// modificare SoftwareSerial.h portando il buffer di ricezione a 128 bytes (altrimenti non funziona) !
// info su homoandroidus.com/viator

// se si usa arduino MEGA, commentare queste due linee e utilizzare i piedini 18-19 della seriale 1
#include <SoftwareSerial.h>  
SoftwareSerial Serial4(10,11);   //rx/tx

//---------------------------------------------
// Sequenza dati da inviare all'inverter - vedi manuale pdf relativo al protocollo di comunicazione
// --------------------------------------------
// QPIGS + CRC + CR ---> info generali sull'attuale funzionamento 
byte ComandoQPIGS[] = {0x51, 0x50, 0x49, 0x47, 0x53, 0xB7, 0xA9, 0x0D};
// --------------------------------------------
// QMOD + CRC + CR ---> per sapere se si sta andando a sole o a enel
byte ComandoQMOD[] = {0x51, 0x4D, 0x4F , 0x44 , 0x49, 0xC1, 0x0D};
// --------------------------------------------

String StringaTemp;
String TuttaLaStringa;

String GridVoltage,GridFrequency,AcOutputVoltage,AcOutputFrequency;
String AcOutputActivePower,OutputLoadPercent,BatteryChargingCurrent;
String ModoInverter,DeviceMode,b2ChargingStatus,BatteryVoltage,BatteryCapacity;

unsigned long prevmillis = 0;
unsigned long currentmillis = 0;
unsigned long prevmillis1 = 0;
unsigned long currentmillis1 = 0;
unsigned long intervallo = 2000;    //intervallo tra 2 letture

int TipoDiComandoDaInviare = 1;

#define LED_RX   13                // led monitor (quello già presente su arduino)



//********************************************
void setup()
{
  Serial.begin(9600);          //  setup monitor seriale
  Serial1.begin(2400);         //  apro la porta verso l'inverter
  pinMode(LED_RX, OUTPUT);   
  Serial.println("-----------------------------------------------------------------------"); 
  Serial.println("VIATOR light 1.0");
  Serial.println("-----------------------------------------------------------------------");   
  Serial.print("  ");

  digitalWrite(LED_RX, HIGH);   // provo il led spia
  delay (1000);
  digitalWrite(LED_RX, LOW);
}

//************************************************
void loop()
{
   
    CHIEDI_DATI ();
}



//***************************************
void CHIEDI_DATI ()
{

   digitalWrite(LED_RX, LOW);
   currentmillis=millis();
   

    
    // se e' passato il tempo dell'intervallo
    if(currentmillis - prevmillis > intervallo) 
    { 

      prevmillis = currentmillis;
 
      switch (TipoDiComandoDaInviare)
      {
         case 1 :
         CHIEDI_DATI_QMOD() ;        
         TipoDiComandoDaInviare = 2;
         break;
         
         case 2 :
         CHIEDI_DATI_QPIGS() ;
         TipoDiComandoDaInviare = 1;      
         break;

         default:         
         // NIENTE
         break;
      }   
    } 

}


//---------------------------------------------- 
void CHIEDI_DATI_QMOD()
{
  
    Serial4.write(ComandoQMOD,sizeof(ComandoQMOD));  // invio il comando all'inverter
    delay (150);                                     // do il tempo di ricevere la risposta  
    
     Serial.println(" ");
     Serial.println(">> DATI_QMOD <<");
   
     // se arriva la risposta dalla seriale
     while (Serial4.available() > 0 )
     {
        // prendo un carattere alla volta  
        char recieved = Serial4.read();
        //... e lo aggiungo ad una stringa temporanea
        StringaTemp += recieved; 
        
        // se ricevo un CR, significa che l'invio dati e' terminato e si può leggere la linea arrivata
        if (recieved ==0x0D)         
        {
          Serial.println (" ");  
          Serial.print("Linea ricevuta : ");
          Serial.println (StringaTemp);
        }   
     }       
       
     delay (20); 
     VISUALIZZO_DATI_QMOD ();
     StringaTemp = "";
     TuttaLaStringa = "";
     Serial.println("-----------------------------------------------------------------------");     
}  


//***************************************************************
void VISUALIZZO_DATI_QMOD ()
{
   TuttaLaStringa = StringaTemp;
   DeviceMode = TuttaLaStringa.substring(1,2);       // estrraggo le info necessarie 
   
   Serial.println (" "); 
   Serial.println("Device Mode    "+ DeviceMode);

   if (DeviceMode == "B")
   {
      ModoInverter = "SOLARE";
   }  
   if (DeviceMode == "L")
   {
     ModoInverter = "ENEL";
   } 
   
   if (DeviceMode == "F")
   {
      ModoInverter = "FAULT";
   } 
   
   if (DeviceMode == "P")
   {
      ModoInverter = "POW ON";
   } 
   
   if (DeviceMode == "S")
   {
      ModoInverter = "STANDBY";
   }  
   
   if (DeviceMode == "H")
   {
      ModoInverter = "POW SAV";
   }    
   
   Serial.println("Modo inverter  "+ ModoInverter);
   
}


//---------------------------------------------- leggi dati
void CHIEDI_DATI_QPIGS()
{
  
    Serial4.write(ComandoQPIGS,sizeof(ComandoQPIGS));
    delay (150);
    
     Serial.println(" ");
     Serial.println(">> DATI_QPIGS <<");
   
     while (Serial4.available() > 0 )
     {
        char recieved = Serial4.read();
        StringaTemp += recieved; 
        if (recieved ==0x0D)
        {
          Serial.println (" ");  
          Serial.print("Linea ricevuta : ");
          Serial.println (StringaTemp);
        }   
     }       
       
     delay (20); 
     VISUALIZZO_DATI_QPIGS ();
     StringaTemp = "";
     TuttaLaStringa = "";
     Serial.println("-----------------------------------------------------------------------");     
}  


//***************************************************************
void VISUALIZZO_DATI_QPIGS ()
{

   TuttaLaStringa = StringaTemp;
   
   GridVoltage = TuttaLaStringa.substring(1,6); 
   GridFrequency = TuttaLaStringa.substring(7,11);
   AcOutputVoltage = TuttaLaStringa.substring(12,17);
   AcOutputFrequency = TuttaLaStringa.substring(18,22);
   AcOutputActivePower = TuttaLaStringa.substring(28,32);
   OutputLoadPercent =  TuttaLaStringa.substring(33,36);
   BatteryVoltage = TuttaLaStringa.substring(41,45);
   BatteryChargingCurrent = TuttaLaStringa.substring(47,50);
   BatteryCapacity = TuttaLaStringa.substring(51,54);
   b2ChargingStatus = TuttaLaStringa.substring(85,86);
  
   if (BatteryCapacity.toInt() < 100)
   {
     BatteryCapacity =  TuttaLaStringa.substring(52,54);
   }  

     Serial.println (" "); 
     Serial.print("GridVoltage               "); Serial.println(GridVoltage);      
     Serial.print("GridFrequency             "); Serial.println(GridFrequency);
     Serial.print("AcOutputVoltage           "); Serial.println(AcOutputVoltage);
     Serial.print("AcOutputFrequency         "); Serial.println(AcOutputFrequency);
     Serial.print("AcOutputActivePower       "); Serial.println(AcOutputActivePower);
     Serial.print("OutputLoadPercent         "); Serial.println(OutputLoadPercent);
     Serial.print("BatteryChargingCurrent    "); Serial.println(BatteryChargingCurrent);
     Serial.print("b2ChargingStatus          "); Serial.println(b2ChargingStatus);
     Serial.print("BatteryVoltage            "); Serial.println(BatteryVoltage);
     Serial.print("BatteryCapacity           "); Serial.println(BatteryCapacity);     

}


