Cronometro tempo ricezione segnale

Salve a tutti!
Mi trovo in difficoltà riguardo il cronometrare il tempo di ricezione di un segnale analogico.

In pratica, indipendentemente dal valore effettivo del segnale in A0 ho bisogno di sapere per quanto tempo arduino riceve questo segnale partendo appunto dall'istante in cui comincia a riceverlo.
Nella mia ignoranza da neofita ho utilizzato uno spunto preesistente e cercato di modificarlo per la mia esigenza.

long point;
long timepoint = 2000;
void setup() {
  // initialize serial communication at 9600 bits per second:
  pinMode (13, OUTPUT);
  Serial.begin(9600);
  digitalWrite (13, LOW);
  point = millis();
}

// the loop routine runs over and over again forever:
void loop() {
  // read the input on analog pin 0:
  int sensorValue = analogRead(A0);
  // Convert the analog reading (which goes from 0 - 1023) to a voltage (0 - 5V):
  float voltage = sensorValue * (9.0 / 1023.0);
  // print out the value you read:
  Serial.println(voltage);
  delay (1000);
  while ( sensorValue <= 1.30) and  millis()- point>= timepoint);
  {digitalWrite (13, HIGH);
    point = millis(); 
  }
}

Come potete vedere ho sbagliato qualcosa per non dire tutto.
Potreste gentilmente aiutarmi, per favore?
Vi ringrazio in anticipo.`

Per spiegarmi meglio vorrei che il pin 13 rimanga in LOW finché arduino non legge alcun segnale in A0.
Trascorsi 2 secondi dal momento di ricezione del segnale in A0 allora devo trasformare il pin 13 in HIGH.

Buongiorno e benvenuto nella sezione Italiana del forum,
cortesemente, come prima cosa, leggi attentamente il REGOLAMENTO di detta sezione, (... e, per evitare future possibili discussioni/incomprensioni, prestando molta attenzione al punto 15), dopo di che, come da suddetto regolamento (punto 16.7), fai la tua presentazione NELL'APPOSITA DISCUSSIONE spiegando bene quali esperienze hai in elettronica e programmazione, affinché noi possiamo conoscere la tua esperienza ed esprimerci con termini adeguati.

Grazie.

P.S.: Ti ricordo che, purtroppo, fino a quando non sarà fatta la presentazione nell’apposita discussione, nel rispetto del succitato regolamento nessuno ti risponderà (eventuali risposte o tuoi ulteriori post, verrebbero temporaneamente nascosti), quindi ti consiglio di farla al più presto. :wink:

Grazie mille delle informazioni.
Cercando di rispondere al thread non mi permette con il tasto rispondi come sto facendo qui di potermi presentare. Spero di riuscirci al più presto per poter condividere con voi le esperienze di arduino.
Sapete dirmi come rispondere alle presentazioni?

Scusa @geko11 c'è un errore nel post di @docdoc.
Il link corretto per presentarsi è il seguente:
presentazioni-nuovi-iscritti-fatevi-conoscere-da-tutti-part-2

Ciao.

Grazie per la segnalazione, ho corretto il post.

Eh, ci sono tante cose che non vanno, provo a spiegarti per evitare di dare la "pappa pronta", visto che nessuno scrive codice "per conto terzi", e per farti imparare qualcosa in più visto che hai dichiarato di essere novizio :wink: :

long point;
long timepoint = 2000;  // read the input on analog pin 0:

I valori di millis() sono "unsigned long", quindi devi usare questo tipo di variabili.
Poi nel loop:

  // Convert the analog reading (which goes from 0 - 1023) to a voltage (0 - 5V):
  float voltage = sensorValue * (9.0 / 1023.0);

Non mi è chiaro perché tu moltiplichi per 9 e dividi per 1023 (che dovrebbe essere 1024 comunque): in questo modo i valori da 0 a 1023 diventeranno valori da 0 a 9, non da 0 a 5V.

  delay (1000);
  while ( sensorValue <= 1.30) and  millis()- point>= timepoint);
  {digitalWrite (13, HIGH);
    point = millis(); 
  }

Qui dopo l'attesa di 1 secondo (perché?) entri in questo ciclo nel quale, perdonami, è tutto sbagliato.
Primo, perché il ciclo è vuoto in quanto hai messo un ";" dopo la condizione "while" quindi poiché non aggiorni mai "sensorValue" né "point" avranno sempre lo stesso valore quindi non uscirà mai (o uscirà sempre immediatamente, a seconda delle condizioni). Poi "and" dovresti scriverlo "&&".
Secondo, "sensorValue" è un valore intero, non sarà mai pari a 1.30 (forse intendevi "voltage", che hai calcolato ma che non usi mai?).
Terzo, se anche togliessi il ";" e quindi le istruzioni tra le graffe fossero il corpo del "while", se aggiorni continuamente "point" (ma perché non usi nomi in qualche modo significativi del loro scopo??) con millis(), la condizione "millis()-point" sarà sempre zero o poco più non sarà mai maggiore o uguale di "timepoint" che vale 2000 (2 secondi).
Quarto, una volta che hai posto HIGH al pin del LED non è necessaria continuare a porlo HIGH.

Veniamo quindi alla tua specifica richiesta:

Cosa intendi esattamente per "segnale" (ossia cosa hai collegato su A0 e quale tipo di segnale manda)? E per "non legge alcun segnale" cosa intendi? Che analogRead() sia zero? Che sia minore di un certo valore (es. 100 sul massimo 1023)? E che lo sia per un certo tempo (es. mezzo secondo)? Prova a spiegare meglio il contesto.

Per finire, una sola annotazione: questo aspetto, come tanti altri relativi all'implementazione di sistemi di controllo, si schematizzano meglio pensandoli con una cosiddetta "macchina a stati finiti". Ma ne parliamo magari meglio appena avrai chiarito le cose che ti chiedevo. :wink:

Il codice precedente è per una simulazione virtuale che ho costruito su Tinkercad dato che al momento non mi trovo fisicamente in laboratorio, quindi partirei di nuovo da capo nella spiegazione.

Cerco di spiegarmi al meglio utilizzano la componentistica utilizzata per l'effettivo sviluppo della funzione che desidero avere.

Utilizzo un ArduinoMega2560.
Al pin A0 ho collegato questo sensore allegando il link seguentemente al nome.
Interfacing ZMCT103C 5A AC Current Transformer Module with Arduino

Alimento questo sensore con il pin dei 5V di arduino e il gnd, ovviamente il cavo di out del sensore l'ho posto nel pin A0.

Questo sensore legge una corrente che attraversa il cavo di alimentazione di una lampadina ad incandescenza.
Essendo essa alimentata in corrente alternata nel serialplotter di arduino ho sia valori positivi che negativi. Ho ovviato al valore negativo facendo stampare sul seriale il contrario dei valori negativi. Tuttavia ho sempre degli istanti in cui il segnale passa per il valore 0 ed è qui che intendo dire di quando arduino non riceve segnale anche se, grazie a Voi, ho capito che il segnale lo riceve costantemente e che il valore in quel momento è 0.
Il - 2.89 del float è per sottrarre il valore di fondo, cioè tarando il sensore e misurando il segnale senza alimentare nessun carico il monitor seriale di arduino riporta questo valore che sottraggo per tarare il tutto a 0.
Al pin 12 ho collegato un relè che con questo attuale codice lo fa commutare ripetutamente in quanto il segnale passa per lo 0 in base alla frequenza di alimentazione.
Ribadisco che non mi occorre sapere il valore effettivo del segnale analogico ( anche se sarebbe più professionale), ciò di cui ho bisogno è quello di far rimanere attivo il pin del relè finché è presente il passaggio di corrente al carico.
In sostanza come ritardare il passaggio di HIGH e LOW del pin o, a mia idea far rilevare il tempo di misurazione del valore 0 e cronometrarlo in modo da far commutare dopo un certo periodo di tempo di valore costante ovviamente maggiore della frequenza e anche di qualche secondo per l'utilizzo effettivo del circuito finale.
Questo Sketch è preso tra gli esempi di quelli preimpostati nel programma e modificato da me.

Altrimenti pongo questa semplice domanda.
Dove posso imparare a far partire il conteggio del tempo tramite arduino in base ad una certa condizione? ( Ho visto dei tutorial e letto dei siti su come utilizzare arduino come cronometro facendolo partire non all'accensione di esso ma in caso di una certo evento, qui il tempo di durata del valore 0, cioè quando il carico non viene più alimentato)

void setup() {
  Serial.begin(9600);
  pinMode (12, OUTPUT);
}
void loop() {
  int sensorValue = analogRead(A0);
  float voltage = (sensorValue * (5.0 / 1024.0)- 2.89);
  if (voltage < 0){Serial.println (!voltage);
  } else {
  Serial.println(voltage); 
  }
  if (voltage > 0.10) {digitalWrite (12, HIGH);
  } else digitalWrite (12, LOW);
}

Allora le domande sono troppo per rispondere in un post, ma ci arriveremo passo passo.
Premessa non ho quel modulo misuratore di corrente, ma sono competente in materia elettronica e programmazione e questo mi porta a pensare che la d.d.p. sul pin A0 deve essere nel range 0÷5V, quando non passa corrente dovresti avere circa 2.5V questo perché non è possibile applicare tensione inferiore al riferimento GND.

Quindi ad esempio durante la semionda positiva la tensione cresce da 2.5V e sale fino al picco e ritorna giù passando per 2.5V e ora tocca alla semionda negativa.

Direi di visualizzare nel serial monitor con print il valore grezzo restituito da analogRead(A0), con corrente che scorre e senza.

Se non mi sbaglio la cosa si potrebbe semplificare molto aggiungendo un condensatore un diodo e un'altro condensatore per raddrizzare le semionde positive e utilizzare quindi un pin digitale anziché analogico. Ma per adesso rimaniamo con l'analogico e vediamo in base ai dati che visualizzi sul serial monitor di capirci qualcosa di più.

void setup() {
     Serial.begin(115200);
     
}

void loop() {
     uint16_t rawA0 = analogRead(A0);
     Serial.println(rawA0);
}

Copia dal serial monitor e incolla nel post usando il tag CODE per formattarlo meglio.

Ciao.

Ok. Ma questo è un sensore di corrente ossia legge e fornisce un valore proporzionale alla corrente (da cui puoi ricavare la potenza in Watt conoscendo la tensione), e NON la tensione ossia la sinusoide CA, quindi non mi è chiaro perché tu stia parlando di segnale con valori negativi (che tra l'altro su un pin di Arduino non puoi avere, visto che la tensione può essere solo TTL ossia tra 0 e 5 V).
Io ho già avuto a che fare con sensori di corrente, e quindi nel tuo caso, sempre se ho capito bene visto che non ho mai usato esattamente quel sensore, ti basta sapere se c'è assorbimento nel carico collegato al cavo di fase che hai fatto passare attraverso la sua bobina.

Detto questo, e visto che dici che non ti interessa quantificare la corrente, se non c'è assorbimento sul pin avrai un valore pari a zero (magari ammetti un minimo di tolleranza, diciamo un valore inferiore a 10 significa "nessun assorbimento") e questo sarebbe il tuo "mancanza di segnale". In sostanza, sei proprio sicuro che su A0 tu abbia un valore diverso da zero quando non c'è corrente? Sicuro che non si tratti semplicemente di tarare correttamente il sensore (vedo che c'è un trimmer...)?

Perché se è come penso, per sapere se c'è assorbimento ti basta fare una "if (analogRead(A0) > SOGLIA)" (dove "SOGLIA" è una costante che rappresenta il valore di soglia oltre la quale consideri presente il carico, nell'esempio varrebbe 10). Una volta chiarito questo aspetto, poi passiamo alle altre questioni più di implementazione (oltre che di correttezza della sintassi del linguaggio che evidentemente ancora non "mastichi").

Chiarisci e vediamo come proseguire.

Una cosa del genere, però, sarebbe da fare in analogico...

Comunque: leggi continuamente il valore calcolando massimo e media e vai a vedere quando la differenza tra massimo e media supera una soglia prestabilita.

Per il momento vi ringrazio dei consigli. Riprenderò la discussione non appena avrò assimilato il tutto e testato le funzioni consigliate e, nel caso, insorgono altri dubbi. Grazie infinite davvero.

Scusa ma non ha molto senso, il sensore non ha un valore di fondo, è il suo valore normale quando non c'è corrente, dovrebbe essere pari a metà alimentazione, quindi circa 2,5 Volt, che con un carico collegato oscilleranno tra 0 e 5 Volt a seconda della corrente assorbita.
Se non ti interessa misurare l'assorbimento ma vuoi solo sapere se c'è un carico collegato tutto quello che devi fare è controllare che il valore dell'ADC sia (circa) 512, diciamo tra 500 e 525, in quel caso il carico non è collegato. Qualsiasi valore diverso, che sia più alto o più basso, ti indicherà il carico collegato.

Ciao, Ale.

Scusa la mia curiosità, ma tu hai (ed hai usato) quel tipo di sensore?
Perché io per un data logger che ho fatto per il mio fotovoltaico, con un sensore come QUESTO e la libreria EmonLib semplifico tutta la fase di lettura della corrente e calcolo della relativa potenza:

// ---------------------------------------------
// POTENZA EROGATA
// ---------------------------------------------
int getWatt() {
  // Calcolo della corrente e potenza (numero di campioni)
  double Irms = emon1.calcIrms(5000);
  // Calcolo la potenza (Corrente*Tensione=Potenza)
  return (Irms*230);
}

per cui alla fine basterebbe fare:

bool PresenzaCarico = (getWatt() > 10);
if (PresenzaCarico) {
  // carico presente, fai qualcosa
} else {
  // carico non presente, fai altro
}

Ora, non so quel sensore specifico che l'OP possiede quale tipo di output fornisca, ma ho l'impressione che, sempre se compatibile e se il segnale che porta su A0 sia analogo a quello del sensore che uso io, sia più utile usare quella libreria per semplificare ogni discorso al nosrto amico, visto anche che deve "digerire" ancora questioni di base come il linguaggio C...:wink:

No, ma cercando ho trovato questo schema che, perlomeno per i componenti impiegati, dovrebbe somigliare molto a quello dell'OP.
Oltretutto guardando meglio, mi sa che ho scritto l'ennesima castroneria, perchè perlomeno in quello schema l'uscita è accoppiata in alternata, quindi senza carico dovrebbe avere 0, non 2,5 Volt.

Si, forse potrebbe semplificargli la vita, anche perchè, una volta calibrato il sensore, potrebbe anche avere gli assorbimenti corretti senza fare tanti calcoli.

Ciao, Ale.

Lo zero va fatto sul valore medio.

@Datman lascia perdere, aspettiamo che l'OP ci risponda, potrebbe bastargli usare la Emonlib che fa tutto lei e non ci si sbatte né con la calibrazione né con i valori di zero.

... prende la pappa fatta e non impara nulla. Ok.

@Datman non fare battute per favore, usare una libreria non è "prendere la pappa fatta", e nel caso dell'OP che ha problemi anche a comporre un ciclo while mi pare inutile fargli sbattere la testa con considerazioni sulla corrente RMS ed onda sinusoidale, non ti pare?

Hai perfettamente ragione ti ringrazio per volermi non complicare ma aiutarmi a tirare fuori il meglio che posso.
Tuttavia sono ancora ben lontano dal tradurre tutto ciò che scrivete. Fare una semplice media, o meglio farla fare ad Arduino, per me significa ancora dialetto aramaico da tradurre in arabo mandarino :smile: