AAA: cercasi spiegazione codice per "Oscilloscopio" con arduino

//clipping indicator variables
boolean clipping = 0;

//data storage variables
byte newData = 0;
byte prevData = 0;
unsigned int time = 0;//keeps time and sends vales to store in timer[] occasionally
int timer[10];//storage for timing of events
int slope[10];//storage for slope of events
unsigned int totalTimer;//used to calculate period
unsigned int period;//storage for period of wave
byte index = 0;//current storage index
float frequency;//storage for frequency calculations
int maxSlope = 0;//used to calculate max slope as trigger point
int newSlope;//storage for incoming slope data

//variables for decided whether you have a match
byte noMatch = 0;//counts how many non-matches you've received to reset variables if it's been too long
byte slopeTol = 3;//slope tolerance- adjust this if you need
int timerTol = 10;//timer tolerance- adjust this if you need

//variables for amp detection
unsigned int ampTimer = 0;
byte maxAmp = 0;
byte checkMaxAmp;
byte ampThreshold = 30;//raise if you have a very noisy signal

void setup(){
  
  Serial.begin(9600);
  
  pinMode(13,OUTPUT);//led indicator pin
  pinMode(12,OUTPUT);//output pin
  
  cli();//diable interrupts
  
  //set up continuous sampling of analog pin 0 at 38.5kHz
 
  //clear ADCSRA and ADCSRB registers
  ADCSRA = 0;
  ADCSRB = 0;
  
  ADMUX |= (1 << REFS0); //set reference voltage
  ADMUX |= (1 << ADLAR); //left align the ADC value- so we can read highest 8 bits from ADCH register only
  
  ADCSRA |= (1 << ADPS2) | (1 << ADPS0); //set ADC clock with 32 prescaler- 16mHz/32=500kHz
  ADCSRA |= (1 << ADATE); //enabble auto trigger
  ADCSRA |= (1 << ADIE); //enable interrupts when measurement complete
  ADCSRA |= (1 << ADEN); //enable ADC
  ADCSRA |= (1 << ADSC); //start ADC measurements
  
  sei();//enable interrupts
}

ISR(ADC_vect) {//when new ADC value ready
  
  PORTB &= B11101111;//set pin 12 low
  prevData = newData;//store previous value
  newData = ADCH;//get value from A0
  if (prevData < 127 && newData >=127){//if increasing and crossing midpoint
    newSlope = newData - prevData;//calculate slope
    if (abs(newSlope-maxSlope)<slopeTol){//if slopes are ==
      //record new data and reset time
      slope[index] = newSlope;
      timer[index] = time;
      time = 0;
      if (index == 0){//new max slope just reset
        PORTB |= B00010000;//set pin 12 high
        noMatch = 0;
        index++;//increment index
      }
      else if (abs(timer[0]-timer[index])<timerTol && abs(slope[0]-newSlope)<slopeTol){//if timer duration and slopes match
        //sum timer values
        totalTimer = 0;
        for (byte i=0;i<index;i++){
          totalTimer+=timer[i];
        }
        period = totalTimer;//set period
        //reset new zero index values to compare with
        timer[0] = timer[index];
        slope[0] = slope[index];
        index = 1;//set index to 1
        PORTB |= B00010000;//set pin 12 high
        noMatch = 0;
      }
      else{//crossing midpoint but not match
        index++;//increment index
        if (index > 9){
          reset();
        }
      }
    }
    else if (newSlope>maxSlope){//if new slope is much larger than max slope
      maxSlope = newSlope;
      time = 0;//reset clock
      noMatch = 0;
      index = 0;//reset index
    }
    else{//slope not steep enough
      noMatch++;//increment no match counter
      if (noMatch>9){
        reset();
      }
    }
  }
    
  if (newData == 0 || newData == 1023){//if clipping
    clipping = 1;//currently clipping
    Serial.println("clipping");
  }
  
  time++;//increment timer at rate of 38.5kHz
  
  ampTimer++;//increment amplitude timer
  if (abs(127-ADCH)>maxAmp){
    maxAmp = abs(127-ADCH);
  }
  if (ampTimer==1000){
    ampTimer = 0;
    checkMaxAmp = maxAmp;
    maxAmp = 0;
  }
  
}

void reset(){//clean out some variables
  index = 0;//reset index
  noMatch = 0;//reset match couner
  maxSlope = 0;//reset slope
}


void checkClipping(){//manage clipping indication
  if (clipping){//if currently clipping
    clipping = 0;
  }
}


void loop(){
  
  checkClipping();
  
  
  if (checkMaxAmp>ampThreshold){
    frequency = 38462/float(period);//calculate frequency timer rate/period
  
    //print results
    Serial.print(frequency);
    Serial.println(" hz");
  }
  
  delay(100);
  
}

Salve!
Da premettere che sto lavorando a un progetto un po' complesso per le mie conoscenze, però vorrei tanto capire questo codice in modo da poterlo applicare bene nel mio piccolo progettino!
Se qualche anima pia potrebbe mettersi con pazienza e spiegare ne sarei molto grato! Grazie!

In particolare mi servirebbe avere più input, al posto di uno! Qualche idea?

Fammi capire ... tu posti il codice così senza buongiorno, grazie, senza spiegazioni ..... che dovremmo fare? non ho capito

In particolare mi servirebbe avere più input, al posto di uno!

da questo con punto esclamativo che dovremmo comprendere? qualsiasi atmel ha + di 1 input ...

Il problema del codice è che abilita l'input A0 e disabilita gli altri AI, scusa se non mi sono espresso bene.

A me servirebbero più input analogici che mi calcolano la frequenza contemporaneamente, è fattibile?
Poi se possibile vorrei capire un po' il codice, vorrei imparare!

@pablos
No, per sbaglio ho scritto nel codice la domanda! Sbagliando pure il potrebbe! :-[ :-[ :-[

Mi cito:"
Salve!
Da premettere che sto lavorando a un progetto un po' complesso per le mie conoscenze, però vorrei tanto capire questo codice in modo da poterlo applicare bene nel mio piccolo progettino!
Se qualche anima pia potesse mettersi con pazienza e spiegare ne sarei molto grato! Grazie!" :grin: :grin:

Bravo, così va meglio.
Tu prima chiede "Come sta tua moglie, tua famiglia, tuoi figli mangiano, tutto bene? (Lezioni di cioccolato) :slight_smile:
Un po' di cortesia fa piacere!

Per cambiare ingresso devi modificare i primi 4 bit del registro ADMUX.
Vedi datasheet sez. 24.9.1.

Quindi se volessi aggiungere alla misurazione un altro input dovrei semplicemente cambiare il numero di bit di ADMUX?

Il mio obiettivo è quello di avere più letture, se questo mi serve per cambiare solo il pin da A0 ad A1 mi è poco utile ai fini del progetto, anche se mi è utile per sapere.. (scusate l'errore, non ho proprio atto caso al fatto che avevo scritto dentro alla stringa code..)

Aggiungendo un lettura dimezzi la frequenza di acquisizione.

Comunque molti sketch sugli oscilloscopi usano direttamente la analogread, senza star li a maneggiare i registri.

Clipping deve essere volatile.
Tigli il serial.print dalla routine dell'interrupt.
Cerca di snellire la routine.

p.s. Mi sembra un frequenzimetro più che un oscilloscopio.

In quanto alla precisione? Questo che ho provato mi sembrava abbastanza preciso, altri con più input sarebbero tanto precisi?

Per come è strutturato lo sketch credo che potresti avere un funzionamento preciso solo un ingresso alla volta perché la campionatura viene fatta in continuo dal pin usato come ingresso.

Giovicavalla:
Il problema del codice è che abilita l'input A0 e disabilita gli altri AI, scusa se non mi sono espresso bene.

A me servirebbero più input analogici che mi calcolano la frequenza contemporaneamente, è fattibile?
Poi se possibile vorrei capire un po' il codice, vorrei imparare!

E il soggeto continua senza un Ciao. Sei allergico alle buone maniere?

Ciao Uwe
Moderatore.

Ciao! Scusate tutti ma non ci sono proprio abituato ai forum!

Ora chiedo, è quindi possibile ottenere una precisione nella misurazione della frequenza su tutti i pin analogici?

Grazie, ciao!!

Perché pin analogici. se vuoi misurare solo la frequenza non servono pin analogici; vanno bene anche digitali.

Di che frequenze stiamo parlando?
Ciao Uwe

Ciao! Si tratta di un segnale prelevato da un piezoelettrico e preamplificato con un TL072..

Ciao!

A nessuno viene in mente nulla??

Hola!

Forse ho avuto un'idea, anche se non so se funge: un 74HC4051P?? Secondo voi potrebbe funzionare oppure è un idea troppo campata in aria? E se si, come faccio a richiamare la funzione per leggere ogni volta che cambio pin d'ingresso nell'integrato in questione??

Ciao, Giovanni