Amperometro con arduino

Ciao a tutti,
ho trovato il seguente codice su openenergy:

#include "EmonLib.h"                   // Include Emon Library
EnergyMonitor emon1;                   // Create an instance
EnergyMonitor emon2;                   // Create an instance


void setup()
{  
  Serial.begin(9600);
  
  emon1.current(3, 111.1);             // Current: A3 input pin, calibration.
    emon2.current(4, 111.1);             // Current: A4 input pin, calibration.

}

void loop()
{
    double Irms1 = emon1.calcIrms(1480);  // Calculate Irms only
    double Irms2 = emon2.calcIrms(1480);  // Calculate Irms only

  
  Serial.print("Potenza Generata dal FV Kw: ");
  Serial.println(Irms1);		       // Irms
  
  Serial.print("Potenza Consumata in Casa Kw: ");
  Serial.println(Irms2);		       // Irms
}

funziona perfettamente, ma se inserito in un altro codice che ho già in funzione su arduino, mi rallenta tutto il processo.
Qualcuno mi sa spiegarne il motivo? Dipende dalla libreria? E' possibile velocizzarlo?
Più o meno ottengo due letture al secondo, ma arduino non fa circa 60 cicli al sec?

Grazie

elvis:
Più o meno ottengo due letture al secondo, ma Arduino non fa circa 60 cicli al sec?

Con il loop, quasi vuoto, a seconda delle ottimizzazioni, Arduino compie anche 230 mila cicli al secondo. (Velocità del loop Mega 2560 - #10 by marcello.romani - Software - Arduino Forum)

Probabilmente la lentezza deriva dalla libreria usata. Se fa uso intenso di calcoli in virgola mobile il problema è lì perché l'unità aritmetica dell'Atmega gestisce solo calcoli interi in HW. Se vuoi accelerare il processo forse dovresti ricorrere all'uso di una MCU più potente oppure di una ALU esterna.

Ciao Leo72,
Scusa la mia ignoranza ma non ho idea di cosa siano HW, MCU, ed ALU...
Dovrei quindi modificare la libreria EmonLib?
Grazie

HW hardware
MCU unità microprocessore
ALU unità aritmetico-logica (coprocessore matematico)

elvis:
Dovrei quindi modificare la libreria EmonLib?

No. Ti sto dicendo che la lentezza registrata potrebbe essere data proprio dalla libreria stessa e dal tipo e quantità di calcoli che essa esegue.

... quindi, mi sembra di capire, non ci posso far nulla....

Scrivi che il problema nasce nel momento in cui inserisci le letture in un altro codice.
Non è che è l'altro codice che rallenta questo e non viceversa?

Ciao,
con la libreria EmonLib ci ho giocato parecchio, di fatto ci ho aggiunto altri sensori (temperatura, luce, etc ) e shield Wifi/Eth con relative librerie.
Non ho riscontrato nessun problema.

Prova a postare il codice che utilizzi e che ti da problemi!

Fondamentalmente il mio interesse è vedere la corrente misurata dai TA su cosm im modo d'aver sotto controllo la potenza generata dal mio impianto fotovoltaico.

Ho già un codice che "gira" molto bene con il quale visualizzo su cosm i dati dell'impianto termosolare. Refresh dei dati ogni 45"... Perfetto.
Aggiungendo le poche righe per il controllo dei TA, arduino rallenta e le letture su cosm avvengono ogni 4 min. circa.

Fondamentalmente il refresh dei dati su cosm avviene ogni 250 cicli...

4 minuti non è comunque male... ma mi piacerebbe rimanere sui 45"...

Questo è il codice di partenza:

/* IDE 1.0.1
 modified by Ettore Massimo Albani
 */

#include <SPI.h>
#include <Ethernet.h>

#define APIKEY         "XXXXXXXXXXXXXXXXXXXXXXXXXX"   
#define FEEDID         XXXXXX 
#define USERAGENT      "TEST 2"   
byte mac[] = {   
  0xDE, 0xAD, 0xBC, 0xEF, 0xFE, 0xBD};
IPAddress ip(192, 168, 11, 21); 
EthernetClient client;   
char server[] = "api.cosm.com";  
unsigned long lastConnectionTime = 0;  
boolean lastConnected = false; 
const unsigned long postingInterval = 10000; 
String DataString = "";
char Buffer[10];                                           
int otherSensorReadingAria = 0;  
int otherSensorReadingCaldaia = 0;
int otherSensorReadingResistenza2Kw = 0;
int caldaiaON = 0;                                          //*INGRESSO digitale PER CONTROLLO WEB STATO CALDAIA 
int Ventola = 0;                                            //*INGRESSO digitale PER CONTROLLO WEB STATO VENTOLA
int ResistenzaON = 0;                                            //*INGRESSO digitale PER CONTROLLO WEB STATO resistenza
const float AnaRef = 5.0;                                   // valore tensione (5V)
const unsigned int Risoluzione = 1024;                      // risoluzione (10 bit) 
const float RangeMin = 2.0;                                 // temperatura minima °C sensore LM35DZ (alim. 5V, out con res. 2k in serie)
const float RangeMax = 100.0;                               // temperatura massima °C sensore LM35DZ (alim. 5V, out con res. 2k in serie)
const float Incremento = 0.01;                              // incremento (10 mV/°C)
float Volt = 0;                                             // valore sensori analogici in volt
const float Isteresi = 1.0;                                 // isteresi (1 °C)
float TempAria = 0.0;                                       // temperatura aria
float TempAriaMin = 2.0;                                    // soglia inferiore temperatura aria (min 2 °C = RangeMin)
float TempAriaMax = 30.0;                                   // soglia superiore temperatura aria (max 100 °C = RangeMax)
float TempAcquaOUTtermosolare = 0.0;                                      // temperatura acqua
float TempAcquaMin = 2.0;                                   // soglia inferiore temperatura acqua (min 2 °C)
float TempAcquaMax = 43.0;                                  // soglia superiore temperatura acqua (max 100 °C)
float TempAcquaINGTermosolare = 0.0;                                      // temperatura acqua in ingresso al termosolare
extern unsigned long timer0_millis;
float mela;
void setup() {
mela=1;
  analogReference(DEFAULT);                                 // DEFAULT (5V), INTERNAL (1,1V), EXTERNAL (0÷5V)

  pinMode(A0, INPUT);                                       // NB sensore di temperatura aria
  pinMode(A1, INPUT);                                       // sensore di temperatura acqua
  pinMode(A2, INPUT);                                       // sensore di temperatura acqua ingresso termosolare
  pinMode(2, OUTPUT);                                      // D2 uscita per relè in parallelo alla resistenza da 2Kw installata sul bollitore 
  pinMode(3, INPUT);                                       //*D3 ingresso controllo stato ventola da D5   
  pinMode(4, INPUT);                                       //*D4 ingresso controllo stato caldaia da D6
  pinMode(5, OUTPUT);                                       //*USCITA IN PARALLELO AL RELE CALDAIA PER VISUALIZZAZIONE WEB STATO VENTOLA   
  pinMode(6, OUTPUT);                                       //*USCITA IN PARALLELO AL RELE ACQUA PER VISUALIZZAZIONE WEB STATO CALDAIA  
  
  pinMode(7, OUTPUT);                                       // relay ventola ON/OFF
  pinMode(8, OUTPUT);                                       // relay caldaia ON/OFF
  pinMode(9, INPUT);                                        // D10 ingresso per relè in parallelo alla resistenza da 2Kw installata sul bollitore
  Serial.begin(9600);

  if (Ethernet.begin(mac) == 0) {                           // start the Ethernet connection
    Ethernet.begin(mac, ip);                                // DHCP failed, so use a fixed IP address
    Serial.println("Failed to configure Ethernet using DHCP");
  }
}

void loop() {
    digitalWrite(2, HIGH);           
    Ventola = digitalRead(3);  
    caldaiaON = digitalRead(4);
    ResistenzaON = digitalRead(9); 
  Volt = analogRead(A0) * 0.5;
  TempAria = Volt;
  delayMicroseconds(120);
  Volt = analogRead(A1) * 0.5; 
  TempAcquaOUTtermosolare = ((Volt)+3);                 // temperatura acqua in °C +X°C PER COMPENSAZIONE TERMOMETRO TRIVALVOLA
  delayMicroseconds(120);                                   // 120 µs (min time reading = 100 µs x channel) 
  Volt = analogRead(A2) * 0.5;             // valore sensore acqua in volt
  TempAcquaINGTermosolare = ((Volt)+3);                 // temperatura acqua in °C +X°C PER COMPENSAZIONE TERMOMETRO TRIVALVOLA
  delayMicroseconds(120);                                   // 120 µs (min time reading = 100 µs x channel) 
  Serial.print("Temp. Aria: ");
  Serial.println(TempAria, 1);
    otherSensorReadingAria = Ventola;  
  Serial.print("Temp. Acqua: ");
  Serial.println(TempAcquaOUTtermosolare, 1);
   otherSensorReadingCaldaia = caldaiaON;
   Serial.print("Temp. Acqua Ing Termosolare: ");
  Serial.println(TempAcquaINGTermosolare);

  if (TempAria > (TempAriaMax + Isteresi)) {
    digitalWrite(7, HIGH);                                 // relay ventola ON
    digitalWrite(5, HIGH);                                 //*VENTILAZIONE ATTIVATA
    Serial.println("Aria calda - Ventola ON");
  }
  else if (TempAria < (TempAriaMax - Isteresi)) {
    digitalWrite(7, LOW);                                   // relay ventola OFF
    digitalWrite(5, LOW);                                    //*VENTILAZIONE DISATTIVATA
    Serial.println("Aria fredda - Ventola OFF"); 
  }
 if ((TempAcquaOUTtermosolare > (TempAcquaMax + Isteresi)) && mela==1) (timer0_millis = 0, mela = 0 );

  if (TempAcquaOUTtermosolare > (TempAcquaMax + Isteresi) && (millis()>30000)) {
   digitalWrite(8, LOW);                                   // relay caldaia OFF
       digitalWrite(6, LOW);                               //*USCITA IN PARALLELO AL SEGNALE CALDAIA PER TELECONTROLLO
    Serial.println("Acqua Calda - Caldaia OFF");
  }
  else if (TempAcquaOUTtermosolare < (TempAcquaMax - Isteresi)) {
    digitalWrite(8, HIGH);                                  // relay caldaia ON
        digitalWrite(6, HIGH);        //*USCITA IN PARALLELO AL SEGNALE CALDAIA PER TELECONTROLLO
    mela=1;
    Serial.println("Acqua fredda - Caldaia ON"); 
  }
  if (client.available()) {
    char c = client.read();
    Serial.print(c);
  }
  if (!client.connected() && lastConnected) {
    Serial.println();
    Serial.println("disconnecting...");
    client.stop();
  }
  if (millis() < lastConnectionTime) lastConnectionTime = millis();    // evita il blocco dopo 50gg poiché millis() si azzer
  if (!client.connected() && (millis() - lastConnectionTime > postingInterval)) {
    DataString = "TempAria,";
    DataString += FloatFormat(TempAria, 10, 1, false, true);
    DataString += "\nVentola,";
  DataString += otherSensorReadingAria;
   DataString += "\nResistenzaON,";
    DataString += FloatFormat(ResistenzaON, 10, 1, false, true);
  DataString += "\nTempAcquaINGTermosolare,";
    DataString += FloatFormat(TempAcquaINGTermosolare, 10, 1, false, true);
    DataString += "\nTempAcquaOUTtermosolare,";
    DataString += FloatFormat(TempAcquaOUTtermosolare, 10, 1, false, true);
    DataString += "\nCaldaia,";
  DataString += otherSensorReadingCaldaia; 
    sendData(DataString);
  }
  lastConnected = client.connected();
}
void sendData(String thisData) {
  if (client.connect(server, 80)) {
    Serial.println("connecting...");
    client.print("PUT /v2/feeds/");
    client.print(FEEDID);
    client.println(".csv HTTP/1.1");
    client.println("Host: api.cosm.com");
    client.print("X-ApiKey: ");
    client.println(APIKEY);
    client.print("User-Agent: ");
    client.println(USERAGENT);
    client.print("Content-Length: ");
    client.println(thisData.length());
    client.println("Content-Type: text/csv");
    client.println("Connection: close");
    client.println();
    client.println(thisData);
    Serial.println(thisData);
  } 
  else {
    // if you couldn't make a connection:
    Serial.println("connection failed");
    Serial.println();
    Serial.println("disconnecting...");
    client.stop();
  }
  // note the time that the connection was made or attempted:
  lastConnectionTime = millis();
}
String FloatFormat(float X, char Size, unsigned char Decimal, boolean Plus, boolean AutoReduce) {
  char Buffer[Size + 1];
  String Z = dtostrf(X, Size, Decimal, Buffer);
  if (Plus && X > 0) Z[Z.lastIndexOf(' ')] = '+';
  if (AutoReduce) Z.trim();
  return Z;
}

Ciao,
io sparo i dati su EmonCms (del progetto OpenEnergyMonitor) ogni 10 secondi.
Ripeto, senza problemi.

Prova a postare il tuo codice, senza quello si possono solo fare congetture.
Ora che hai postato il codice, c'è qualcosa in più su cui fare valutazioni

Ciao Pitusso,
Hai visto il codice?
Riesci a darmi qualche consigli?
Ma come fai a inviare dati su cosm ogni 10"?

Rieccomi a chiedere aiuto.

Su questo progetto sto utilizzando la libreria EmonLib trovata su openenergymonitor. Tale libreria è stata "costruita" per calcolare:

  • corrente
  • tensione
  • potenza

EmonLib.h:

/*
  Emon.h - Library for openenergymonitor
  Created by Trystan Lea, April 27 2010
  GNU GPL
*/

#ifndef EmonLib_h
#define EmonLib_h

#if defined(ARDUINO) && ARDUINO >= 100

#include "Arduino.h"

#else

#include "WProgram.h"

#endif

class EnergyMonitor
{
  public:

    void voltage(int _inPinV, double _VCAL, double _PHASECAL);
    void current(int _inPinI, double _ICAL);

    void voltageTX(double _VCAL, double _PHASECAL);
    void currentTX(int _channel, double _ICAL);

    void calcVI(int crossings, int timeout);
    double calcIrms(int NUMBER_OF_SAMPLES);
    void serialprint();

    long readVcc();
    //Useful value variables
    double realPower,
       apparentPower,
       powerFactor,
       Vrms,
       Irms;

  private:

    //Set Voltage and current input pins
    int inPinV;
    int inPinI;
    //Calibration coeficients
    //These need to be set in order to obtain accurate results
    double VCAL;
    double ICAL;
    double PHASECAL;

    //--------------------------------------------------------------------------------------
    // Variable declaration for emon_calc procedure
    //--------------------------------------------------------------------------------------
	int lastSampleV,sampleV;   //sample_ holds the raw analog read value, lastSample_ holds the last sample
	int lastSampleI,sampleI;                      

	double lastFilteredV,filteredV;                   //Filtered_ is the raw analog value minus the DC offset
	double lastFilteredI, filteredI;                  

	double phaseShiftedV;                             //Holds the calibrated phase shifted voltage.

	double sqV,sumV,sqI,sumI,instP,sumP;              //sq = squared, sum = Sum, inst = instantaneous

	int startV;                                       //Instantaneous voltage at start of sample window.

	boolean lastVCross, checkVCross;                  //Used to measure number of times threshold is crossed.
	int crossCount;                                   // ''


};

#endif

Avendo io bisogno di calcolare solo la corrente come posso fare ad eliminare tutti i calcoli che il mio Arduino fa e che a me non servono e che mi rallentano solo il refresh dei dati su xively?

Riuscite a darmi un consiglio?
Grazie

EmonLib.cpp

//#include "WProgram.h" un-comment for use on older versions of Arduino IDE
#include "EmonLib.h"

#if defined(ARDUINO) && ARDUINO >= 100

#include "Arduino.h"

#else

#include "WProgram.h"

#endif

// Sets the pins to be used for voltage and current sensors
void EnergyMonitor::voltage(int _inPinV, double _VCAL, double _PHASECAL)
{
   inPinV = _inPinV;
   VCAL = _VCAL;
   PHASECAL = _PHASECAL;
}

void EnergyMonitor::current(int _inPinI, double _ICAL)
{
   inPinI = _inPinI;
   ICAL = _ICAL;
}

// Sets the pins to be used for voltage and current sensors based on emontx pin map
void EnergyMonitor::voltageTX(double _VCAL, double _PHASECAL)
{
   inPinV = 2;
   VCAL = _VCAL;
   PHASECAL = _PHASECAL;
}

void EnergyMonitor::currentTX(int _channel, double _ICAL)
{
   if (_channel == 1) inPinI = 3;
   if (_channel == 2) inPinI = 0;
   if (_channel == 3) inPinI = 1;
   ICAL = _ICAL;
}

// emon_calc procedure
// Calculates realPower,apparentPower,powerFactor,Vrms,Irms,kwh increment
// From a sample window of the mains AC voltage and current.
// The Sample window length is defined by the number of half wavelengths or crossings we choose to measure.
void EnergyMonitor::calcVI(int crossings, int timeout)
{
  int SUPPLYVOLTAGE = readVcc();
  int crossCount = 0;                             //Used to measure number of times threshold is crossed.
  int numberOfSamples = 0;                        //This is now incremented  

  // 1) Waits for the waveform to be close to 'zero' (500 adc) part in sin curve.
  boolean st=false;                                  //an indicator to exit the while loop

  unsigned long start = millis();    //millis()-start makes sure it doesnt get stuck in the loop if there is an error.

  while(st==false)                                   //the while loop...
  {
     startV = analogRead(inPinV);                    //using the voltage waveform
     if ((startV < 550) && (startV > 440)) st=true;  //check its within range
     if ((millis()-start)>timeout) st = true;
  }
  
  // 2) Main measurment loop
  start = millis(); 

  while ((crossCount < crossings) && ((millis()-start)<timeout)) 
  {
    numberOfSamples++;                            //Count number of times looped.

    lastSampleV=sampleV;                          //Used for digital high pass filter
    lastSampleI=sampleI;                          //Used for digital high pass filter
    
    lastFilteredV = filteredV;                    //Used for offset removal
    lastFilteredI = filteredI;                    //Used for offset removal   
    
    // A) Read in raw voltage and current samples
    sampleV = analogRead(inPinV);                 //Read in raw voltage signal
    sampleI = analogRead(inPinI);                 //Read in raw current signal

    // B) Apply digital high pass filters to remove 2.5V DC offset (centered on 0V).
    filteredV = 0.996*(lastFilteredV+(sampleV-lastSampleV));
    filteredI = 0.996*(lastFilteredI+(sampleI-lastSampleI));
   
    // C) Root-mean-square method voltage
    sqV= filteredV * filteredV;                 //1) square voltage values
    sumV += sqV;                                //2) sum
    
    // D) Root-mean-square method current
    sqI = filteredI * filteredI;                //1) square current values
    sumI += sqI;                                //2) sum 
    
    // E) Phase calibration
    phaseShiftedV = lastFilteredV + PHASECAL * (filteredV - lastFilteredV); 
    
    // F) Instantaneous power calc
    instP = phaseShiftedV * filteredI;          //Instantaneous Power
    sumP +=instP;                               //Sum  
    
    // G) Find the number of times the voltage has crossed the initial voltage
    //    - every 2 crosses we will have sampled 1 wavelength 
    //    - so this method allows us to sample an integer number of half wavelengths which increases accuracy
    lastVCross = checkVCross;                     
    if (sampleV > startV) checkVCross = true; 
                     else checkVCross = false;
    if (numberOfSamples==1) lastVCross = checkVCross;                  
                     
    if (lastVCross != checkVCross) crossCount++;
  }
 
  // 3) Post loop calculations
  //Calculation of the root of the mean of the voltage and current squared (rms)
  //Calibration coeficients applied. 
  
  double V_RATIO = VCAL *((SUPPLYVOLTAGE/1000.0) / 1023.0);
  Vrms = V_RATIO * sqrt(sumV / numberOfSamples); 
  
  double I_RATIO = ICAL *((SUPPLYVOLTAGE/1000.0) / 1023.0);
  Irms = I_RATIO * sqrt(sumI / numberOfSamples); 

  //Calculation power values
  realPower = V_RATIO * I_RATIO * sumP / numberOfSamples;
  apparentPower = Vrms * Irms;
  powerFactor=realPower / apparentPower;

  //Reset accumulators
  sumV = 0;
  sumI = 0;
  sumP = 0;
}

double EnergyMonitor::calcIrms(int NUMBER_OF_SAMPLES)
{
  
int SUPPLYVOLTAGE = readVcc();

  
  for (int n = 0; n < NUMBER_OF_SAMPLES; n++)
  {
    lastSampleI = sampleI;
    sampleI = analogRead(inPinI);
    lastFilteredI = filteredI;
    filteredI = 0.996*(lastFilteredI+sampleI-lastSampleI);

    // Root-mean-square method current
    // 1) square current values
    sqI = filteredI * filteredI;
    // 2) sum 
    sumI += sqI;
  }

  double I_RATIO = ICAL *((SUPPLYVOLTAGE/1000.0) / 1023.0);
  Irms = I_RATIO * sqrt(sumI / NUMBER_OF_SAMPLES); 

  //Reset accumulators
  sumI = 0;
 
  return Irms;
}

void EnergyMonitor::serialprint()
{
    Serial.print(realPower);
    Serial.print(' ');
    Serial.print(apparentPower);
    Serial.print(' ');
    Serial.print(Vrms);
    Serial.print(' ');
    Serial.print(Irms);
    Serial.print(' ');
    Serial.print(powerFactor);
    Serial.println(' ');
    delay(100); 
}

//thanks to http://hacking.majenko.co.uk/making-accurate-adc-readings-on-arduino
//and Jérôme who alerted us to http://provideyourown.com/2012/secret-arduino-voltmeter-measure-battery-voltage/

long EnergyMonitor::readVcc() {
  long result;

  #if defined(__AVR_ATmega168__) || defined(__AVR_ATmega328__) || defined (__AVR_ATmega328P__)
  ADMUX = _BV(REFS0) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);  
  #elif defined(__AVR_ATmega32U4__) || defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
  ADMUX = _BV(REFS0) | _BV(MUX4) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
  ADCSRB &= ~_BV(MUX5);   // Without this the function always returns -1 on the ATmega2560 http://openenergymonitor.org/emon/node/2253#comment-11432
  #elif defined (__AVR_ATtiny24__) || defined(__AVR_ATtiny44__) || defined(__AVR_ATtiny84__)
  ADMUX = _BV(MUX5) | _BV(MUX0);
  #elif defined (__AVR_ATtiny25__) || defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny85__)
  ADMUX = _BV(MUX3) | _BV(MUX2);
  #endif

  delay(2);					// Wait for Vref to settle
  ADCSRA |= _BV(ADSC);				// Convert
  while (bit_is_set(ADCSRA,ADSC));
  result = ADCL;
  result |= ADCH<<8;
  result = 1126400L / result;			//1100mV*1024 ADC steps http://openenergymonitor.org/emon/node/1186
  return result;
}

Ciao Elvis..valida sta libreria..
Tornando a noi, ho notato che nello sketch della libreria EmonLib.cpp, ci sono delle delay(); cosa che nel tuo di sketch, nn ne ho viste..questo comporta rallentamenti sul ciclo di un programma..soprattutto, come nel tuo caso ce di mezzo una comunicazione seriale..
A me era capitata una cosa analoga..due sketch perfettamente funzionanti se uniti sì rallentavano a vicenda..

Bene bene, allora provo ad eliminare il delay(100) sulla libreria emonlib.cpp, ma secondo te si può eliminare un po' di cose e mantenere solo le stringhe relative al calcolo della corrente?
Devo dire che ho già fatto qualche tentativo, ma, evidentemente, cancello un po' troppa roba...

si non è mai buona cosa cancellare qualcosa dalle librerie..al max modificarle..comunque tieni presente che quelle delay(); sicuramente sono li per dare un tempo alla visualizzazione dei valori..quindi teoricamente cancellandola/e nn dovrebbe succedere niente..
prova e fammi sapere..
tu hai mai usato la shield RTC?

Ciao,
sto lavorando in questo periodo con un progettino che attualmente ha 3 sensori TA e deve crescere sino a 9.
Ad ora (quindi con 3 sensori) continuo a fare aggiornamenti ogni 10 secondi via eth (e 30 sec via gprs) senza problemi di sorta.

Nella libreria inoltre l'unico casi di delay significativo (se 100ms così si possono chiamare) si ha con la print seriale di tutte le variabili gestite, cosa che non hai motivo di utilizzare.

EDIT
io credo che il problema non risieda nella libreria in se, come già detto, ma da problemi colllaterali (overflow, memoria, etc).
Quindi, la cosa che ti consiglio di fare, è fare uso del monitor seriale e inserire nel codice in punti strategici delle print, in modo che tu possa capire in che punto del tuo codice avviene il "blocco".
Trovi poi in rete piccole funzioni che ti permettono di controllare la memoria disponibile di Arduino. Inserisci anche la chiamata a questa funzione in vari punti del tuo codice e verifica.

si quella è una prova assolutamente sensata da fare e doverosa..
ma quello che intendo io è che se nel suo programma usa dei serial.print senza usare delay, e quando va ad aggiungere il programma che ha trovato e che contiene dei serial.print però con delay, gli va a rallentare l'intero programma, anche se è solo uno il delay.

tu hai ipotizzato che potrebbe essere la memoria ma se cosi fosse il programma propio non partirebbe..