"delay" dentro un "delay" impossibile?

volglio cercare di rendere esente da delay() la mia programmazione
faccio l'esempio reale
ogni tot millisecondi usando millis() (non delay)
porto una variabile a uno
un if controlla se la variabile a uno (che dopo eseguito il codice va a zero)
ed esegue il codice
(10 letture dello stesso canale ADC
DELL'ADS1256
TRA UNA LETTURA E L'ALTRA ADESSO c'e un delay ()
vorrei togliere questo delay bloccante con un "delay()" non bloccante

il delay è molto minore del tempo che impiega l'arduino ad attraversare tutto lo sketch
che ci possiamo inventare?

proverei qualcosa del genere

const byte sensorPin = A0;

unsigned long masterChrono;
const unsigned long masterPeriod = 5000; // 5s
bool acquisitionStarted = false;

unsigned long acquisitionChrono;
const unsigned long acquisitionPeriod = 200; // 20ms

const byte sampleCnt = 10;
int samples[sampleCnt];
byte currentSample = 0;

void setup() {
  Serial.begin(115200); Serial.println();
  masterChrono = -masterPeriod; // per iniziare subito
}

void loop() {
  if (!acquisitionStarted && (millis() - masterChrono >= masterPeriod)) {
    acquisitionStarted = true;
    acquisitionChrono = millis();
    Serial.println(F("sampling started!"));
  }

  if (acquisitionStarted) {
    if (millis() - acquisitionChrono >= acquisitionPeriod) {
      acquisitionChrono = millis();
      samples[currentSample++] = analogRead(sensorPin);
      Serial.print(F("sample #")); Serial.println(currentSample);
      if (currentSample >= sampleCnt) {
        Serial.println(F("sampling ended!"));
        currentSample = 0;
        acquisitionStarted = false;
        masterChrono = millis();
      }
    }
  }
}

:face_with_monocle: proverò a studiarlo meglio questo codice ma non riesco a vedere la "soluzione logica" ammesso che ci sia per dei delelay(10) sembrano troppo troppo piccoli

Immagino di non aver capito la tua domanda allora... pensavo volessi sbarazzarti del delay()

si voglio levare il piu possibile i delay() dalla mia programmazione "arduinica"
anche altre cose adesso mi sembrano "intollerabili" .
tipo un if che verifica lo stato di un pin digitale a ogni ciclo di loop :frowning_face:
e altre "cosette"
ovviamente quando si inizia con arduino tutto va bene,
poi se le cose si fanno serie bisogna risparmiare sulle risorse del micro dove possibile,
se no si rimane sempre a corto di prestazioni o hardware

il tuo arduino è veloce, va bene controllare un pin ad ogni loop() se questo è quello che devi fare.

l'ottimizzazione iniziale non è sempre buona. se le cose iniziano a essere lente, allora certo, puoi guardare dove viene speso il tempo.

Postalo il codice.
Certo anche delay(1000) è molto minore di un ciclo di loop che impegna la cpu per 10 secondi.

Comunque leggo poi che forse tiro ad indovinare che il delay è di 10ms e chissa quante cose può (o deve) fare arduino in 10ms.

Ciao.

sicuro ... se va bene lo stesso è uguale, usiamolo cosi!
ma è il principio che mi sembra strampalato gia in partenza,
e come aprire la porta ogni minuto per vedere se c'è qualcuno

questo e l'if interessato CAMBIA SOLO L'ADC CHE QUI è L' ADS1115,
da sostituire con ads1256 a 24 bit
la variabile stab e uguale a 10 millisecondi,

con che cosa posso sostituire il delay(stab) ?

if( remote == 0 &&  REGOL_DATA == 0) {
    adc_1.setCompareChannels(ADS1115_COMP_0_GND);


 lett_ta_1 = adc_1.getRawResult() ;
     delay(stab);
lett_ta_2 = adc_1.getRawResult() ;
     delay(stab);
lett_ta_3 = adc_1.getRawResult() ;
     delay(stab);
lett_ta_4 = adc_1.getRawResult() ;
     delay(stab);
lett_ta_5 = adc_1.getRawResult() ;
     delay(stab);
lett_ta_6 = adc_1.getRawResult() ;
  delay(stab);
lett_ta_7 = adc_1.getRawResult() ;
 delay(stab);
lett_ta_8 = adc_1.getRawResult() ;
  delay(stab);
lett_ta_9 = adc_1.getRawResult() ;
 
 
 //Serial.println("lett_ta_1");
 //Serial.println(lett_ta_1);
 
 //Serial.println("millis");
 //Serial.println(millis());

 posiz_ta = lettura_posiz_ta;
 //riconfermo la lettura perche posiz_ta passa nel pettine
 //Serial.println("lettura_posiz_ta");
 //Serial.println(lettura_posiz_ta);

lettura_posiz_ta = (lett_ta_1/10)
+ (lett_ta_2/10) + (lett_ta_3/10) + (lett_ta_4/10)  
+ (lett_ta_5/10) + (lett_ta_6/10)
+ (lett_ta_7/10) + (lett_ta_8/10) + (lett_ta_9/10);

lettura_posiz_ta = lettura_posiz_ta  / 16 ;


if (lettura_posiz_ta == posiz_ta - 1) {
   lettura_posiz_ta = lettura_posiz_ta + 1 ;
   } 
 
 if (lettura_posiz_ta == posiz_ta + 1) {
   lettura_posiz_ta = lettura_posiz_ta - 1;
  }
 }

se questo è un problema puoi usare gli interrupt

ma il loop() verrà eseguito senza fare nulla o (meglio ?) puoi spegnere il microcontrollore.

if( remote == 0 &&  REGOL_DATA == 0) {
    adc_1.setCompareChannels(ADS1115_COMP_0_GND);
    // devi trasformare lett_ta_1 in un array
    // Ti serve quindi un indice set a 0, es: myIdx
    if (myIdx == 0) {
       lett_ta_1[myIdx] = adc_1.getRawResult() ;
       saveTime = millis();
       myIdx = 1;
    } else {
      if ( (milli() - saveTime) >= 10 ) {
          
           lett_ta_1[myIdx] = adc_1.getRawResult() ;
           saveTime = millis();
           if (myIdx < 9)
               myIdx++;
         
      }
    }
   // quando myIdx == 9 hai collezionato i tuoi dati e ci hai messo 100ms, durante questi 100ms non puoi effetture medie e altri calcoli ovviamente.
 

Vedi se ne capisci il senso perché è da sistemare sicuramente.

Ciao.

Vedi se ne capisci il senso perché è da sistemare sicuramente.

La condizione if( remote == 0 && REGOL_DATA == 0) potrebbe essere un trigger impulsivo, non è detto che sia vera ad ogni ciclo di loop o che rimanga vera per il tempo necessario al completamento del processo di lettura. Il problema è naturalmente il design bloccante generale, che è basato su una procedura guidata direttamente dall'ordine delle istruzioni, e non da un susseguirsi di stati/eventi/azioni testati in un ciclo di loop che gira libero alla massima velocità.

con che cosa posso sostituire il delay(stab) ?

Non è così immediato, va ripensato completamente l'ordine di esecuzione come detto prima, ma anche di tutto il resto del programma.

Questa la tua procedura:

SE condizione:
    prime impostazioni
    leggi
    attendi
    leggi
    attendi
    leggi
    attendi
    leggi
    attendi
    leggi
    attendi
    leggi
    attendi
    leggi
    attendi
    leggi
    attendi
    leggi
    elabora

Questo è come deve/può diventare:

SE  non in lettura   E  condizione di avvio lettura:
    prime impostazioni
    leggi primo campione
    salva tempo
    imposta in lettura
ALTRIMENTI SE  in lettura   E   timeout 10ms:
    leggi campione
    SE ultimo campione:
        elabora
        imposta non in lettura
    ALTRIMENTI:
        salva tempo

...che grosso modo è quanto scritto da Maurotec

La cosa importante da capire è che la prima procedura è bloccante, l'if termina solo quando tutti i passi (e relativi delay) sono stati eseguiti. la seconda non è bloccante, sono solo if che valutano una condizione, se è vera si esegue l'azione richiesta, altrimenti si passa subito oltre. E l'esecuzione completa della procedura avviene in molti cicli di loop, un passo ogni volta che una condizione diventa vera.

if (n==0) t_stab=millis(); 
if (millis()-t_stab>=10*n)
  {  // Per n da 0 a 8:
  lett_ta[n] = adc_1.getRawResult();
  n+=1;
  }
if (n==9) n=0;

sicuramente una "sbirciatina" a gli array la darò che sono proprio a digiuno

ti sei avvicinato alla soluzione del problema.
come avevo detto fino a che si e agli inizi o si vuole solo giocare/accendere le luci del presepe tutto va bene.
quando si iniziano ad usare "schedine" extra con le loro librerie piu un codice lunghetto tutto sembra diventare lento