[Tone]: trovare fronte positivo dell'onda quadra

Salve ragazzi,
ho creato un segnale ad onda quadra utilizzando la funzione Tone.
Sarei interessato a trovare il fronte positivo di questo segnale in modo da poter svolgere una determinata azione ogni qualvolta avvenga la transizione.

Non riesco a capire come mai la condizione dell’if non si verifica mai e il LED di prova che ho collegato rimane sempre acceso.

#include <Wire.h>

void setup() {
  pinMode(3, OUTPUT);
  pinMode(13, OUTPUT);
  digitalWrite(13,LOW);
  tone(3,1000);
}

void loop() {
  
  byte prevValue=digitalRead(3);
  while(!(digitalRead(3)==1 && prevValue==0))
  {
    if(digitalRead(3)==1 && prevValue==0)
    {
      digitalWrite(13,LOW);
      break;
    }
    else
    {
      prevValue=digitalRead(3);
      digitalWrite(13,HIGH);
    }
  }
}

Grazie a tutti.

Sul pin 3 puoi usare l'interrupt in questo modo

attachInterrupt(digitalPinToInterrupt(3), tuaFunzione, RISING);

quando rileva il fronte di salita richiama la funzione "tuaFunzione", li cambi una variabile booleana che usi più o meno così nel loop principale:

digitalWrite(13,tuaVariabileBooleana);

La funzione attachInterrupt va inserita nel setup o nel loop?

Dai però neanche sbattersi a cercare nel reference o almeno su google... https://www.arduino.cc/reference/en/language/functions/external-interrupts/attachinterrupt/

Sinceramente ci sono da ieri cercando di fare questa semplice cosa. Sarò scarso, ma almeno su Google le cose provo a cercarle. Avevo semplicemente già provato ad utilizzare l’interrupt, ma senza successo.
Motivo per cui ti ho chiesto dove posizionare quella funzione.
Comunque, provando ad adattare il mio codice ottengo questo, ma continua a non funzionare e non mi spiego il perchè.
Forse è dovuto al fatto che uso un pin prima come output e poi come input.

#include <Wire.h>
volatile byte state = LOW;
void setup() {
  pinMode(3, OUTPUT);
  pinMode(13, OUTPUT);
  digitalWrite(13,state);
  tone(3,1000);
  pinMode(3,INPUT_PULLUP);
  attachInterrupt(3,function,RISING);
}

void loop() {
  digitalWrite(13,state);
}

void function()
{
  state=HIGH;
}

Si, non avevo fatto caso al doppio uso, non puoi usare la tone sul solito pin che poi andrai a leggere, sposta la tone su un'altro pin PWM e collegalo con una resistenza al pin di input

Dovrei semplicemente collegare il pin 3 con un altro pin pwm (ad esempio il 5) usando semplicemente una resistenza? La resistenza serve per evitare il cortocircuito giusto e quindi non posso usare un semplice wire?

attachInterrupt() non vuole il numero del pin come primo parametro, devi usare la funzione digitalPinToInterrupt().

Grazie della correzione, ma il problema rimane. Probabilmente, l'unica soluzione è collegare i due pin.

Togli il "probabilmente" :)

Mi sai dire se posso collegare i due pin direttamente senza usare nessuna resistenza? In questo momento non ne ho.

Se stai attento a non mettere il pin 3 in output, certo.

Ho collegato i pin 3 e 5 mediante un wire e cambiato il codice in questo modo:

#include <Wire.h>
volatile byte state = LOW;
void setup() {
  pinMode(5, OUTPUT);
  pinMode(13, OUTPUT);
  digitalWrite(13,state);
  tone(5,1000);
  pinMode(3,INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(3),function,RISING); 
}

void loop() {
  digitalWrite(13,LOW);
}

void function()
{
  state=HIGH;
}

Grazie a tutti dell’aiuto, ma purtroppo non funziona neanche in questo modo.

Unica cosa che fa la loop è tenere basso il pin 13, se è basso allora funziona. Domanda: è basso?

Si rimane basso, ma io genero un segnale a onda quadra attraverso la funzione tone e uso anche l'interrupt per individuare i fronti di salita. Quindi mi aspetterei che il led si accendesse ogni volta che si verifica un fronte. Ho provato a mettere la funzione dell'interrupt dentro il loop, ma è lo stesso.

... ti rendi conto a che velocità gira il loop() nel quale tu comunque metti LOW il pin 13 ? Speri veramente di vedere qualche cosa ? Non solo, ma ... dove pensi di andare a scrivere HIGH su quel pin?

Direi che devi rivedere l'intera logica del programma, chiariti le idee su cosa vuoi VEDERE e ... se le frequenze sono quelle che leggo, magari ti serve anche un oscilloscopio per vedere qualche cosa di sensato !

Guglielmo

Ovvio che non vedi nulla, all'interno della isr semplicemente assegni HIGH a state, in questo modo non accendi nessun led. Devi aggiungere nella loop "digitalWrite(13,state);", però se poi non riporti state a LOW il led rimane acceso fisso, puoi aggiungere un delay(50) e subito dopo "digitalWrite(13,LOW)" in modo che il led emette dei lampeggi quando viene eseguita la tone, per provare falla durare almeno 1 secondo altrimenti non vedi lo stesso nulla con 5 ms di durata.

Nel loop al posto di LOW devi mettere la variabile state che setti nell'isr dell'interrupt, perché altriementi come pensi che il pin possa andare alto? Oltretutto al primo fronte di salita si accenderebbe e poi più nulla quindi devi, come detto da @gpb01, rivedere un po' la logica del programma. Consiglio: Intanto iniza a togliere LOW e mettere la la variabile, poi passa a gestire bene il resto. @astrobeed Se non erro la tone così impostata crea un onda quandra con fronte di salita ogni secondo quindi dovrebbe risucire a vedere il cambio dello satto del led, sbaglio?

fabpolli:
Se non erro la tone così impostata crea un onda quandra con fronte di salita ogni secondo quindi dovrebbe risucire a vedere il cambio dello satto del led, sbaglio?

Veramente quella tone(5,1000); genera un onda quadra a 1000 Hz sul pin 5 … vedi un po’ tu … :wink:

Guglielmo

gpb01: Veramente quella tone() genera un onda quadra a 1000 Hz ... vedi un po' tu ... ;)

Guglielmo

:-[ Ecco spiegato, avevo interpretato il secondo parametro in mS... :-[