Ingressi analogici che interferiscono l'uno con l'altro?

Credo che il mio post precedente no mi ero spiegato bene, ora riprovo

ho riscontrato un problema piuttosto strano durante l'utilizzo di due sensori e speravo in un aiuto. I due sensori di cui parlo sono i seguenti:

  1. Sensore di risposta cutanea galvanica (misurazione della conduttività della pelle) : Grove - GSR Sensor | Seeed Studio Wiki

  2. Sensore a impulsi per misurare la frequenza cardiaca (battiti al minuto, intervallo tra le battute, forma d'onda PPG)
    https://pulsesensor.com/

Quindi, il problema è il seguente:

quando collego i sensori agli slot analogici (GSR su A0 e sensore di impulsi su A2 in particolare), provo letture che sembrano suggerire che entrambi i flussi di dati provenienti dalla GSR e dal sensore di impulsi stanno interferendo l'uno con l'altro (cioè le letture di impulso influenzano le letture del sensore GSR) e ricevo valori anomanli se comparati con codici dei singoli sensori.
Sospetto che si tratti di un'interferenza all'interno di Arduino

Di seguito il codice che sto usando

#define USE_ARDUINO_INTERRUPTS false
#include <PulseSensorPlayground.h>

const int GSR=A0;
const int PULSE_INPUT=A2;

const int OUTPUT_TYPE = SERIAL_PLOTTER;
const int THRESHOLD = 550;  
int sensorValue=0;
int gsr_average=0;

byte samplesUntilReport;
const byte SAMPLES_PER_SERIAL_SAMPLE = 10;

/* load pulseSensor library */
PulseSensorPlayground pulseSensor;

void setup() {
  Serial.begin(115200);
  
  /* ===== Setting up the pulse sensor ===== */
  pulseSensor.analogInput(PULSE_INPUT);
  pulseSensor.setSerial(Serial);
  pulseSensor.setOutputType(OUTPUT_TYPE);
  pulseSensor.setThreshold(THRESHOLD);
  // Skip the first SAMPLES_PER_SERIAL_SAMPLE in the loop().
  samplesUntilReport = SAMPLES_PER_SERIAL_SAMPLE;
}

void loop() {

    /* ========== Collecting data from the GSR sensor ========== */
    long sum=0;
    //Average 10 measurements to reduce noise
    for(int i=0;i<10;i++) {          
      sensorValue=analogRead(GSR);
      sum += sensorValue;
      }
   gsr_average = sum/10;
 
  if (pulseSensor.sawNewSample()) {
    /*
       Every so often, send the latest Sample.
       We don't print every sample, because our baud rate
       won't support that much I/O.
    */
    if (--samplesUntilReport == (byte) 0) {
      samplesUntilReport = SAMPLES_PER_SERIAL_SAMPLE;

      /* outputs GSR readings along with pulse readings in the same line, separated by commas */
      pulseSensor.outputSample(gsr_average);
    }
  }
}

Il codice va racchiuso nei tag CODE e NON in quelli per le tabelle.

Per questa volta ho corretto io il tuo post, ma, cortesemente, per il futuro, presta più attenzione. Grazie.

Guglielmo

P.S.: NON esistono "interferenze interne" di Arduino ... sono sempre cose dovute alla scarsa conoscenza del funzionamento degli ingressi analogici delle MCU e quindi a cattiva programmazione :wink:

È possibile.
Il convertitore ADC del ATemga ha un condesatore S&H per memorizzare la tensione di misura durante la conversione.
Se la sorgente della tensione da misurare ha una resistenza interna troppo alta il condensatore S&H non viene caricato alla tensione analogica e cosí sembra che una tensione intfluisca l'altra.

Ciao Uwe

/* outputs GSR readings along with pulse readings in the same line, separated by commas */
      pulseSensor.outputSample(gsr_average);

Questa parte di codice dovrebbe dare errore in compilazione. Il metodo outputSample() non prende argomenti, almeno spulciando la libreria rapidamente non ho trovato questo metodo.

Dovresti stampare gsr_average con Serial.println(gsr_average) e poi stampare il valore di pulse sensor con
pulseSensor.outputSample()

Può essere che nel copia ed incolla del codice da IDE a forum c'è stato un problema?

Ciao.

uwefed:
Il convertitore ADC del ATemga ha un condesatore S&H per memorizzare la tensione di misura durante la conversione.
Se la sorgente della tensione da misurare ha una resistenza interna troppo alta il condensatore S&H non viene caricato alla tensione analogica e cosí sembra che una tensione intfluisca l'altra.

Ovvero, quanto già detto ...

gpb01:
... sono sempre cose dovute alla scarsa conoscenza del funzionamento degli ingressi analogici delle MCU ...

... se non si rispettano le specifiche date nei datasheet, può ovviamnete capitare di tutto :wink:

Oppure, può essere un uso non corretto di qualche libreria software, come sta facendo notare Maurotec ... ::slight_smile:

Guglielmo

Aggiungo solo un'altra cosa ... e' vero che ci sono piu ingressi analogici, ma il convertitore interno dovrebbe esere uno solo, multiplexato fra i vari ingressi utilizzati ... quindi credo sarebbe una buona cosa fare un paio di letture "da scartare" prima di quella da utilizzare ogni volta che si legge un diverso ingresso, per evitare anche la possibilita' di lettura incrociata ...

Non dimentichiamo che se sono state messe le resistenze di pull-up (da 20k, come suggerisce il data sheet) si crea un collegamento di 40k tra un ingresso e l'altro e anche questo influisce...

Uh?... Resistenze di pull-up su un segnale analogico?...
Comunque delle resistenze di pull-up hanno il terminale in comune forzato alla tensione di alimentazione, il che rende impossibili le interferenze.

Grazie a tutti
Studierò e proverò e se ne vengo a capo vi faccio sapere!

steve-cr:
Non dimentichiamo che se sono state messe le resistenze di pull-up (da 20k, come suggerisce il data sheet)

... perdona, mi sono riletto tutto il capitolo relativo all'ADC, capitolo 24, da pagina 246 a pagina 261 del datasheet DS40002061A (identificativo Microchip) e, in nessun punto trovo un suggerimento relativo a resistenze di pull-up sugli ingressi analogici (cosa che, per altro, avrebbe molto poco senso) ... puoi chiarire cosa intendevi? Parlavi forse degli ingressi digitali?

Guglielmo

P.S.: Non posso allegare le pagine estratte relative all'ADC perché ... fanno 38 MB, comunque il riferimento è l'ultimo datasheet :wink:

Forse si riferisce ai datasheet dei sensori.

Datman:
Forse si riferisce ai datasheet dei sensori.

Non credo ... ti allego gli schemi dei due sensori ... :wink:

Guglielmo

Schematic Prints.PDF (110 KB)

PulseSensorAmpd_-_Schematic.pdf (20.7 KB)

Ho provato a fare come diceva Marcotec ma niente da fare sono ancora in conflitto

Ho trovato questo codice (in allegato) che sembra funzionare o meglio a qualche buon anima su internet ha funzionato, ma non riesco a fare lo schematico perchè sembra non usare pin Analogici!! in poche parole non so come hanno collegato il tutto, linko anche il video del funzionamento.

Grazie a chi risponderà

gsr_pulsesensor_test.ino (9.08 KB)

dodden:
... ma non riesco a fare lo schematico perchè sembra non usare pin Analogici!!

... come no ? ? ? leggi bene il codice, riga 49:

int gsr = analogRead(sensorPin);

... legge il sensore tramite una analogRead() :wink:

Guglielmo

int pulsePin = 0;  // Pulse Sensor purple wire connected to analog pin 0
int potPin = 1;
int sensorPin = 2;
int gsr = analogRead(sensorPin);
int pot = analogRead(potPin);

Nella ISR:

Signal = analogRead(pulsePin);

Datman:
int pulsePin = 0; // Pulse Sensor purple wire connected to analog pin 0

... quello è un'altra cosa, per cui usa un ingresso analogico, ma il sensore è collegato al pin 2:

int sensorPin = 2;

Guglielmo

dodden: hai già visto QUI ? e QUI?

Guglielmo

Premesso che mi viene il mal di testa a cercare di interpretare un codice così incasinato (ossia indentato "ad minchiam", ma il Ctrl-T non lo conosce nessuno?), la prima cosa che mi viene in mente è anche questa: ma come sono esattamente i collegamenti hardware?

quello è un'altra cosa, per cui usa un ingresso analogico, ma il sensore è collegato al pin 2:

si si avevo notato che la lettura era in analogRead ma il pin di input non lo era, quindi provo a farlo così e vediamo che succede!

Un'ultima domanda il sensore che ho un GSR grove ha 4 uscite: rosso +, nero -, giallo e bianco
al pin 2 ci attacco il bianco o il giallo???

Sicuramente è una domanda stupida...

Grazie infinite

Scrivendo analogRead(0)
viene interpretato come analogRead(A0)
o l'IDE segnala errore?...
(zero in realtà viene da una variable int)
Dal sorgente non mi è chiaro: analogRead()