Tengo un codigo que se ha relentizado mucho

Buenas, tengo un codigo que por extension y por calculos se ha relentizado mucho.
y creo que ahora no me lee lo suficientemente rapido la señal de la pinza de intensidad.
se podría usar otro arduino en modo exclavo para que me hiciera la lectura de la sonda y guardar los resultados para enviarlo al maestro y este escriba los resultados en la SD. y en la pantalla lcd sin que se demorase la lectura en el arduino "esclavo".
no soy programador y este programa lo he echo gracias a vuestra ayuda y a la de una persona que si tiene conocimientos.




//Programa creado el 11-4-2020

//// Librerias DEL PROGRAMA
#include <Wire.h>
#include <Adafruit_ADS1015.h>          // incluye libreria para el manejo del modulo señal de la sonda
#include <LiquidCrystal_I2C.h>
#include <RTClib.h>                    // incluye libreria para el manejo del modulo RTC
#include <SD.h>                        // libreria para la tarjeta SD


//===========asignar objetos y sus direcciones para el I2C
LiquidCrystal_I2C lcd(0x27, 16, 2); 
Adafruit_ADS1115 ads(0x48);
RTC_DS3231 rtc;                       // crea objeto del tipo RTC_DS3231 y le da su direccion


/* CONSTANTE DE LA APLICACION */
#define CANTMUESTRAS 2000 // muestras a tomar ( mas muestras mas exactidud pero mas tiempo de ejecucion)
#define AMAXSENS 50       // corriente maxima del sensor en este caso es el SCT013 que ofrece 50A max a 1000 mV
#define MVMAXSENS 1000    // Mv maximos que ofrece el sensor en su corriente maxima soportada CUANDO ESTE TERMINADO TIENE QUE PONERSE 1000
#define VOLTRED 230       // tension de la red

#define NUMERO_TRAMOS_HORARIOS 6     // NUMEROS DE TRAMOS HORARIOS EN 2020 VARIARAN APARTIR DEL 2021
#define HORARIO_VALLE          0      //00:00--08:00  VALLE 
#define HORARIO_LLANO          1      //08:00--11:00  LLANO  
#define HORARIO_PUNTA          2      //11:00--15:00  PUNTA 
#define HORARIO_LLANO2         3      //15:00--19:00  LLANO
#define HORARIO_PUNTA2         4      //19:00--23:00  PUNTA
#define HORARIO_LLANO3         5      //23:00--00:00  LLANO

#define CONTADOR_VALLE  0
#define CONTADOR_PUNTA  1
#define CONTADOR_LLANO  2

#define TRAMO_HORAS 0
#define TRAMO_MINUTOS 1
/*Variable si es festivo o no*/
bool Festivo = false;

/* AJUSTAR VALOR SEGÚN CONTADOR COMPAÑIA */
float CONTADOR_PUNTA_Segun_lectura = 4110;
float CONTADOR_LLANO_Segun_lectura= 1881;
float CONTADOR_VALLE_Segun_lectura = 79;
bool   LecturaContador_Actual = 0;
int MesContrato = 8;           //Fechas contrato mes
int diaContrato = 27;          //Fechas contrato dia
float contadorPotenciaConsumidaYearAnterior = 3558; //este valor se actualiza al finalizar el año de contrato a las 23:59:59
//============ CONTROL CONTADORES==============
long contadorPotenciaTotal_Anterior;        
long contadores_HORARIO_PUNTA_Anterior;    
long contadores_HORARIO_LLANO_Anterior ;    
long contadores_HORARIO_VALLE_Anterior  ;   
long contadorPotenciaConsumidaYear_Anterior;

long contadorPotenciaTotal_Actual;        
long contadores_HORARIO_PUNTA_Actual;    
long contadores_HORARIO_LLANO_Actual ;    
long contadores_HORARIO_VALLE_Actual  ;   
long contadorPotenciaConsumidaYear_Actual;

// VARIABLES

// ==========variables calculo
float Peficaz;
float Int_calculada;
float med_Ieficaz;
float energiaConsumida;
float LCDPeficaz; //AÑADIDO EDU variable entera para poder representar el valor en la lcd Y EN WATIOS

//==========Para el control de tiempos MILLIS

//long milisec = millis(); // calcualar el timepo en milisegundos
long time = 0; //conversión de milisegundos a segundos

DateTime tInicio; // momento en el que se inicia el sistema
DateTime tActual; // momento actual
DateTime tAnterior; //momento anterior
DateTime tramoFin;

//==============  apertura del archivo y su grabacion en la SD
File LecturaContadores;
unsigned long tiempoAhora0=0;
unsigned long tiempoPasado0=0;
const unsigned long tiempoespera = 1000;
bool permitir_escritura = false;
bool inicilizarSD_if_tarjeta= false;
const int pinTarjeta=53;


// VARIABLES VISUALIZACION LCD
//DateTime UltimaVisualizacion; //para poder limpiar la LCD 
long TiempoDeVisualizacion = 50;//tiempo que quiero que se vea cada mensaje
int MensajeLCD =0;// para utilizarlo en el swicht de mensajes lcd



//==============VARIABLES PARA EL CAMBIO DE HORA 
long tTranscurrido; // tiempo transcurrido en  esta lectura en segundos
int tramoHorario[2][NUMERO_TRAMOS_HORARIOS]; 
//t_tramoHorario tramoHorario_t[NUMERO_TRAMOS_HORARIOS];
float horasTranscurridas;
bool horaRetrasada = false;
bool desactivacionContador = false;
//===========VARIABLES FESTIVO 
int DiaSemana = tActual.dayOfTheWeek();
  int MesAnyo = tActual.month();


//=========== VARIABLES CAMBIO DE TARIFICACIÓN ========
int contadorActual;
int tramoHorarioActualCorregido;
DateTime inicioVerano(tActual.year(),03,28,02,00);  // fecha del inicio del horario de verano SEGURAMENTE CAMBIAR MANUALMENTE
DateTime inicioInvierno(tActual.year(),10,28,02,00); // fecha del inicio del horario de invierno SEGURAMENTE CAMBIAR MANUALMENTE

 //===============VARIABLES ACOMULADORES ENERGIA
float contadorPotenciaTotal=0;                   //este es el valor desde que se activo el contador

float contadorPotenciaConsumidaYear = 0;         // lo consumido en el año
DateTime tramosHorarios[NUMERO_TRAMOS_HORARIOS];
float contadores[NUMERO_TRAMOS_HORARIOS];  //############## habra tantos contadores como tramos de horarios

//===========Variables de control
bool initok = false; //Ok si todos los modulos se inicializan correctamente


// =========== COMIENZA EL VOID SETUP
void setup() {
     Serial.begin(9600); // inicializo las comunicaciónes
    
   
     
    
     inicializarLCD();
     inicializarADS(); //Modulo para conexion de la sonda 
     initok = inicializarReloj();

     tInicio = rtc.now(); // guardamos el momento de encendido
     tActual = rtc.now(); // guardamos el momento actual inicial
     tTranscurrido = 0 ;
      for (int i=0; i< 3; i++){
       contadores[i]=0;
       }
     // valle 00-8  llano 8-11_15-19_23-00  punta 11-15_19-23
     tramoHorario[TRAMO_HORAS][HORARIO_VALLE]=  00;  tramoHorario[TRAMO_MINUTOS][HORARIO_VALLE]=  00;
     tramoHorario[TRAMO_HORAS][HORARIO_LLANO]=   8;  tramoHorario[TRAMO_MINUTOS][HORARIO_LLANO]=  00;
     tramoHorario[TRAMO_HORAS][HORARIO_PUNTA]=  11;  tramoHorario[TRAMO_MINUTOS][HORARIO_PUNTA]=  00;
     tramoHorario[TRAMO_HORAS][HORARIO_LLANO2]= 15;  tramoHorario[TRAMO_MINUTOS][HORARIO_LLANO2]= 00;
     tramoHorario[TRAMO_HORAS][HORARIO_PUNTA2]= 19;  tramoHorario[TRAMO_MINUTOS][HORARIO_PUNTA2]= 00;
     tramoHorario[TRAMO_HORAS][HORARIO_LLANO3]= 23;  tramoHorario[TRAMO_MINUTOS][HORARIO_LLANO3]= 00;
//inicializar_Tarjeta_SD();
 Serial.print("Iniciando SD ...");
       if (!SD.begin(pinTarjeta)) {
         Serial.println("No se pudo inicializar");
         return;
         }
     Serial.println("inicializacion exitosa");
  
      if(!SD.exists("datalog.txt"))
       {
       LecturaContadores = SD.open("datalog.txt", FILE_WRITE);
          if (LecturaContadores) {
              LecturaContadores.println("contadorPotenciaTotal, Contador PUNTA, Contador LLANO, Contador Valle, Contador Year anterior, ");
              Serial.println("Archivo nuevo, Escribiendo encabezado(fila 1)");
                delay(100);
                 LecturaContadores.close();
                 inicilizarSD_if_tarjeta == false;
                  } else {
                    Serial.println("Error creando el archivo datalog.txt");
       }}
}



/*void inicializar_Tarjeta_SD(){
       Serial.print("Iniciando SD ...");
       if (!SD.begin(pinTarjeta)) {
         Serial.println("No se pudo inicializar");
         return;
         }
     Serial.println("inicializacion exitosa");
  
      if(!SD.exists("datalog.txt"))
       {
       LecturaContadores = SD.open("datalog.txt", FILE_WRITE);
          if (LecturaContadores) {
              LecturaContadores.println("contadorPotenciaTotal, Contador PUNTA, Contador LLANO, Contador Valle, Contador Year anterior, ");
              Serial.println("Archivo nuevo, Escribiendo encabezado(fila 1)");
                
                 LecturaContadores.close();
                 inicilizarSD_if_tarjeta == false;
                  } else {
                    Serial.println("Error creando el archivo datalog.txt");
       }}
}*/

void inicializarADS() {
   ads.setGain(GAIN_TWO); // es una ganancia de la libreria 2x gain +/- 2.048V  1 bit = 0.0625mV
   ads.begin();
}

void inicializarLCD(){
  lcd.begin(16,2); //lcd.begin(16,2);
  lcd.init(); //inicializa lcd                   //PODER INICAR LA PANTALLA, SALIAN CARACTERES RAROS
  lcd.backlight();
  
}

bool inicializarReloj(){
    
   return rtc.begin();
 rtc.adjust(DateTime(__DATE__,__TIME__));    //AÑADIDO PARA AJUSTAR HORA 1 VEZ
    
}

void inicializarVariables(){
  
  
}

void actualizarTiempos(){

    tAnterior = tActual; // tiempo actual del barrido anterior del loop
    tActual = rtc.now(); // tiempo actual en cada barrido del loop
    tTranscurrido = ( tActual.secondstime()- tAnterior.secondstime()); 
 }

void actualizaHorario() //Cambiar hora verano-invierno Adelanta la hora a partir del dia 25 de Marzo, busca el primer domingo y cuando se han las 2 de la noche adelanta el reloj una hora
     {
      uint16_t hour = tActual.hour();
      uint16_t minute = tActual.minute();
      uint16_t second = tActual.second(); 
      uint16_t year= tActual.year(); 
      uint16_t month = tActual.month();
      uint16_t day = tActual.day();

           
      // if ((month == 3) && (day ==30) &&(hour==2)&& (year==2021))
      if ((month == 3) && (day ==30) &&(hour==2))
       {
        desactivacionContador = true;// esta variable hay que activarla cada vez que hace una medicion
         hour = 3;
         rtc.adjust(DateTime(year, month, day, hour, minute, second));
       }
    //Retrasa la hora a partir del dia 25 de Octubre, busca el primer domingo
    //y cuando se han las 2 de la noche retrasa el reloj una hora
    
   // if ((month ==10) && (day >= 26) && (year=2021) && (hour==3) && !horaRetrasada )   
   if ((month ==10) && (day >= 26) && (hour==3) && !horaRetrasada )
     {
      desactivacionContador = true;// esta variable hay que activarla cada vez que hace una medicion
      hour = 2;
      horaRetrasada=true;
      rtc.adjust(DateTime(year, month, day, hour, minute, second));
     }
    if (hour==4)    
    {
      horaRetrasada=false;
    }   
}


void AsignamosValorContadores(){
 contadores[HORARIO_PUNTA] = CONTADOR_PUNTA_Segun_lectura;
 contadores[HORARIO_LLANO] = CONTADOR_LLANO_Segun_lectura;
 contadores[HORARIO_VALLE] = CONTADOR_VALLE_Segun_lectura;
 contadorPotenciaTotal = contadores[2] + contadores[ 1] + contadores[3];
 contadorPotenciaConsumidaYear=contadorPotenciaTotal-contadorPotenciaConsumidaYearAnterior;

 }

void PotenciaConsumidaYearAnterior(){
  if ( (MesContrato == tActual.month()) && (diaContrato == tActual.day()) && (23 == tActual.hour()) && (59 == tActual.minute()) && (59 == tActual.second()))
  {
  contadorPotenciaConsumidaYearAnterior=contadorPotenciaTotal;
  }
}


void  actualizamosContadores(){
     horasTranscurridas= (float)tTranscurrido/3600;//tTranscurrido/3600;
     energiaConsumida = Peficaz* horasTranscurridas; //energia expresada en kW hora
     contadores[contadorActual] += energiaConsumida ;  //actualizados los contadores y asignamos el cociente y los convertimos en "entero"
     contadorPotenciaTotal += energiaConsumida; //carga el valor total en w minutos de todos los tramos
      LCDPeficaz = Peficaz*1000; //conversion de float a entero para poder representar los valores
}

/*===========FESTIVOS EN ESPAÑA===================
1 de enero (viernes): Año Nuevo
2 de abril: Viernes Santo
1 de mayo (sábado): Fiesta del Trabajo
12 de octubre (martes): Fiesta Nacional de España
1 de noviembre (lunes): Día de Todos los Santos
6 de diciembre (lunes): Día de la Constitución
8 de diciembre (miércoles): Inmaculada Concepción
25 de diciembre (sábado): Navidad
*/
void comprobarSiEsFestivo_FinDe(){
  
  if ((DiaSemana==6)||(DiaSemana==7)){
   // Serial.println("FESTIVO, Fin de semana");
    Festivo = true;
    }
    else if( MesAnyo== 1 && DiaSemana == 1)
  {
      // Serial.println("FESTIVO, Año Nuevo");
       Festivo= true;
       }
  else if( MesAnyo== 4 && DiaSemana == 2)
  {
      // Serial.println("FESTIVO, Viernes Santo");
       Festivo= true;
       }
 else if( MesAnyo== 5 && DiaSemana == 1)
  {
      // Serial.println("FESTIVO, Fiesta del Trabajo");
       Festivo= true;
       }
        else if( MesAnyo== 10 && DiaSemana == 12)
  {
      // Serial.println("FESTIVO, Fiesta Nacional de España");
       Festivo= true;
       }
        else if( MesAnyo== 11 && DiaSemana == 1)
  {
      // Serial.println("FESTIVO, Día de Todos los Santos ");
       Festivo= true;
       }
        else if( MesAnyo== 12 && DiaSemana == 6)
  {
       //Serial.println("FESTIVO, Día de la Constitución");
       Festivo= true;
       }
        else if( MesAnyo== 12 && DiaSemana == 8)  //PARA COMPROBAR ES EL 12 Y EL 8
  {
      // Serial.println("FESTIVO, Inmaculada Concepción");
       Festivo= true;
       }
        else if( MesAnyo== 12 && DiaSemana == 25)
  {
      // Serial.println("FESTIVO, Navidad");
       Festivo= true;
       }
       
       else{
       // Serial.println("LABORAL");
        Festivo= false;
       }
      
}


void comprobarTramoTarificacion(){
      uint8_t hour = tActual.hour();
      uint8_t minute = tActual.minute();
      uint8_t second = tActual.second(); 
      uint16_t year= tActual.year(); 
      uint8_t month = tActual.month();
      uint8_t day = tActual.day();
      DateTime tramoFin;
      DateTime tramoInicio;
      if (Festivo== true){
       
        tramoHorarioActualCorregido = 0;
      }
      else{
      for (int i=0; i < NUMERO_TRAMOS_HORARIOS; i++) {
        DateTime tramoTmp1(tActual.year(),tActual.month(),tActual.day(),tramoHorario[TRAMO_HORAS][i],tramoHorario[TRAMO_MINUTOS][i]);
        tramoInicio = tramoTmp1;
        if ( i ==  NUMERO_TRAMOS_HORARIOS-1) {
                  DateTime tramoTmp(tActual.year(),tActual.month(),(tActual.day()+1), tramoHorario[TRAMO_HORAS][HORARIO_VALLE],tramoHorario[TRAMO_MINUTOS][HORARIO_VALLE] ); // LA HORA FIN SERA IGUAL A LA HORA DIURNA DEL DIA SIGUIENTE
          tramoFin = tramoTmp;
        } else {
          DateTime  tramoTmp(tActual.year(),tActual.month(),tActual.day(),tramoHorario[TRAMO_HORAS][i+1],tramoHorario[TRAMO_MINUTOS][i+1]);
          tramoFin = tramoTmp;
          }    
        if (tActual >= tramoInicio && tActual< tramoFin) {
            tramoHorarioActualCorregido = i;
        }
      }}
      switch (tramoHorarioActualCorregido) {
             case 2:   
                        contadorActual=CONTADOR_PUNTA;
                                    break;
             case 4:
                        contadorActual=CONTADOR_PUNTA;
                                    break;
             case 1:
                        contadorActual=CONTADOR_LLANO;
                                    break;
             case 3:
                        contadorActual=CONTADOR_LLANO;
                                    break;
             case 5:
                        contadorActual=CONTADOR_LLANO;
                                    break;
             case 0:
                        contadorActual=CONTADOR_VALLE;
                                    
                                    break;
                                    }
}
/*                                                                          contadorActualCorregido
 * NºARRAY              HORARIO DE LOS TRAMOS                                ASIGNACION CONTADOR 
    0     ||       tramoHorario[TRAMO_HORAS][HORARIO_VALLE]=00; ||  3 contador VALLE
    1     ||       tramoHorario[TRAMO_HORAS][HORARIO_LLANO]= 08;     ||  2 contador LLANO
    2     ||       tramoHorario[TRAMO_HORAS][HORARIO_PUNTA]= 10;       ||  1 contador PUNTA
    3     ||       tramoHorario[TRAMO_HORAS][HORARIO_LLANO2]= 14;    ||  2 contador LLANO
    4     ||       tramoHorario[TRAMO_HORAS][HORARIO_PUNTA2]= 18;      ||  1 contador PUNTA
    5     ||       tramoHorario[TRAMO_HORAS][HORARIO_LLANO3]= 22;    ||  2 contador LLANO
    
 */

void medicionActual(){
                                 // funcion de medicion
  /* basado en la siguiente teoria de onda:
    Al valor eficaz los norteamericanos le llaman valor RMS
    como abreviatura de Root Mean Square , ya que el mismo está matemáticamente relacionado con la curva senoidal,
    extrayendo la raíz cuadrada de la suma de sus infinitos valores instantáneos, elevados al cuadrado.
    como no podemos medir infinitos valores realizamos una cantidad de mediciones y
    aplicamos un factor de correccion basado en mediciones reales con amperimetro*/
 
  
  long tiempoinicio = millis();                       // para medir cuanto tarda en realizar las mediciones
   int16_t bitsads;
  float mVporbit = 0.0625F;
  float Ieficaz;
  float Iinstant;
  float mVinstant;
  float sumIinstant=0;

  for (int i = 0; i < CANTMUESTRAS; i++) {
    bitsads = ads.readADC_Differential_0_1();
    mVinstant = bitsads * mVporbit;
    Iinstant = mVinstant * AMAXSENS / MVMAXSENS;   // regla de tres en base al sensor conectado ya que el sensor ofrece tension y la pasamos directemante proporcional a intensidad
    sumIinstant += sq(Iinstant);                   // suma de cuadrados
  }
  med_Ieficaz = sqrt(sumIinstant / CANTMUESTRAS);        // raiz cuadrada de la suma de cuadrados dividida por el numero de muestras
  Int_calculada = med_Ieficaz * 1.36; // se multiplica por un valor de correccion basado en mediciones reales = Amperios
  Peficaz = (Int_calculada * VOLTRED)/1000;  //P=(V*I*)=KW
} 

void HayVariacionesEnContadores_preparaSD(){
 contadorPotenciaTotal_Actual         = (contadorPotenciaTotal/=1);
 contadores_HORARIO_PUNTA_Actual      = (contadores[HORARIO_PUNTA]/=1);
 contadores_HORARIO_LLANO_Actual      = (contadores[HORARIO_LLANO]/=1);
 contadores_HORARIO_VALLE_Actual      = (contadores[HORARIO_VALLE]/=1);

  
permitir_escritura = false;
 if ( contadorPotenciaTotal_Anterior < contadorPotenciaTotal_Actual ||contadores_HORARIO_PUNTA_Anterior < contadores_HORARIO_PUNTA_Actual || contadores_HORARIO_LLANO_Anterior < contadores_HORARIO_LLANO_Actual || contadores_HORARIO_VALLE_Anterior <  contadores_HORARIO_VALLE_Actual || contadorPotenciaConsumidaYear_Anterior < contadorPotenciaConsumidaYear_Actual)
 {// si son iguales nos vamos y no escribimos.
 contadorPotenciaTotal_Anterior         = (contadorPotenciaTotal/=1);
 contadores_HORARIO_PUNTA_Anterior      = (contadores[HORARIO_PUNTA]/=1);
 contadores_HORARIO_LLANO_Anterior      = (contadores[HORARIO_LLANO]/=1);
 contadores_HORARIO_VALLE_Anterior      = (contadores[HORARIO_VALLE]/=1);
 contadorPotenciaConsumidaYear_Anterior = (contadorPotenciaConsumidaYear /=1);
 permitir_escritura = true;
}else{
 
}
  }


void Abrir_Archivo_escribe()
     {
       LecturaContadores = SD.open("datalog.txt", FILE_WRITE);//abrimos  el archivo
  
       if (LecturaContadores) {                    
          LecturaContadores.print(contadorPotenciaTotal_Actual);
         LecturaContadores.print(",");
          LecturaContadores.print(contadores_HORARIO_PUNTA_Actual);
         LecturaContadores.print(", ");
          LecturaContadores.print(contadores_HORARIO_LLANO_Actual);
         LecturaContadores.print(",");
          LecturaContadores.print(contadores_HORARIO_VALLE_Actual);
         LecturaContadores.print(",");
          LecturaContadores.print(contadorPotenciaConsumidaYear_Anterior); 
     LecturaContadores.print(",");
      LecturaContadores.println((millis()/1000)); 
      
        LecturaContadores.close(); //cerramos el archivo
       
       }
       permitir_escritura = false;
       }

void   actualizamosLCD(){
  lcd.init();
   

  //===PROBAMOS MENAJES ALTERNATIVOS
int NumerosMensajes = 5;  
long tiempo1aVisualizacion = millis();
long tiempoAnteriorVisualizacion;
if( (tiempo1aVisualizacion-tiempoAnteriorVisualizacion)>TiempoDeVisualizacion){
     tiempoAnteriorVisualizacion = tiempo1aVisualizacion;
     MensajeLCD++;
      if (MensajeLCD>NumerosMensajes)
        {
           MensajeLCD=0;
         }
}
switch(MensajeLCD){
 
      case 0:
lcd.clear();
lcd.setCursor(0,0);    lcd.print(contadorPotenciaTotal,0);         lcd.print(" kwh");
lcd.setCursor(1,1);    lcd.print("Potencia Total");
break;
      case 1:
lcd.clear();
lcd.setCursor(0,0);    lcd.print(LCDPeficaz);         lcd.print(" w");
lcd.setCursor(0,1);    lcd.print("Potencia Eficaz");
break;
      case 2:
lcd.clear();
lcd.setCursor(0,0);    lcd.print(contadores[HORARIO_PUNTA],0);         lcd.print(" kwh");
lcd.setCursor(3,1);    lcd.print("Hora PUNTA");
break;
      case 3:
lcd.clear();
lcd.setCursor(0,0);    lcd.print(contadores[HORARIO_LLANO],0);         lcd.print(" kwh");
lcd.setCursor(3,1);    lcd.print("Hora LLANA");
break;
      case 4:
lcd.clear();
lcd.setCursor(0,0);    lcd.print(contadores[0],0);         lcd.print(" kwh");
lcd.setCursor(3,1);    lcd.print("Hora VALLE");
break;
      case 5:
lcd.clear();
lcd.setCursor(0,0);    lcd.print(contadorPotenciaConsumidaYear,0);         lcd.print(" kwh");
lcd.setCursor(0,1);    lcd.print("Pot. Cons. Any");
break;      
}
  
}
void printDateTime(DateTime &hora,char mensaje[])
{
      Serial.print("Hora: ");
  Serial.print(hora.hour());
  Serial.print(":");
  Serial.print(hora.minute());
  Serial.print(":");
  Serial.print(hora.second());
  Serial.print("--");
  Serial.print(hora.day());
  Serial.print(":");
  Serial.print(hora.month());
  Serial.print(":");
  Serial.print(hora.year());
  Serial.println(mensaje);
}
void actualizamosSerial(){
Serial.print(energiaConsumida,5);
     Serial.println("kwh energiaConsumida,");
Serial.print(LCDPeficaz); // para ver si lee la potencia eficaz en watios
     Serial.println("w  actuales,");
Serial.print(contadorPotenciaTotal,5);
     Serial.println(" kwh Potencia Total,");
Serial.print(contadores[CONTADOR_PUNTA],5);
     Serial.println(" kwh Hora Punta,");
Serial.print(contadores[CONTADOR_LLANO],5);
    Serial.println(" kwh Hora Llana,");
Serial.print(contadores[CONTADOR_VALLE],5);
    Serial.println(" kwh Hora Valle,");
Serial.print(Int_calculada);
     Serial.println(" A calculada,");
Serial.print(tTranscurrido);
      Serial.println(" tTranscurrido,");
 Serial.print(tActual.secondstime(), DEC);
      Serial.println(" TActual,");
Serial.print(tAnterior.secondstime());
      Serial.println(" TAnterior,");
 Serial.print(horasTranscurridas);
      Serial.println(" horasTranscurridas,");
 Serial.print( contadorActual);
 Serial.print("  contadorActual,");
     Serial.println(" 1 Punta, 2 llano, 0  valle");
 Serial.print(tramoHorarioActualCorregido);
         Serial.println(" tramoHorarioActualCorregido");
         Serial.print(contadores[HORARIO_PUNTA]);
         Serial.println("contadores[HORARIO_PUNTA]");
         Serial.print(contadores[HORARIO_LLANO]);
         Serial.println("contadores[HORARIO_LLANO]");
         Serial.print(contadores[HORARIO_VALLE]);
         Serial.println("contadores[HORARIO_VALLE]");

       Serial.print("Festivo ,");
    Serial.println(Festivo);
        Serial.print("DiaSemana ,");
    Serial.println(DiaSemana);
       Serial.print(NUMERO_TRAMOS_HORARIOS);
  Serial.println("  NUMERO_TRAMOS_HORARIOS");
      Serial.print("Hora: ");
printDateTime (tramoFin,"  tramoFin,");
   
Serial.print("Hora: ");
printDateTime (tActual,"  tiempo Actual,");
   
Serial.println("=====================Fin Escritura==============");

  
}
void loop() {
     if(!initok) {
         lcd.clear();
         lcd.print("Fallo el Init");
         Serial.println("Fallo el Init");
         return;     }
     medicionActual();   // calculados los Kw eficaces en este instante
     actualizarTiempos();
     actualizaHorario();
     comprobarSiEsFestivo_FinDe();
    if (Festivo==0){comprobarTramoTarificacion();}
    if ( LecturaContador_Actual==0)   { AsignamosValorContadores();  LecturaContador_Actual=true; }
 
     actualizamosContadores();
     PotenciaConsumidaYearAnterior();
     actualizamosLCD();
     actualizamosSerial();
     HayVariacionesEnContadores_preparaSD();
     if (permitir_escritura== true){ Abrir_Archivo_escribe();}
}

Por ultimo, este codigo en arduino nano o uno, es demasido extenso, Pero viendo por ejemplo un codigo como el Marlin (programa para la impresoras 3d) que es super extenso, como es posible que entre dicho codigo?.
El utilizar diferentes "archivos"(no estoy seguro que sea ese el nombre, son las pestañas que contiene como si fueran diferentes scketch dentro del mismo) en scketch hace que el programa sea mas "ligero"?

Tu problema esta aquí

  for (int i = 0; i < CANTMUESTRAS; i++) {
      bitsads = ads.readADC_Differential_0_1();
      mVinstant = bitsads * mVporbit;
      Iinstant = mVinstant * AMAXSENS / MVMAXSENS;   // regla de tres en base al sensor conectado ya que el sensor ofrece tension y la pasamos directemante proporcional a intensidad
      sumIinstant += sq(Iinstant);                   // suma de cuadrados
  }

Toma el tiempo usando milllis() y verás de que te hablo.
Debes hacerlo de manera que no sea bloqueante, ahora eso actua como un delay.

Ok miro de solucionarlo supongo que con un if se puede enmendar.

Aunque la sd no ayuda en el retraso?

No lo entiendes o al menos no comprendes lo que te he dicho.
Te he pedido que pongas un contador de tiempo antes y despues de ese for() para que veas cuantos milisegundos insume.

 unsigned long midoTiempoAds = milllis();
 for (int i = 0; i < CANTMUESTRAS; i++) {
      bitsads = ads.readADC_Differential_0_1();
      mVinstant = bitsads * mVporbit;
      Iinstant = mVinstant * AMAXSENS / MVMAXSENS;   // regla de tres en base al sensor conectado ya que el sensor ofrece tension y la pasamos directemante proporcional a intensidad
      sumIinstant += sq(Iinstant);                   // suma de cuadrados
  }
Serial.print(millis() -midoTiempoAds);
Serial.println(" mseg");

Justamente esto.

Ahora bien, lo que yo te propongo es usar una rutina tal que trabaje de manera no bloqueante. No has entendido que significa eso.
Cuando un código encuentra un for(0 ... >2000) como en tu caso, se detiene ahi durante el lapso que eso significa o sea se BLOQUEA.
Hacer algo no bloqueante es llevarlo adelante de manera que eso se minimice, cómo entonces?
Existe una técnica en la que se retira un término de la serie (llamo serie a todos los números que tienes acumulados, tus 2000) y se suma uno nuevo.
En tu caso, que pasaría si en cada ciclo retiramos el primer número de la serie y agregamos el nuevo? pues que tardaríamos solo 1 tiempo del ADS y no 2000 mas todas las cuentas involucradas. Es una mejora de casi 2000 a 1 o algo mas.
Bien.. cómo se hace.
Bueno la idea es que llevas un contador y al principio los 2000 primeros loops se irá acumulando valores hasta llegar al loop 2000 y de ahi en mas ya solo trabaja como en tu caso. Podrías incluso hacerlo en el setup y entonces ni cuenta te darás.

Esa es una mirada y la otra es usar cosas que estan hechas.
La mejor es EmonLib

Y la otra es que hagas lo que te he dicho usando un timer asi que comprometes el micro. Claro que se que no es fácil, pero para eso tienes a Emonlib. Pruebala te hace todo lo que quieres calculas y no pierde tiempo.

La verdad Surbyte, es que no me entero mucho. Lo que para vosotros es mirar el Código y decir pues mira esto o lo otro, que os puede llevar 15 minutos, para mi supone 2 o 3 días buscando ejemplos y tutoriales para poder arañar la superfice de lo que me comentas.
Pero os agradezco el esfuerzo y la ayuda, es la única forma de poder aprender.

EmonLib veo que es una librería, buscaré todo lo que pueda para entender que hace y como funciona.
Gracias me pongo a ello.

pues de momento veo que la libreria Emonlib, no admite el i2c que es donde tengo conectado el ADS1115 que es donde tengo la pinza stc. por lo que tendré o que prescindir de la ADS1115 o haber si encuentro alguien que me explique como se puede usar el ADS1115.

Haber surbyte, este sería el codigo que me propones?

//=================================ANTES DEL SETUP
#define CANTMUESTRAS 2000 // muestras a tomar ( mas muestras mas exactidud pero mas tiempo de ejecucion)
#define AMAXSENS 50       // corriente maxima del sensor en este caso es el SCT013 que ofrece 50A max a 1000 mV
#define MVMAXSENS 1000    // Mv maximos que ofrece el sensor en su corriente maxima soportada CUANDO ESTE TERMINADO TIENE QUE PONERSE 1000
#define VOLTRED 230       // tension de la red

long ContadorMuestreo = 0 ; //declarado al principio del programa.
float sumIinstant=0;        //declarado al principio del programa.
//=================================DESPUES DEL SETUP 
void medicionActual(){
                                 // funcion de medicion
  /* basado en la siguiente teoria de onda:
    Al valor eficaz los norteamericanos le llaman valor RMS    como abreviatura de Root Mean Square , ya que el mismo está matemáticamente relacionado con la curva senoidal,    extrayendo la raíz cuadrada de la suma de sus infinitos valores instantáneos, elevados al cuadrado.    como no podemos medir infinitos valores realizamos una cantidad de mediciones y    aplicamos un factor de correccion basado en mediciones reales con amperimetro*/

   long tiempoinicio = millis();                       // para medir cuanto tarda en realizar las mediciones
   int16_t bitsads;
  float mVporbit = 0.0625F;
  float Ieficaz;
  float Iinstant;
  float mVinstant;

 if ( ContadorMuestreo < CANTMUESTRAS){
  bitsads = ads.readADC_Differential_0_1();
    mVinstant = bitsads * mVporbit;
    Iinstant = mVinstant * AMAXSENS / MVMAXSENS;   // regla de tres en base al sensor conectado ya que el sensor ofrece tension y la pasamos directemante proporcional a intensidad
    sumIinstant += sq(Iinstant);                   // suma de cuadrados
ContadorMuestreo++;
}else {
  med_Ieficaz = sqrt(sumIinstant / CANTMUESTRAS);        // raiz cuadrada de la suma de cuadrados dividida por el numero de muestras
  Int_calculada = med_Ieficaz * 1.36; // se multiplica por un valor de correccion basado en mediciones reales = Amperios
  Peficaz = (Int_calculada * VOLTRED)/1000;  //P=(V*I*)=KW
ContadorMuestreo=0;
}
  

} 

el trozo original lo vuelvo a poner para que se vea mejor la comparación.
haber si me puedes decir como lo ves. :+1:

//=================================ANTES DEL SETUP
#define CANTMUESTRAS 2000 // muestras a tomar ( mas muestras mas exactidud pero mas tiempo de ejecucion)
#define AMAXSENS 50       // corriente maxima del sensor en este caso es el SCT013 que ofrece 50A max a 1000 mV
#define MVMAXSENS 1000    // Mv maximos que ofrece el sensor en su corriente maxima soportada CUANDO ESTE TERMINADO TIENE QUE PONERSE 1000
#define VOLTRED 230       // tension de la red

long ContadorMuestreo = 0 ; //declarado al principio del programa.
float sumIinstant=0;        //declarado al principio del programa.
//=================================DESPUES DEL SETUP //=================================ANTES DEL SETUP
#define CANTMUESTRAS 2000 // muestras a tomar ( mas muestras mas exactidud pero mas tiempo de ejecucion)
#define AMAXSENS 50       // corriente maxima del sensor en este caso es el SCT013 que ofrece 50A max a 1000 mV
#define MVMAXSENS 1000    // Mv maximos que ofrece el sensor en su corriente maxima soportada CUANDO ESTE TERMINADO TIENE QUE PONERSE 1000
#define VOLTRED 230       // tension de la red

long ContadorMuestreo = 0 ; //declarado al principio del programa.
float sumIinstant=0;        //declarado al principio del programa.
//=================================DESPUES DEL SETUP 

void medicionActual(){
                                 // funcion de medicion
  /* basado en la siguiente teoria de onda:
    Al valor eficaz los norteamericanos le llaman valor RMS
    como abreviatura de Root Mean Square , ya que el mismo está matemáticamente relacionado con la curva senoidal,
    extrayendo la raíz cuadrada de la suma de sus infinitos valores instantáneos, elevados al cuadrado.
    como no podemos medir infinitos valores realizamos una cantidad de mediciones y
    aplicamos un factor de correccion basado en mediciones reales con amperimetro*/
 
  
  long tiempoinicio = millis();                       // para medir cuanto tarda en realizar las mediciones
   int16_t bitsads;
  float mVporbit = 0.0625F;
  float Ieficaz;
  float Iinstant;
  float mVinstant;
  float sumIinstant=0;
//================================================================
  for (int i = 0; i < CANTMUESTRAS; i++) {
    bitsads = ads.readADC_Differential_0_1();
    mVinstant = bitsads * mVporbit;
    Iinstant = mVinstant * AMAXSENS / MVMAXSENS;   // regla de tres en base al sensor conectado ya que el sensor ofrece tension y la pasamos directemante proporcional a intensidad
    sumIinstant += sq(Iinstant);                   // suma de cuadrados
  }
  //============================================================0
  med_Ieficaz = sqrt(sumIinstant / CANTMUESTRAS);        // raiz cuadrada de la suma de cuadrados dividida por el numero de muestras
  Int_calculada = med_Ieficaz * 1.36; // se multiplica por un valor de correccion basado en mediciones reales = Amperios
  Peficaz = (Int_calculada * VOLTRED)/1000;  //P=(V*I*)=KW
} 

No digo que sea fácil, te has metido en un tema complicado que por supuesto se puede resolver pero requiere atención como todo.
Permíteme un tiempo y veré de darte una respuesta.

Por supuesto Subryte, cuando te sea posible, faltaría más.
Creo que de esta manera resuelvo el tema del retraso por la acumulación de muestreo, pero necesito que un experto me de su punto de vista.

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.