Go Down

Topic: "o simile": oscilloscopio da poveretti con Arduino (Read 116 times) previous topic - next topic

maubarzi

Ecco il codice del mio "o simile", cioè l'aggeggio che ho usato per fare le rilevazioni di questo thread.

E' scritto da un nabbo del C, quindi in modo molto semplice.

Scatta a trigger.
Nel setup mi salvo la lettura analogica di A0 e mi salvo 0 o 1024 come riferimento.
Quando la lettura differisce per più di 800 (TRIGGER_THRESHOLD) scatta il trigger che termina le letture e stampa l'output per essere visualizzato nel plotter seriale.
Poi rifaccio allo stesso modo una lettura di riferimento per il prossimo trigger.

Per ora non spiego altro così vedo se il codice risulta sufficientemente intuitivo ;)

Code: [Select]

// Per misurare una campionatura di BUFFER_SIZE - TRIGGER_START letture, aprire il monitor seriale e scommentare la seguente define.
// Alla fine della stampa dei campioni verrà stampata anche la durata di tale campionatura.
//#define PRINT_DURATION
#define BUFFER_SIZE 500
#define TRIGGER_START 100
#define TRIGGER_THRESHOLD 800
#define DELAY 30
//#define ZOOM 20 // Fattore di zoom della parte bassa. 20 = amplifica di 20 i valori fino al 5% (100/20). Usato per amplificare il comportamento vicino allo zero.
int data[BUFFER_SIZE] = {0};
int currBufferPosition = 0; // Indice per scrivere su un elemento del buffer circolare.
int triggerReference = 0; // Lettura campione, se una lettura si discosta più di DELTA_TRIGGER scatta il trigger.
int startTriggerPosition = -1; // Posizione iniziale del buffer con i dati buoni. All'attivazione del trigger inizia TRIGGER_START passi indietro rispetto alla posizione corrente del buffer. Questo per visualizzare anche i dati precedenti all'attivazione del trigger.
unsigned long microsStart = 0;
unsigned long microsStop = 0;

void setup() {
  Serial.begin(115200);
  pinMode(2, INPUT);
  triggerReference = analogRead(A0);
  if (triggerReference > 500) {
    triggerReference = 1024;
  } else {
    triggerReference = 0;
  }
}

void loop() {
  data[currBufferPosition] = analogRead(A0);
  if (startTriggerPosition < 0) {
    // Il trigger non è ancora scattato.
    if (abs(data[currBufferPosition] - triggerReference) > TRIGGER_THRESHOLD) {
      // Trigger scattato, ci salviamo la posizione di partenza 100 passi prima del trigger.
      startTriggerPosition = currBufferPosition + BUFFER_SIZE - TRIGGER_START;
      #ifdef PRINT_DURATION
        microsStart = micros();
      #endif
    }
  } else {
    // Il trigger è scattato, vediamo se abbiamo riempito il buffer.
    if (currBufferPosition + 1 % BUFFER_SIZE == startTriggerPosition % BUFFER_SIZE) {
      // Stampiamo il risultato
      #ifdef PRINT_DURATION
        microsStop = micros();
      #endif
      for (int i = 0; i < BUFFER_SIZE; i++) {
        Serial.print(data[(i + startTriggerPosition) % BUFFER_SIZE]);
        #ifdef ZOOM
          Serial.print('\t');
          if (i < DELAY) {
            // I primi elementi, fino al DELAY, non li stampiano per non inquinare la nuova lettura, perchè andrebbero a visualizzare i dati della parte finale della lettura.
            Serial.println(0);
          } else {
            // Spostiamo in avanti di DELAY letture in modo che la parte amplificata non si sovrapponga perchè stampata in ritardo.
            int lowZoom = data[(i + startTriggerPosition - DELAY) % BUFFER_SIZE];
            if (lowZoom > 1024/ZOOM) {
              lowZoom = 1024/ZOOM;
            }
            lowZoom = lowZoom * ZOOM;
            Serial.print(lowZoom);
          }
        #endif
        Serial.println();
      }
      // Resettiamo il trigger.
      startTriggerPosition = -1;
      // Prendiamo un nuovo riferimento da cui far scattare un nuovo trigger.
      triggerReference = analogRead(A0);
      if (triggerReference > 500) {
        triggerReference = 1024;
      } else {
        triggerReference = 0;
      }
      #ifdef PRINT_DURATION
        Serial.print("Durata campionatura = ");
        Serial.print(microsStop - microsStart);
        Serial.println(" uS");
      #endif
    }
  }
  currBufferPosition = (currBufferPosition + 1) % BUFFER_SIZE;
}
Nessuna buona azione resterà impunita!

Preistoria -> medioevo -> rinascimento -> risorgimento -> rincoglionimento!

maubarzi

Se si imposta
Code: [Select]

TRIGGER_THRESHOLD 630

e si trascura che il fondoscala è 1024 e non 1000 perchè si è pigri e si va per approssimazioni ad occhio (i meno pigri e più pignoli si possono fare i calcoli precisi precisi :P ),
abbiamo che la linea verticale dei primi 100 punti della grafica del plotter seriale cade esattamente ad evidenziare il tempo RC.
Siamo circa al 63% (date le approssimazioni pigre di cui sopra) della carica/scarica del condensatore.
Nessuna buona azione resterà impunita!

Preistoria -> medioevo -> rinascimento -> risorgimento -> rincoglionimento!

Go Up