Cos'è ElectroYou | Login Iscriviti

ElectroYou - la comunità dei professionisti del mondo elettrico

Misurazione periodo o frequenza con Arduino

Progetti, interfacciamento, discussioni varie su questa piattaforma.

Moderatori: Foto UtenteMassimoB, Foto Utentexyz, Foto UtenteWALTERmwp

1
voti

[1] Misurazione periodo o frequenza con Arduino

Messaggioda Foto Utentelorenrus » 24 apr 2020, 19:48

Ciao a tutti



quello che devo fare e andare a generare un onda quadra, ad esempio uscente dal pin 5 con la funzione TONE, poi quest'onda andrà in altri dispositivi e poi rientrerà sempre nella stesso Arduino, ad esempio nel pin 5. Quello che devo fare è CONFRONTARE L'ONDA IN USCITA E QUELLA IN INGRESSO E VERIFICARE CHE "COINCIDANO".



Per simulare il tutto per ora invio dal pin 4 e ricevo direttamente sul 5 senza andare negli altri dispositivi, come detto sopra.



Il codice è quello che inserisco di seguito. L'ultima funzione abilitata da Check_Wave deve essere completata, ma per la domanda che devo porre non è importante.



Ho usato la funzione Tone per generare l'onda quadra e la PulseInLong per rilevare i fronti sia positivo che negativo.



Le freq che interessano a me sono F1=115200 Hz e F2 = 1 MHz.



Allora fino alla freq di 50 kHz riesco ad ottenere dei valori diciamo accettabili ma oltre i 70 kHz mi escono dei valori assolutamente sballati.



Capisco che all'aumentare della freq la PulseIn/PulseInLong sarà sempre più messa sotto stress dato il periodo sempre più piccolo in cui si dovrà abilitare e disabilitare.



Ma essendo che io devo fare la misura che vi ho detto sopra come potrei fare ?



Questi valori sballati che mi escono da circa quella freq in poi è corretto dire che è un limite dell'arduino ?



Grazie

Codice: Seleziona tutto

float Periodo = 1;
unsigned long Periodo_Arrotondato;
unsigned long Mezzo_periodo_Pos;
unsigned long Mezzo_periodo_Neg;
unsigned long Periodo_Completo;
unsigned long Freq = 1000000;

bool Stamp           = true;
bool Load_Array      = true;
bool Check_Array_Min = false;
bool Check_Array_Max = false;
bool Check_Wave      = false;

int Array_Dimension = 40;
int Valori[40]; // Parte da zero quindi sono 20 elementi
int i = 1;

int Estremo_Inferiore;
int Estremo_Superiore = NULL;


void setup() {

  pinMode(5, INPUT);

  pinMode(4, OUTPUT);

  Serial.begin(9600);

  Periodo = (Periodo/Freq) * 1000000;
  Serial.println(Periodo,8);

  /* Se faccio diventare il float 8.68 in int lui me lo approssima per difetto a 8. */
  //Periodo_1 = Periodo;
  //Serial.println(Periodo_1);

  /* Allora uso la funzione ceil che me lo approssima al primo valore mafggiore dispoonibile quindi 9, in questo caso essendo che i valori di pulse che ricevo sono
   *  8 e 10 verifico che il mio periodo sia all'interno di questo intervallo
   */
   
  Periodo_Arrotondato = ceil(Periodo);
  //Serial.println(Periodo_1);
}


void loop() {
   
  if(Load_Array) {

    tone(4, Freq);

    delay(100);
   
    Mezzo_periodo_Pos = pulseInLong(5, HIGH);

    Mezzo_periodo_Neg = pulseInLong(5, LOW);
   
    Periodo_Completo = Mezzo_periodo_Pos + Mezzo_periodo_Neg;

    Serial.print("Periodo Completo = ");
    Serial.println(Periodo_Completo);

//    Serial.print("Mezzo Periodo Positivo = ");
//    Serial.println(Mezzo_periodo_Pos);
//
//    Serial.print("Mezzo Periodo Negativo = ");
//    Serial.println(Mezzo_periodo_Neg);
   
    if(i < (Array_Dimension + 1)) {

      Valori[i] = Periodo_Completo;
      delay(100);
   
      Serial.print("Valare nell'array = ");
      Serial.println(Valori[i]);

      Serial.print("Valare di i = ");
      Serial.println(i);

      if(i == Array_Dimension & Stamp) {

        Serial.println("Caricamento completato");

//        Serial.println(Valori[5]);
//        Serial.println(Valori[6]);
//        Serial.println(Valori[12]);
//        Serial.println(Valori[15]);
//        Serial.println(Valori[19]);
       
        Load_Array      = false;
        Check_Array_Min = true;
        Check_Array_Max = false;
        Check_Wave      = false;

        Stamp = false;
      }

      i ++ ;
     }
    }

  if(Check_Array_Min) {

    //noTone(4);
    int j;
   
    for(j = 1; j < Array_Dimension + 1; j++) {

      if(Estremo_Inferiore > Valori[j]) {

        Estremo_Inferiore = Valori[j];
      }
      else {

        // Solamente per la prima volta
        if(j == 1) {

          Estremo_Inferiore = Valori[j];
        }
      }

      Stamp = true;
    }
   
    if(j == (Array_Dimension + 1) & Stamp) {

      Serial.print("Estremo inferiore = ");
      Serial.println(Estremo_Inferiore);

      Load_Array      = false;
      Check_Array_Min = false;
      Check_Array_Max = true;
      Check_Wave      = false;

      Stamp = false;
    }
  }

  if(Check_Array_Max) {

    int j;
   
    for(j = 1; j < Array_Dimension + 1; j++) {

      if(Estremo_Superiore < Valori[j]) {

        Estremo_Superiore = Valori[j];
      }
      else { }

      Stamp = true;
    }
   
    if(j == (Array_Dimension + 1) & Stamp) {

      Serial.print("Estremo superiore = ");
      Serial.println(Estremo_Superiore);

      Load_Array      = false;
      Check_Array_Min = false;
      Check_Array_Max = false;
      Check_Wave      = true;

      Stamp = false;
    }
  }
 
  if(Check_Wave) {

    if(Estremo_Inferiore != Estremo_Superiore) {
     
      if(Periodo_Arrotondato > Estremo_Inferiore && Periodo_Arrotondato < Estremo_Superiore) {

        Stamp = true;
     
        if(Stamp) {

          Serial.println("ONDA QUADRA CORRETTA");

          Load_Array      = false;
          Check_Array_Min = false;
          Check_Array_Max = false;
          Check_Wave      = false;

          Stamp = false;
        }
       }
       else {

          if(Stamp) {

            //Serial.println("VERIFICARE L'ONDA QUADRA INVIATA");

            Stamp = false;
          }
       }
     }
     else {

       
     }
   }

}

Avatar utente
Foto Utentelorenrus
5 2
 
Messaggi: 31
Iscritto il: 30 ott 2018, 18:30

0
voti

[2] Re: Misurazione periodo o frequenza con Arduino

Messaggioda Foto Utentemarioursino » 24 apr 2020, 20:34

Da documentazione:

The timing of this function has been determined empirically and will probably show errors in shorter pulses. Works on pulses from 10 microseconds to 3 minutes in length.

Secondo me ti stai scontrando con un limite inferiore di tempo. A 1 MHz la vedo molto dura arrivare, anche con dei clock molto veloci sei già vicino l'ordine di grandezza dell instruction cycle (faresti difficoltà anche con micro "professionali" ad avere una risoluzione decente).

Forse ai 115.2k arrivi scrivendo a mano una routine.
Avatar utente
Foto Utentemarioursino
4.492 3 9 13
G.Master EY
G.Master EY
 
Messaggi: 1452
Iscritto il: 5 dic 2009, 4:32

0
voti

[3] Re: Misurazione periodo o frequenza con Arduino

Messaggioda Foto Utentelorenrus » 24 apr 2020, 22:20

Ciao e grazie per la risposta. Si infatti questa info poi l'ho letta. in ogni caso mi inizia a dare problemi da piu' o meno 70 kHz in poi.

In ogni caso stavo pensando di ovviare al problema in questo modo:

leggo lo stato del pin in cui mi arrivare l'onda quadra. Li avrò un tot di valori ad 1 ed un tot a 0. Faccio generare l'onda da tone per 1 sec ed in questo secondo leggo lo stato sul pin in questo modo:

Codice: Seleziona tutto


void loop() {

    if(millis() < 1000) {

      tone(4, Freq);

      delay(1000);
     
      state = digitalRead(5);
   
      if (state != oldstate) { //Se cambia
     
        c++; //Incremento
        oldstate = state;
     }
    }
    else {

      noTone(4);

      Serial.println(c);
    }
}



quello che vorrei fare con il codice è in pratica contare gli impulsi sia negativi che positivi perché ogni volta che sul pin ho un passaggio da 1 a 0, o viceversa, vuol dire che l'onda sta commutando. Io mi salvo il numero di commutazioni, o di impulsi nella variabile c.

Quindi sapendo che se F = 1Mhz, T= 1us vuol dire che in 1 sec avrò 1 milione di periodi da 1 us; convertendoli ad impulsi avrò 2 milioni di impulsi da 1us/2.

Per fare quello che ho detto secondo voi il segunete codice può andare ?

Altra domanda: quando millis() non è più < di 1 sec e poi chiamo la funzione noTone, quest'ultima è corretto considerarla che non fa più generare una forma d'onda uscente dal pin ?

Grazie
Avatar utente
Foto Utentelorenrus
5 2
 
Messaggi: 31
Iscritto il: 30 ott 2018, 18:30

1
voti

[4] Re: Misurazione periodo o frequenza con Arduino

Messaggioda Foto Utenteboiler » 24 apr 2020, 22:31

Dicci cosa vuoi fare (concretamente, quindi qual è l'applicazione) e vediamo di trovare una soluzione.
La strada che stai cercando di seguire ti porterà solo a delusioni.

Boiler
Avatar utente
Foto Utenteboiler
16,4k 5 7 13
G.Master EY
G.Master EY
 
Messaggi: 2912
Iscritto il: 9 nov 2011, 12:27

0
voti

[5] Re: Misurazione periodo o frequenza con Arduino

Messaggioda Foto Utentelorenrus » 24 apr 2020, 22:36

Ciao

quello che voglio fare è quello che riporto nel primo messaggio.

Devo inviare un'onda quadra e la devo ricevere e verificare che sia la stessa che ho inviato.

Comunque ho provato il codice dell'ultimo messaggio e mi conta correttamente il numero degli impulsi ovviamente fino a quando non salgo troppo con la freq e quindi non riesce ad incrementare la variabile c in modo corretto.

Grazie
Avatar utente
Foto Utentelorenrus
5 2
 
Messaggi: 31
Iscritto il: 30 ott 2018, 18:30

1
voti

[6] Re: Misurazione periodo o frequenza con Arduino

Messaggioda Foto Utenteboiler » 24 apr 2020, 22:41

lorenrus ha scritto:Devo inviare un'onda quadra e la devo ricevere e verificare che sia la stessa che ho inviato.

Questa non è un'applicazione. Questo è un tentativo di soluzione. O vuoi sapere se sono uguali perché è un quesito della Settimana Enigmistica?

Ad ogni modo...

Non sarà mai la stessa, questo è sicuro, già solo per il fatto che è andata da A a B.
Cosa vuoi sapere esattamente?
Se la frequenza è la stessa?
Se l'ampiezza è la stessa?
Quanto è l'angolo di fase?
Se ci sono armoniche che non erano presenti all'emissione?
Altro?
Una combinazione di tutti questi?

Sono problemi diversi con soluzioni diverse.

Boiler
Avatar utente
Foto Utenteboiler
16,4k 5 7 13
G.Master EY
G.Master EY
 
Messaggi: 2912
Iscritto il: 9 nov 2011, 12:27

0
voti

[7] Re: Misurazione periodo o frequenza con Arduino

Messaggioda Foto Utentelorenrus » 24 apr 2020, 22:44

Ovviamente si lo so che non saranno esattamente uguali.

Devo verificare la frequenza o il periodo e il duty cycle.
Avatar utente
Foto Utentelorenrus
5 2
 
Messaggi: 31
Iscritto il: 30 ott 2018, 18:30

0
voti

[8] Re: Misurazione periodo o frequenza con Arduino

Messaggioda Foto Utentemarioursino » 24 apr 2020, 22:45

Non mi torna una cosa comunque.. nell'ultimo loop tu hai un delay(1000), quindi campioni ogni secondo?
Avatar utente
Foto Utentemarioursino
4.492 3 9 13
G.Master EY
G.Master EY
 
Messaggi: 1452
Iscritto il: 5 dic 2009, 4:32

0
voti

[9] Re: Misurazione periodo o frequenza con Arduino

Messaggioda Foto Utentelorenrus » 24 apr 2020, 22:50

Scusa avevo dimenticato di toglierlo

Codice: Seleziona tutto

    if(millis() < 1000) {

      tone(4, freq);
     
      state = digitalRead(5); //read state
   
      if (state != oldstate) { //if state changes:
     
        c++; //increment counter
        oldstate = state; //and reset current state
     }
    }
    else {

      noTone(4);
      Serial.println(c);
      Stamp = true;
    }



Fino a 20kHz ottengp come valore di c = 39437 che è circa 40000 che sarebbe il numero di impulsi in 1 sec che ho con f = 20 kHz. Aumentando la freq inzia a dar problemi.

Grazie :)
Avatar utente
Foto Utentelorenrus
5 2
 
Messaggi: 31
Iscritto il: 30 ott 2018, 18:30

0
voti

[10] Re: Misurazione periodo o frequenza con Arduino

Messaggioda Foto Utentemarioursino » 24 apr 2020, 23:06

Quel codice mi lascia perplesso. Non capisco nemmeno come tu faccia ad ottenere quel valore corretto.

La velocità di quel loop, e quindi la "frequenza di campionamento", dipende da quante istruzioni contiene e da come il compilatore le traduce.
Avatar utente
Foto Utentemarioursino
4.492 3 9 13
G.Master EY
G.Master EY
 
Messaggi: 1452
Iscritto il: 5 dic 2009, 4:32

Prossimo

Torna a Arduino

Chi c’è in linea

Visitano il forum: Nessuno e 1 ospite