Sensore multisonda per umidità del terreno per ricerca di biologia vegetale

Come isolare più sonde di umidità del terreno collegate tramite CD4051 per evitare crosstalk e derive di tensione?

Ciao a tutti, premetto che sono un biologo che si diletta di elettronica molto basic e che sta usando ogni guida disponibile, ma a volte alcune cose che faccio non mi sono al 100% chiare proprio per la mancanza della base necessaria, comunque ho una necessità sperimentale a cui nessuno riesce a rispondere :sob:

sto lavorando a un progetto con Arduino Nano per mappare l’umidità del terreno in verticale, usando più sonde inserite nel suolo a distanza di ~2 mm. L’idea è ottenere una sorta di profilo della distribuzione dell’acqua quando irrigo dal basso. Mi serve in realtà sapere l'istante in cui l'acqua propaga fino a quel punto e magari avere una lettura abbastanza riproducibile da poter identificare un valore di umidità stabile.

Configurazione attuale

6 sonde puntiformi nel terreno.

Un CD4051BE come multiplexer per selezionare una sonda alla volta che verrà letta separatamente dalla stessa entrata analogica di Arduino (su entrate direttamente separate il crosstalk era terribile, usandone una aperta esclusivamente per una sonda alla volta sembra essere migliorato ma non perfetto).

Ogni sonda viene alimentata da un uscita digitale separata di Arduino tramite una resistenza da 1kΩ per la lettura su un PIN analogico tramite il cd4051.

Ogni sonda è collegata poi alla porta del CD4051 per la lettura tramite la porta in uscita, collegata tramite una resistenza di 1 kΩ ad A0 di Arduino. Ogni sonda è anche collegata tramite una resistenza da 100kΩ a terra per scaricare ogni residuo prima di passare alla lettura successiva.

La modifica della lettura avviene tramite la scarica verso un elettrodo di ritorno (GND) inserito nel terreno, uno per sonda a circa 2mm lateralmente alla sonda stessa per evitare che il segnale abbia un lag dovuto alla distanza sonda-gnd

Schema semplificato del wiring (una sonda rappresentativa, replicate le altre sul CD4051):

Sonda i (es. canale 0):
D8 --[1k]--o-----> X0 (CD4051)----->[1k]----->A0
|
[elettrodo attivo]
|
(terriccio)
|
[elettrodo di ritorno a gnd]

Teoricamente con letture separate da una lettura dummy e un pochino di delay (non troppo, mi servono letture veloci sul mezzo secondo in totale) dovrei riuscire a percepire l'arrivo dell'acqua tramite la diminuzione di resistenza del terreno come una diminuzione del readout ad a0.

Codice: (ho usato chatGPT per aiutarmi nella pulizia del codice e per avere una media di letture consecutive, cosa che non riuscivo in alcun modo a fare)

const int pinS0 = 2;
const int pinS1 = 3;
const int pinS2 = 4;

const int analogPin = A0; // Z -> (10k) -> A0

const int probePins[6] = {8,9,10,11,12,13};

const int NPROBES = 6;
const unsigned int POWER_SETTLE_US = 500;   // microsecondi, regola 300-800
const unsigned int BETWEEN_SAMPLES_US = 200;
const int SAMPLES = 2;

void setup() {
  Serial.begin(115200);
  pinMode(pinS0, OUTPUT);
  pinMode(pinS1, OUTPUT);
  pinMode(pinS2, OUTPUT);

  // inizializza probe pins come INPUT (scollegati)
  for (int i=0;i<NPROBES;i++) pinMode(probePins[i], INPUT);

  analogRead(analogPin); // lettura di scarto iniziale
  delay(50);
  Serial.println("time_ms,p0,p1,p2,p3,p4,p5");
}

void selectMuxChannel(int ch) {
  digitalWrite(pinS0, ch & 1);
  digitalWrite(pinS1, (ch >> 1) & 1);
  digitalWrite(pinS2, (ch >> 2) & 1);
}

int readProbe(int idx) {
  // Assicuriamo che tutte le sonde siano spente
  for (int i=0;i<NPROBES;i++) pinMode(probePins[i], INPUT);

  // Seleziona canale
  selectMuxChannel(idx);

  // Accendi la sonda (OUTPUT HIGH via 1k)
  pinMode(probePins[idx], OUTPUT);
  digitalWrite(probePins[idx], HIGH);

  // Attendi il settling (microsecondi)
  delayMicroseconds(POWER_SETTLE_US);

  // Lettura di scarto
  analogRead(analogPin);

  long sum = 0;
  for (int s=0;s<SAMPLES;s++) {
    sum += analogRead(analogPin);
    if (s < SAMPLES-1) delayMicroseconds(BETWEEN_SAMPLES_US);
  }
  int value = sum / SAMPLES;

  // Spegni sonda e scollega return
  pinMode(probePins[idx], INPUT);
 
  return value;
}

void loop() {
  unsigned long t = millis();
  int values[NPROBES];
  for (int i=0;i<NPROBES;i++){
    values[i] = readProbe(i);
    delayMicroseconds(200); // piccolo gap tra canali
  }

  // stampa CSV
  Serial.print(t);
  for (int i=0;i<NPROBES;i++){
    Serial.print(',');
    Serial.print(values[i]);
  }
  Serial.println();
  delay(1000);
}

Problemi osservati:

Crosstalk: quando irrigo dal basso, anche le sonde più lontane rispondono parzialmente come se fossero influenzate dall’acqua, mentre dovrebbero rispondere in ritardo anche perché io vedo dal lato il progredire dell'acqua e non arriva così in fretta all'ultima sonda. Alcune delle sonde (la seconda e le ultime due dal basso in particolare) cambiano molto anche quando fuori dal terreno collego direttamente gnd alla sonda per mandare la lettura a 0 come test di prova, cosa che non dovrebbe essere possibile assolutamente dato che senza il terreno non dovrebbe esserci nessun crosstalk.

Deriva a riposo: anche senza irrigazione, vedo un trend discendente lento dei valori (es. da 495 ADC a ~450 in 10 minuti). Questa cosa non capita sempre, su breadboard ogni tanto capitava, poi ho saldato tutto su una millefori e capita ancora, quindi non penso sia dovuto alla stabilità del collegamento.

Domanda:

Qual è il modo migliore per:

isolare le letture delle sonde (per ridurre il crosstalk tra ingressi del CD4051 e tra le sonde stesse),

stabilizzare le oscillazioni/derive del voltaggio, considerando che non posso usare buffer esterni al momento?

Ha senso usare un'alimentazione esterna, magari con un condensatore in Vin per stabilizzarla quando magari la lettura la fa oscillare? O magari mandare le sonde a un PIN digitale in LOW separato per ogni sonda invece che all'elettrodo di ritorno a gnd comune?

Accetto consigli sia sul circuito (resistenze di pull-down, modifiche al wiring, disposizione dell’elettrodo di ritorno, ecc.) sia a livello software (tempi di lettura, medie, ecc.).

Grazie in anticipo per ogni spunto!

Buongiorno e benvenuto nella sezione Italiana del forum,

cortesemente, come prima cosa, leggi attentamente il REGOLAMENTO di detta sezione, (... e, per evitare future possibili discussioni/incomprensioni, prestando molta attenzione al punto 15), dopo di che, come da suddetto regolamento (punto 16.7), fai la tua presentazione NELL'APPOSITA DISCUSSIONE (... quello che vedi in blu è un link, fai click su di esso per raggiungere la discussione) spiegando bene quali esperienze hai in elettronica e programmazione, affinché noi possiamo conoscere la tua esperienza ed esprimerci con termini adeguati.

Grazie,

Guglielmo

P.S.: Ti ricordo che, purtroppo, fino a quando non sarà fatta la presentazione nell’apposita discussione, nel rispetto del succitato regolamento nessuno ti risponderà (eventuali risposte o tuoi ulteriori post, verrebbero temporaneamente nascosti), quindi ti consiglio di farla al più presto. :wink:

Grazie mille, mi era totalmente sfuggito, mi ero concentrato troppo sulle informazioni per scrivere un messaggio comprensibile date le mie basse conoscenze di elettronica e mi sono dimenticato di presentarmi, rimedio subito!

1 Like

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.