Stepper in sketch combinato risulta lento

buongiorno, nello sketch dell' oggetto, figurano alcune condizioni che riproducono un menù all'interno del quale un utente si "sposta".

ho la necessita di pilotare uno stepper nel mio caso nema 11 (4,5V 0,6A) con driver bipolar stepper (A4988). ora un semplice sketch "pulito"(intendo sketch dedicato al solo pilotaggio del motore senza il menù) risulta in un movimento adeguatamente veloce dello stepper.

nel momento in cui richiamo gli stessi comandi ma nel corpo di istruzioni dello sketch "a menu" per implementare la funzione del motore, vengono eseguiti a rilento(se chiedo un serial print di millis viene eseguito ogni 80 ms..)

ora se non al programma non viene richiesto di pilotare il driver, millis si aggiorna regolarmente.

anticipo eventuali domandi di delay() sparsi nel programma perchè non ce ne sono, è tutto concepito tramite intervalli dovuti a millis();

grazie a tutti anche solo per l'interessamento come sempre!

bel caso servano specifiche come al solito, chiedete pure e cercherò di fornirle al meglio che mi riesce.

Senza vedere il codice serve la famosa e " Sfera di cristallo USBtm " per poter formulare ipotesi

ok lo posto subito

progetto: erogatore automatico di croccantini per cani o gatti:

dunque il programma controlla : 4 pulsanti ed un potenziometro per far impostare all'utente quantità di cibo e muoversi all'interno del menu' definito dalle condizioni di stato di ck3.

un rtc()RealTimeClock per avere un orario di riferimento a cui impostare l'erogazione

un motore stepper che attua la forza di rotazione necessaria all'erogazione dei croccantini

una cella di carico che monitora il peso della ciotola normalmente ed in fase di riempimento

ed un display lcd per permettere la visualizzazione indipendentemente dal seriale di arduino.

#include "RTClib.h"                                       //LIBRERIA PER MODULO REAL TIME CLOCK

RTC_DS3231 rtc;                                           //GENERAZIONE ISTANZA REAL TIME CLOCK

                                                                  //PIN:(CELLA DI CARICO)5V + GND+22DT+24SCK //(PULSANTE ROSSO )18//(PULSANTE VERDE)19//(PULSANTE GIALLO)2//(PULSANTE BLU)3
#define steP 8                                                          //(POTENTIOMETER)A0 5V+GND//(LCD)5V+GND+21  SCL BLU.+20 SDA VERDE.//(REAL TIME CLOCK RTC DS3231)5V+GND+SCL+SDA.
#define dire 9
#define enable 10
#define greenB 19                                         //ASSEGNAZIONE PIN DI ARDUINO
#define redB 18                                           //
#define pot A0                                            //
#define giallo 2                                            //
#define blueB 3                                           //

#include <Wire.h>
#include <LiquidCrystal_I2C.h>                            //LIBRERIA COMANDI LCD

#define I2C_ADDR 0x27                                     //ASSEGNAZIONE DEI PIN DELL CHIP EXPANDER NELL'I2C
#define BACKLIGHT_PIN 3                                   //
#define En_pin 2                                          //
#define Rw_pin 1                                          //
#define Rs_pin 0                                          //
#define D4_pin 4                                          //
#define D5_pin 5                                          //
#define D6_pin 6                                          //
#define D7_pin 7                                          //

LiquidCrystal_I2C lcd(I2C_ADDR, En_pin, Rw_pin, Rs_pin, D4_pin, D5_pin, D6_pin, D7_pin);                          //COMUNICAZIONE PIN E I2c

#include "HX711.h"                        //libreria cella di carico
HX711 scale(22, 24);

unsigned long timer, intervallo = 0, intervallo2 = 0;
float calibration_factor = -463, units;
int load, statoPre = 1, previous = 1, tempO, tempM, statoO = 3, statoM = 3, statoLoop = 0, tempLoad, previousS = 1, pulse = LOW; //tempO=ore//tempM=minuti//statoO=salvaore//statoM=salvaminuti//ck3Temp=temporanea ck3 esce dalle 3 condizioni normali
volatile int ck3 = 1, ck2 = 1, ck1 = 0;                                                                       //StatoLoop=condizione stato nel loop//tempLoad=valore carico croccantini//previousS=stato funzione tara
char *res = malloc(5);                    //PASSA PARAMETRO QUANTITA' DI MEMORIA (5BYTE)




void setup() {
  Serial.begin(9600);
  if (!rtc.begin()) {                                         //CONTROLLO PER L'INIZIALIZZAZIONE RTC ALTRIMENTI AVVISA SU SERIALE
    Serial.println("rtc scollegato");
    while (true);
  }
  if (rtc.lostPower())                                        //SALVATAGGIO INFORMAZIONI INERENTI A DATA ED ORA NEL CASO VENGA A MANCARE L'ALIMENTAZIONE(RTD FORNITO DI BATTERIA)
    rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));


  lcd.begin(20, 4);                                 //ATTIVAZIONE RIGHE E COLONNE
  lcd.setBacklightPin(BACKLIGHT_PIN, POSITIVE);     //ATTIVAZIONE RETROILLUMINAZIONE
  lcd.setBacklight(HIGH);                           //

  pinMode(giallo, INPUT);                      //ATTIVAZIONE RESISTENZE INTERNE PULL UP PER PULSANTI
  pinMode(blueB, INPUT_PULLUP);                     //
  pinMode(greenB, INPUT_PULLUP);                   //
  pinMode(redB, INPUT_PULLUP);                     //
  pinMode(pot, INPUT);                             //
  pinMode(steP, OUTPUT);
  pinMode(dire, OUTPUT);
  pinMode(enable, OUTPUT);
  digitalWrite(enable, HIGH);
  digitalWrite(dire, HIGH);                         //pin dir A4988 5V IL NEMA 11 RUOTA IN SENSO ANTIORARIO
  attachInterrupt(digitalPinToInterrupt(redB), menu, FALLING);                //PULSANTE ROSSO SCORRE PAGINE MENU'
  attachInterrupt(digitalPinToInterrupt(greenB), conferma, FALLING);          //PULSANTE VERDE CONFERMA LE OPERAZIONI SCELTE DALL'UTENTE
  attachInterrupt(digitalPinToInterrupt(giallo), togli, RISING);             //PULSANTE GIALLO INCREMENTA IN FASE DI SELEZIONE(ORARIO)
  attachInterrupt(digitalPinToInterrupt(blueB), aggiungi, FALLING);               //PULSANTE BLU DECREMENTA IN FASE DI SELEZIONE(ORARIO)
}
void loop() {
  Serial.println("tempO" + String(tempO) + "  tempM" + String(tempM) + "  ck3:" + String(ck3) + "  statoLoop" + String(statoLoop) + "  tempLoad:" + String(tempLoad) + "  Peso:" + String(units, 0) + "  ck2:" + String(ck2));

  DateTime now = rtc.now();                                                                           //OTTENGO L'INFORMAZIONE DI DATA ED ORA NEL CORPO DI VOID LOOP
  lcd.setCursor(0, 0);                                                                                //SERIE DI COMANDI PER PRINT A SCHERMO
  lcd.print(zeriData(now.day()) + "/" + zeriData(now.month()) + "/" + zeriData(now.year()));          //
  lcd.setCursor(15, 0);                                                                               //
  lcd.print(zeriData(now.hour()) + ":" + zeriData(now.minute()));                                     //

  timer = millis();                                                                                   //ASSEGNAZIONE DI MILLIS AD UNA VARIABILE TIMER, CHE NE PERMETTERA' LA MANIPOLAZIONE
  scale.set_scale(calibration_factor);                                                                //PASSA IL VALORE DI CALIBRAZIONE ALLA GESTIONE DELLA CELLA DI CARICO
  units = scale.get_units();                                                                          //ASSOCIA LA VARIABILE UNITS AL PESO RILEVATO DALLA BILANCIA.(D'ORA IN POI G.)
  load = analogRead(pot);                                                                             //VALORE ANALOGICO DEL POTENZIOMETRO UTILIZZATO COME STRUMENTO DI INTERFACCIA PER L'UTENTE

  if (statoPre != ck3) {                                                                              // AD OGNI CAMBIO DI STATO DEL PULSANTE ROSSO RICHIAMO UN LCD CLEAR E RIPULISCO LO SCHERMO
    lcd.clear();                                                                                      //RIASSEGNO IN OLTRE ALLA VARIABILE CK2 IL VALORE DI 1 ONDEVITARE CHE L'UTENTE NEL NAVIGARE TRA LE PAGINE
    statoPre = ck3;                                                                                   // DEL MENU' SCORRA LE FINESTRE PRINCIPALI SENZA RIPORTARE LA SCHERMATA NEL "LUOGO DI PARTENZA"
    ck2 = 1;
  }
  if (previous != ck2) {                                                                              // AD OGNI CAMBIO DI STATO DEL PULSANTE VERDE RICHIAMO UN LCD CLEAR E RIPULISCO LO SCHERMO
    lcd.clear();
    previous = ck2;
  }
  if (ck3 >= 5)                                                                                       //HO AVUTO NECESSITà DI CREARE UNA PAGINA DI MENU' NON RICHIAMATA DALL'UTENTE BENSI' CHE SI AUTOGENERASSE
    ck3 = 1;                                                                                          //ALLA VERIFICA DELLA CONDIZIONE DI ORA E MINUTI IMPOSTATA DALL'UTENTE(CK3==4) DAL MOMENTO IN QUI 4 NON è UN VALORE
  // ASSEGNATO AL NORMALE INCREMENDO DELLA VARIBILE CK3 TRAMITE PULSANTE,E' STATO NECESSARIO AVERE UN CONTROLLO AUTOMATICO
  if (ck3 == 1)                                                                                       //CK3 DEFINISCE LA PRIMA PAGINA DEL MENU' RICHIAMA GRAMMI(STAMPA DEL PESO) CON POSSIBILITA' DA PARTE DELL'UTENTE
    grammi();                                                                                         //DI PORTARE A 0 LA BILANCIA CON O SENZA UN EVENTUALE PESO APPLICATO.
  if (ck3 == 2)                                                                                       //RICHIAMA RIEMPIMENTO POSSIBILITA' DI VARIARE LA QUANTITA' DI CROCCANTINI DA EROGARE E UN ORA PRECISA IN CUI ESEGUIRLA
    riempimento();
  if (ck3 == 3) {
    calibrazione();
    if (ck3 == 4)
      ck3 = 1;
  }                                                                                   //FUNZIONE CHE PERMETTE ALL'UTENTE DI RICALIBRARE LA BILANCIA IN CASO NEL TEMPO DOVESSE MODIFICARSI IN QUALCHE MODO
  //IL PARAMETRO DI SCALING.
  if (tempO == now.hour() && tempM == now.minute())  {                                                //CONDIZIONE CHE RISULTA VERA SOLAMENTE SE L'ORARIO IMPOSTATO DALL'UTENTE CORRISPONDE A QUELLO REALE
    if (statoLoop == 0 && units < tempLoad) {                        // MODIFICARE CK3 PER FARE SI CHE IL LOOP PERSISTA ED ESEGUO UN SINGOLO CLEAR CHE RIPULISCA LO SCHERMO ADATTANDOLO AL SEGUENTE SET DI ISTRUZIONI, SALVO IL VECCHIO VALORE
      lcd.clear();
      statoLoop = 1;
      digitalWrite(enable, LOW);                                                       // CHE CORRISPONDE ALL'ULTIMA PAGINA DI MENU CON CUI L'UTENTE SI INTERFACCIA PRIMA CHE L'EROGAZIONE PARTA,COSI' DA ESSERE RIPROPOSTA UNA VOLTA FINITA L'EROGAZIONE
    }
  }
  if (statoLoop == 1) {                                                                      //SE CK3 = 4 ALLORA LE 3 CONDIZIONI PRECEDENTI NON PERSISTONO, PERTANTO DOPO LCD.CLEAR() MI TROVO UNA NUOVA PAGINA DI MENU' STAMPABILE PER LA DURATA DI TUTTA L'EROGAZIONE
    ck3 = 4;
motorino();                                  //IMPONENDO STATO LOOP =1 NON APPENA SMETTE DI VERIFICARSI LA CONDIZIONE ORARIO UTENTE E ORARIO ATTUALE, IL PROGRAMMA PROSEGUE NEL CORPO DI ISTRUZIONI SUCCESSIVO
    lcd.setCursor(11, 0);
    lcd.print("(4)" );
    if (ck3 != 4)
      ck3 = 4;
  }                                         //RICHIAMANDO QUESTA FUNZIONE IL PROGRAMMA ESEGUE UN CONTROLLO DELL'UNITA CORRISPONDENTE AL PESO DELLA CIOTOLA CON LE UNITA' IMPOSTATE TRAMITE INTERFACCIA DALL'UTENTE,RELATIVE AL PESO DESIDERATO DI RIEMPIMENTO.


  //CONDIZIONI VERIFICATE UNA SOLA VOLTA DOPO CHE L'EROGAZIONE FINISCE: RIPORTA ALLA PAGINA DI MENU' PREMEMORIZZATA SU ck3Temp
  if (statoLoop == 2)
  { digitalWrite(enable, HIGH);                                 //IN CUI CK3 RIPRENDE IL VAOLRE LASCIATO DALL'ULTIMA NAVIGAZIONE DELL'UTENTE.                                                           //VARIABILE DI STATO IMPOSTA ALTRIMENTI LA CONDIZIONE ORA IMPOSTATA E ORA ATTUALE DIVERSE RISULTEREBBE SEMPRE VALIDA, IMPOSSIBILITANDO LA RIUSCITA DELL'UTILIZZO DEL NORMALE MENU'
    statoLoop = 3;
    ck3 = 1;
    lcd.clear();
  }
  //PUO' ACCADERE CHELA CONDIZIONE CHE VERIFICA ORE E MINUTI RITORNI FALSA SE PER ERRORE L'UTENTE DOVESSE CONFERMARE L'ORARIO NEL MOMENTO STESSO                                            //A QUEL PUNTO LA VARIABILE DI STATO NON SAREBBE IN LINEA CON I CHECK CHE DEVE GARANTIRE,INOLTRE IL SERVO A SEGUITO DELL'ERRORE UTETE RIMARREBBE ALIMENTATO                                                              //E' NECESSARIO INOLTRE IN TALE EVENTUALITA' CHE LA VARIABILE ASSEGNATA AL MENU' RITORNI ALLA POSIZIONE DI PARTENZA,ALTRIMENTI ESCE DAI PAREMETRI CHE
  if (statoLoop == 3 && tempM != now.minute())
    statoLoop = 0;                                                 //NE CONTROLLANO IL NORMALE SCORRIMENTO (1->3)
  if (statoLoop == 0 && ck3 > 3) {
    digitalWrite(enable, HIGH);
    ck2 = 1;
    previous = ck2;
  }



  //VERIFICATO QUINDI CHE NON SI E' NELLO STATO CORRISPONDENTE AL MOMENTO DI ATTIVAZIONE DEL MOTORE PER L'EROGAZIONE DEI CROCCANTINI, SI PROCEDE ALLA RICONVERSIONE DI CK3 NEL CASO SUPERI LA SOGLIA DELLA 3 PAGINA DI MENU'
}



void motorino() {
  lcd.setCursor(11, 0);
  lcd.print("(4)" );


  if (units <= tempLoad * 8 / 10 )
  {
    if (timer - intervallo >= 10) {
      Serial.println(timer);
      pulse = !pulse;
      intervallo = timer;
    }
    digitalWrite(steP, pulse);

    lcd.setCursor(0, 2);
    lcd.print("Impostato:" + String(tempLoad) + "g.");
    lcd.setCursor(0, 3);
    lcd.print("Riempendo:" + String(units, 0) + "g.");
    pulisciSchermo();
  }
  if (units > tempLoad * 8 / 10 && units < tempLoad * 0.90 )
  {
    if (timer - intervallo >= 20) {
      Serial.println(timer);
      pulse = !pulse;
      intervallo = timer;
    }
    digitalWrite(steP, pulse);
    lcd.setCursor(0, 2);
    lcd.print("Impostato:" + String(tempLoad) + "g.");
    lcd.setCursor(0, 3);
    lcd.print("Riempendo:" + String(units, 0) + "g.");
    lcd.print("   ");
  }
  if (units >= tempLoad) {
    statoLoop = 2;
    lcd.clear();
    digitalWrite(enable, HIGH);
  }
}
String zeriData(int n) {                               //FORMATO DATA CON 0 DAVANTI ANCHE AD 1 SOLA CIFRA SIGNIFICATIVA
  sprintf(res, "%02d", n);
  return String(res);
}
void tara() {                                         //AZZERA LA BILANCIA

  if (ck2 != previousS) {                              // se nella prima pagina menu, il tasto verde viene premuto ck2 assume valore diverso da stato--> scale.tare puoò essere eseguito
    scale.tare();                                     // immediatamente previous assume il nuovo valore di ck2, e la condizione smette di verificarsi.
    previousS = ck2;
  }
}
void togli() {                                       //attach interrupt incremento(giallo) non viene richiamata al cambio di stato del pin 2[problema]
  if (timer - intervallo2 >= 180)
  {
    intervallo2 = timer;
    ck1--;
  }
}
void aggiungi() {
  if (timer - intervallo2 >= 180)
  {
    intervallo2 = timer;
    ck1++;
  }
}
void conferma() {                                     //RICHIAMA LA CONFERMA DA PULSANTE VERDE
  if (timer - intervallo2 >= 300)
  {
    ck2++;
    intervallo2 = timer;
  }
}
void menu() {                                          // RICHIAMA VARIABILE MENU'
  if (timer - intervallo2 >= 300)
  {
    ck3++;
    intervallo2 = timer;
    ck2 = 1;
  }
}
void pulisciSchermo() {                                //RICHIAMA PULIZIA COORDINATE LCD
  lcd.print("  ");
}
void grammi () {                                        //RICHIAMA STAMPA DEL PESO MISURATO
  previousS = ck2;
  lcd.setCursor(11, 0);
  lcd.print("(1)" );
  lcd.setCursor(0, 1);
  lcd.print("*Verde per Azzerare*" );
  lcd.setCursor(0, 2);
  lcd.print("");
  lcd.setCursor(5, 3);
  lcd.print("Peso:" + String(units, 0) + "g.");
  pulisciSchermo();
  tara();                                               //RICHIAMA TARA IN MODALITA' IMPULSO ALL'INTERNO DELLA FUNZIONE
}
void riempimento() {                                    //RICHIAMA IMPOSTAZIONE RIEMPIMENTO CIOTOLA[problema]selezione orario
  DateTime now = rtc.now();
  lcd.setCursor(11, 0);
  lcd.print("(2)" );
  if (ck2 == 1) {
    if (load < 24)
      load = 0;

    statoO = 3;                                 //  OGNI VOLTA CHE IL MENU TORNA IN PAGINA PRINCIPALE, INDIPENDENTEMENTE DAI VALORI ASSUNTI DALLE VARIABILI DI STATO NEL PROGRAMMA
    statoM = 4;                                 //  TORNANO AL LORO VALORE DI ORIGINE
    lcd.setCursor(2, 1);
    lcd.print("**Rifornimento**");
    pulisciSchermo();
    lcd.setCursor(0, 3);
    lcd.print("Quantita':");
    lcd.setCursor(10, 3);
    lcd.print(String(load / 2) + "g.");
    lcd.print("   ");
    ck1 = now.hour();
  }
  if (ck2 == 2) {
    tempLoad = load / 2;
    lcd.setCursor(2, 1);
    lcd.print("**Rifornimento**");
    lcd.setCursor(0, 3);                                          //questa condizione dovrebbe essere nella funzione interrupt per evitare incongruenze durante l'esecuzione di istruzioni esterne, ma in tal caso
    lcd.print("Orario:");
    lcd.setCursor(8, 3);
    if (timer - intervallo >= 100) {
      intervallo = timer;
      lcd.print(String(zeriData(ck1)) + ":" + String(zeriData(now.minute())));
    }
    pulisciSchermo();

    if (ck1 < 0)
      ck1 = 23;                                              // il limite di ck1 per minuti != da limite di ck1 per ore.(non può più essere simultaneamente limitato a 24 (ore) e 60 (minuti) )    lcd.setCursor(14, 1);

    if (ck1 > 23)
      ck1 = 0;
  }
  if (ck2 == 3) {
    if (statoO == 3) {                                          //SALVATAGGIO VARIABILE ORE APPENA IMPOSTATA DALL'UTENTE TRAMITE TASTO VERDE DI CONFERMA CHE AVVIENE CON IL SUPPORTO DI UNA VARIABILE DI STATO
      tempO = ck1;                                              //ALTRIMENTI VERREBBE ESEGUITA L'OPERAZIONE DI SALVATAGGIO A LOOP, SOVVRESCRIVENDO CONTINUAMENTE IL VALORE VAR ck1 CHE A QUESTO PUNTO DEVE INVECE
      ck1 = now.minute();                                       //DARE POSSIBILITA' ALL'UTENTE DI SCRORRERE I VALORI DA 0-60 PER SALVARE VARIABILE MINUTI
      statoO = 4;
      Serial.println("una volta");
      Serial.println(ck2);
    }
    lcd.setCursor(2, 1);
    lcd.print("**Rifornimento**");
    lcd.setCursor(0, 3);
    lcd.print("Orario:");
    lcd.setCursor(8, 3);
    lcd.print(String(zeriData(tempO)) + ":"  );
    if (timer - intervallo >= 100) {
      intervallo = timer;
      lcd.setCursor(11, 3);
      lcd.print(zeriData(ck1));
    }
    pulisciSchermo();

    if (ck1 < 0 )
      ck1 = 59;

    if (ck1 > 59)
      ck1 = 0;
  }
  if (ck2 == 4)
  {
    if (statoM == 4) {
      tempM = ck1;
      ck1 = 0;
      statoM = 5;
    }
    lcd.setCursor(2, 1);
    lcd.print("**Ora Impostata**");
    lcd.setCursor(0, 3);
    lcd.print("Orario:");
    lcd.setCursor(8, 3);
    lcd.print(String(zeriData(tempO)) + ":" + String(zeriData(tempM)));
    pulisciSchermo();


    if (timer - intervallo2 >= 3000)
    {
      if (statoM == 5)
      { lcd.clear();
        statoM = 6;
        ck2 = 1;

      }

      intervallo2 = timer;


    }
    if (ck2 > 4)
      ck2 = 1;
    if (ck2 >= 2 && ck3 == 3)
      ck2 = 1;
  }


}
void calibrazione() {                                  //RICHIAMA LA CALIBRAZIONE PER CALIBRARE LA BILANCIA[da impostare su lcd]
  lcd.setCursor(11, 0);
  lcd.print("(3)" );
  lcd.setCursor(0, 2);
  lcd.print("Peso:" + String(units, 0) + "g.");
  pulisciSchermo();

  if (load <= 511) {
    load = load - 511;
    lcd.setCursor(0, 1);
    lcd.print("Togli: " );
    pulisciSchermo();
    lcd.setCursor(13, 1);
    lcd.print(load / 4);
    pulisciSchermo();
    if (ck2 == 2) {
      ck2 = 1;
      calibration_factor = calibration_factor + load / 4;
    }
  }
  if (load > 511)
  {

    load = load - 511;
    lcd.setCursor(0, 1);
    lcd.print("Aggiungi: ");

    lcd.setCursor(13, 1);
    lcd.print("+" + String(load / 4));
    pulisciSchermo();
    if (ck2 == 2)
    {
      ck2 = 1;
      calibration_factor = calibration_factor + load / 4;

    }
  }
  lcd.setCursor(0, 3);
  lcd.print("Calibrazione:" + String(calibration_factor, 0));
  pulisciSchermo();
  if (ck2 != 1 && ck3 == 3)
    ck2 = 1;
}

mi rendo conto che sia improponibile il caso specifico, per questo la mia domanda era abbastanza generica se esiste un caso comune in cui richiamando gli step del motore ad un dato ritardo, il programma li esegua comunque piu lentamente di quanto richiesto e desiderato.

Allora considera che su un micro controllore tipo Arduino non hai sistema operativo con più task attivi e cose che possono interporsi alla tua elaborazione quindi se il micro esegue più lentamente i comandi di quello che ti aspetti è dovuto unicamente al fatto che sta facendo altro nel tuo programma.
Occorre quindi che metti un bel po' di messaggi di debug sulla seriale per capire che giro fa il codice per capire dove sta l'inghippo che fa girare più lentamente il motorino rispetto al solo codice dedicato.
Diciamo che il codice è strutturato in modo un po' confuso per chi lo legge la prima volta, magari per te è tutto chiaro perché ci sei sopra da molto.
Quello che posso dirti con quasi certezza che fai abbondante uso della classe String per convertire le informazioni, questo oltre che superfluo è dannoso e alla lunga può portare a blocchi o comportamenti anomali quando il programma girerà per molto tempo senza un riavvio (e non sto consigliando di riavviarlo ogni tanto :slight_smile: )
Per fare la solita cosa prova a guardare le funzioni per le stringhe classiche del C tipo
itoa
in modo che ti metti al riparo dal rischio di "finire la memoria" disponibile (se cerchi sul forum trovi molte volte la cosa come trattata e nei topic c'è anche un alternativa che non ti costringe a stravolgere troppo il programma se vuoi)
Altra cosa è l'impostazione dell'ora nel caso venga persa l'alimentazione a batteria, se succede la data/ora torna alla data/ora di compilazione non quella attuale. Quindi o prevedi di poterla reimpostare da display o la devi richiedere in altro modo, ma non credo che il progetto sia connesso quindi mi sa che resta solo la prima possibilità.

1 Like

ok grazie tante! oggi e domani faccio fatica a mettermici sopra per impegni, ma se trovo l'inghippo avviso e aggiorno immediatamente grazie!

ps grazie anche per l'rtc