Leggere un sensore di pressione idraulica

Salve,
Vorrei calcolare la pressione idraulica necessaria a gonfiare un palloncino, di quelli che si usano per fare i gavettoni , riempiendolo con una siringa piena di acqua.
A tale scopo collegherei la siringa con il palloncino tramite un tubo collegato ad un sensore di pressione che ha al suo interno ha una membrana piezoelettrica (questo sensore si chiama trasduttore ). In pratica la pressione idraulica esercitata dall'acqua che esce dalla siringa deforma la membrana piezoelettrica, generando delle correnti elettriche che possono essere lette da arduino e trasformate in valori di pressione idraulica.
Ho scelto un sensore di quelli che usano i medici perchè mi serve un sensore monouso .
Il sensore viene alimentato tramite un alimetatore duale che genera correnti continue a +5V e a -5V .
Quando il sensore viene attivato dal flusso dell'acqua genera 2 segnali denominati :
Signal-
Signal+

Questi segnali possono essere letti da arduino, connettendo i 2 fili che portano tali segnali elettrici a 2 ingressi analogici di arduino per es. A4 ed A5.
Sono riuscito a collegare ad arduino il Display LCD del mio starter kit e vorrei usare tale display per visualizzare i valori di pressione.
Ci lavoro da tre mesi , ma sono riuscito solo a collegare il display ad arduino e far funzionare il sensore ( nel senso che, se ci collego un tester, il tester legge dei segnali elettrici )
Qualcuno potrebbe aiutarmi a trasformare i segnali del sensore in valori di pressione?
Sono Disperato =(

edit by mod: non usare il MAIUSCOLO, grazie.

un sensore di pressione ha una uscita differenziale che è quella del ponte di wheatstone su cui è basato.
Pertanto le due uscite - e + vanno collegate ad un ampli operazione che fa la differenza. In genere la
differenza è molto piccola e va contemporaneamente amplificata. Se ci sono 2 tubicini piccoli allora penso che sia
per aria e non credo che lo puoi collegare ai liquidi.

Grazie per avermi risposto e spero che mi possa aiutare.
In realtà si tratta di un sensore per liquidi con un solo tubicino.
Potresti spiegarmi meglio la faccenda dell'amplificatore?
Io credevo si potessero collegare i segnali + e - in uscita dal sensore agli ingressi analogici A 1,2 etc. di arduino come si fa nel caso di un barometro atmosferico di cui ho trovato lo schema e lo sketch al seguente links

http://coolarduino.wordpress.com/2013/04/10/barometric-atmospheric-pressure-arduino-project/

Per favore aiutami a capirci qualcosa.

Per primo serve sapere che sensore/trasduttore di pressione hai a disposizione.

Se é uno come suppone ntaraschi allora non serve un amplificatore operazionale ma un amplificatore instrumentale che puó essere comprato gia fatto oppure costruito da 3 amplificatori operationali con resistenze di precisione (parliamo del 0,1% e migliori).

Ciao Uwe

Caro Uwe,
Ho trovato un sensore presso una ditta italiana.
Tale sensore serve in urodinamica.
Potrai trovare più dettagli sul seguente link:
http://www.sunmedical.it/consumabile.lasso?idpresidio=29&seiquism=Monouso&sottoidcurr=10# .

Siccome so bene che non ci sono molti dettagli ho pensato di chiedere al servizio di assistenza della ditta che lo vende.
Mi è stato setto che il sensore funziona con corrente continua a 5V ed a -5V perciò ho comprato un alimentatore duale che mi fornisse i -5V.
Invece i segnali in uscita sono 2 :
Signal-;
Signal+.

Tale sensore è molto simile a quello della Pendo TECH.
LINK Pendotech:
http://www.pendotech.com/products/disposable_pressure_sensors/disposable_pressure_sensors.htm
I dettagli sullo spinotto sono ai links:

l'application note é al seguente link:

Spero che mi possa aiutare.

Grazie

Red

Non c'é mezza informazione.

Perché vuoi usare proprio quel sensore. Di cui non ricevi informazioni e il quale visto che é monouso non garantisce una risposta stabile nel tempo perché é fatto per essere usato per breve tempo.

Dalle mezze informazioni sembra che sia un trasduttore a ponte.
Non serve una alimentazione duale ma basta 5 V e massa; cosí eviti di dover gestiere tensioni negative. Poi usa un amplificatore tipo INA125 o simile.

Per la teoria vedi http://cerulean.dk/words/?page_id=42 Il trasduttore non usa estensimetri ma resistenze che cambiano valore in funzione della pressione (con qualche meccanica in mezzo).

Non chiedere ne il campo di misura neil fattore tra presione e tensione letta.

Ciao Uwe

Ciao, ma la necessità che sia monouso è importante? altrimenti sarebbe più facile usare un sensore pressione per liquidi che ti darebbero un segnale lineare 0-5V che potresti far leggere ad arduino senza troppi grattacapi. Se il problema viene dato da contaminazione del sensore o altro, potresto anche inventarti un sistema per isolare sensore dal liquido in esame, non so, magari mettendolo in un cilindro riempito di una sorta di gel impermeabile al liquido in oggetto, in linea di massima, dovrebbe misurare la pressione in maniera precisa a patto che non vi siano vuoti d'aria. Altra idea "meccanica" potrebbe essere, se le pressioni sono di una certa entità, mettere tra il sensore ed il liquido un pistone in un cilindro e tra sensore e pistone un'altro liquido, così si potrebbe trasmettere la stessa pressione senza contaminare il sensore. Ma anche il sensore rinchiuso dentro un palloncino/membrana riempita di liquido inerte per il sensore, potrebbe funzionare bene! come vedi, le soluzioni ci sono in caso il tu non riesca a far funzionare il tuo sensore, senza datasheet dettagliato vedo dura riuscire a fare delle letture attendibili e ripetibili.
:wink:

Purtroppo il sensore deve essere sterile e monouso perché serve per una metodica chirurgica che attualmente presenta solo il 70% di successo a causa del fatto che nessuno ha mai pensato di controllare la pressione.
Si tratta della mia tesi di specializzazione perciò avrei bisogno di aiuto per l'uso del sensore che, tra l'altro, sto comprando a mie spese.

Ok, adesso è più chiaro. Bene, quindi dovrai sperimentare con il link che ti ha dato uwefed, gli ho dato un'occhiata e sembra promettente per il tuo progetto. Purtroppo resta il fatto che al di la del far funzionare il circuito, devi per forza conoscere la curva caratteristica, ovvero, se lineare, devi conoscere che voltaggio esce alla sua pressione più bassa e quale a quella più alta, altrimenti, ti toccherà misurarle sperimentalmente e linearizzare il sensore in base a questi dati raccolti, ovviamente, per questo ti conviene prima applicare il circuitino che ti è stato indicato, e provare a misurare con arduino che voltaggio ne viene fuori almeno in due pressioni diverse, una bassa ed una alta, così potrai ottenere un risultato diretto mettendolo nella funzione map() come ti ho già spiegato in un' altro post.

Grazie al post di Uwe sono più tranquillo riguardo al circuito.
Sto già procurandomi i componenti .
Grazie ad hiperformance71 invece ho capito che dovrò usare la funzione map per leggere i valori in out dal sensore.
Credo di aver capito che cosa sia la funzione map.
In pratica devo conoscere i valori di tensione minima e massima in uscita e poi ridistribuirli secondo una qualche scala per ricavarne i valori pressori .
Così ho capito che devo assolutamente farmi dire, da chi mi sta vendendo il sensore, quali siano questi valori di tensione altrimenti credo che dovrò misurarli con un tester o qualcosa di simile.
Grazie di cuore a entrambi, però, ragazzi, spero che mi aiuterete ancora non appena avrò tutti i componenti . :slight_smile:

Non ci sono problemi, nel mio piccolo se ti posso dare una mano lo farò.

Per il sensore, ti serve conoscere la curva caratteristica, di solito i sensori hanno un'andamento lineare, per esempio, i sensori che conosco:

tensione / Pressione
20mV 200kpa
4300mV 2560kpa

se rappresenti questi dati in un grafico e metti nell'asse x la tensione in mV o in Volts e sull'asse Y i Kpa, otterrai una retta, alcuni sensori partono da quasi 0mV fino a 5000mV, e per questo che devi conoscere questi dati. Ovviamente, a te te li daranno con valori troppo piccoli (ricordo di aver letto 20mV max, quindi presumo che tutta la scala vada da 0 a 20mV richiederà per forza di un circuito amplificatore come quello indicato da UWE), quindi credo che ti toccherà comunque andare a misurare sul campo la sua curva caratteristica. Dovrai sapere in che ordine di pressioni ti serve misurare, il range min e max. 0-100kpa, 0-1000kpa ecc, dovrai procurarti un manometro adeguato per quel range di pressioni, creare una camera stagna dome mettere il tuo sensore collegato ed alimentato (se già Amplificato, potresti anche farlo misurare ad arduino a 10 bit ADC, avresti un minimo di 4,887mV a byte se non ricordo male). poi con qualche sistema, magari una siringa da "cavallo" pian piano innietti aria o liquido (dipende cosa devi misurare) nella camera stagna e segni che valore pressione leggi sul tuo manometro e che valore ADC su Arduino (o mV con un multimetro decente) poi continua ad applicare pressione e ad intervalli regolari continua a segnare questi dati fino a che non raggiungi la scala massima di pressione d'esercizio. A questo punto, crea una grafica XY e verifica che la linea sia lineare, se così fosse, potrai usare la funzione map, cosi:

esempio, ipotetici valori rilevati:

tensione pressione
20mV (=4 valore ADC) 10 kpa
3500mV (=716 valore ADC) 200kpa

a questo punto, la tua funzione map():

Pressione_Sensore_Kpa = map(Valore_ADC_Attuale, 4 , 716 , 10 , 200)

io per comodità, gli assegnerei ad ognì parametro un nome variabile/costante, esempio:

int Valore_ADC_Attuale; //quello che leggerai con analogRead(pin)
int Valore_ADC_min = 4; //valore ADC alla pressione minima,
int Valore_ADC_max=716; //valore ADC alla pressione massima,
int Press_Kpa_min=10; //pressione minima rilevabile
int Press_Kpa_max=200; //pressione massima rilevabile.

e poi rivedrei la funzione map così:

Pressione_Sensore_Kpa = map( Valore_ADC_Attuale, Valore_ADC_min, Valore_ADC_max, Press_Kpa_min, Press_Kpa_max);

Per convertire da mV a Valori ADC nel caso lo rilevassi con multimetro/oscilloscopio sarebbe:

Valore_ADC = mV * 1023 / 5000 mV o in volts: Volts * 1023 / 5 Volts

Ciao :wink:

mi sembra di aver letto che hanno un range da -7 a 75 psi e su uno dei PDF, realizzano un test affidabilità dopo che e stato sottoposto a due cicli in autoclave, e qui, hanno realizzato delle misurazioni da 5 a 75 psi (0,34 a 5,1 bar o 340 a 5100 kpa) per applicazioni "umane" mi sembra troppo il divario dei due valori, di conseguenza, si approfitterà si e no, il 30% della sua scala e quindi si avrà una precisione minore. Mi sembra difficile che nel corpo umano vi siano pressioni di 5 bar!! non è mica una F1 dell'era turbo!!! :D, Prima di comprare, ti consiglio di verificare range di pressione che ti servono e se il fabricante ha qualcosa più vicino ai tuoi dati pressori minimo e massimo, così avrai massima precisione.

Caro Hiperformance71,
Grazie per la disponibilità e per i suggerimenti.
Ho chiesto qualche dato al venditore .
Così mi ha inviato le seguenti specifiche elettriche:

• Tensione di eccitazione: 4 a 8 volts RMS
• Frequenza di eccitazione: DC a 5000Hz
• Spostamento di fase: meno di 5
• Impedenza di eccitazione: 300 a 400 ohms
• Impedenza del segnale: 250 a 350 ohms
• Simmetria: +/- 5%
• Accuratezza :AAMI/ANSI
• Sensibilità :5?V/V/mmHg
• Deriva dopo 5 minuti di funzionamento: < 2mmHg in 4 ore
• Deriva dovuto alla temperatura: 10mmHg massima
• Shock meccanico: Dopo 3 cadute da 1 metro di altezza

A parte il fatto che il sensore si rompe dopo almeno 3 cadute da un metro e che è sensibile ed accurato non ci ho capito molto , ma forse i dati sull'impedenza di eccitazione e sull'Impedenza del segnale potrebbero esser utili per capire qualcosa sull'amplificatore da usare.

Non saprei, l'unico dato che vedo utile è la sensibilita: 5uV/mmHg quindi per ottenere 1 bar dove dovrebbero esserci 760mmHg (se la memoria non mi fallisce) devremmo aver un output di 760 x 5uV = 3800uV = 0,0038 V, un po pochini! senza un circuito amplificatore non riuscireste a misurarlo con Arduino visto che la sua sensibilità/risoluzione a 10 bit gli consente un minimo di 4,887 mV ovvero 4887uV quindi al di sotto del suo minimo misurabile! A questo punto dovresti avere un circuitino amplificatore con un guadagno di almeno 100:1 o più. Su questo cedo la parola ai guru dell'elettronica, io in questo campo sono a digiuno o quasi.

Mi pare strano che tra tante caratteristiche, non ti abbiano fornito anche la scala minima e massimo ri pressioni misurabili, quindi devo prendere per buone quelle lette sul loro sito nei link postati da te, ovvero 5@75psi ovvero circa 0,3@5,1 bar (o 300 @ 5100mV)

Riguardo al probblema che gli ingressi analogici A4 e A5 di arduino non “leggono” correnti più basse di 5V credo di aver trovato la soluzione .
Infatti, oltre ad usare l’amplificatore suggerito da Uwe, ho trovato un sito che da il seguente suggerimento:
Arduino implementa, con la Libreria Wire fornita con l’IDE, la comunicazione I2C sulle porte A4 e A5 che sono Open-Collector a meno che, via software, non si abiliti il pull-up interno del microController.
Purtroppo Wire abilita il pull-up interno per cui il livello logico High sulle porte A4 e A5 si porta a 5V (valore di alimentazione di Arduino), creando una situazione di incompatibilità con i dispositivi che una logica di controllo con livello High inferiore a 5V.
Per ristabilire la compatibilità e necessario o modificare Wire, eliminando le istruzioni di attivazione del pull-up, oppure, più semplicemente, aggiungendo le istruzioni di disattivazione del pull-up nel proprio software di gestione del Modulo (se utilizza la libreria Wire) nel modo seguente:
subito dopo l’inizializzazione della libreria: Wire.begin();
inserire il seguente codice:
#ifndef cbi
#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
#endif
#if defined(AVR_ATmega168) || defined(AVR_ATmega8) || defined(AVR_ATmega328P)
// disattiva il pull-up interno
cbi(PORTC, 4);
cbi(PORTC, 5);
#else
cbi(PORTD, 0);
cbi(PORTD, 1);
#endif

Sfortunatamente non sono riuscito a inserire il codice nel software che uso perché il compilatore mi da un errore.
Perciò allego il software.

/*
 **************************  Barometric (atmospheric pressure) Arduino project *************************
 * LINK: http://coolarduino.wordpress.com/2013/04/10/barometric-atmospheric-pressure-arduino-project/
 *
 * Created for  Arduino UNO board: Anatoly Kuzmenko 10 April 2013 
 *                                 k_anatoly@hotmail.com
 *
 * SOFTWARE COMPILES USING Arduino 1.0.4 IDE (Tested on Linux OS only).
 * 
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute copies of the Software, 
 * and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
 * The above copyright notice and this permission notice shall be included
 * in all copies or substantial portions of the Software.
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY,  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
 *
 * Copyright (C) 2013 Anatoly Kuzmenko.
 * All Rights Reserved.
 ********************************************************************************************
 */
#include <Wire.h>
#include <Adafruit_MPL115A2.h>
#include <LiquidCrystal.h>

#define  ABS_MINIM     97.325         // absolute pressure minimum, kPa
#define  UPD_HISTR     7200           // update history interval in sec, 2 hours

LiquidCrystal lcd( 8, 9, 4, 5, 6, 7);

Adafruit_MPL115A2      mpl115a2;

         byte          prs_bars[8][8];// Custom characters array
         byte          prs_hist[8] = { 8, 11, 15, 7, 3, 0, 5, 8};  // Start-up "demo" data.

volatile uint8_t       sec_tick = 0;
         uint16_t      sec_cntr = 0;

         float         lpf_pres = 0.0;
         float         lpf_temp = 0.0;    
         
void setup(void) 
{
//  Serial.begin(115200);
  mpl115a2.begin();
  lcd.begin(16, 2);      

  for (uint8_t j = 0; j < 8; j++)  
  {
    for (uint8_t i = 0; i < 8; i++)
    {
      if ( i <= j )  prs_bars[j][7-i] = B11111;
      else           prs_bars[j][7-i] = B00000;
    }
  }  
  for ( uint8_t i = 0; i < 8; i++)
  {
    lcd.createChar(i, prs_bars[i]);
  }

  for ( uint8_t j = 0; j < 16; j++)          // Taking time for sensor to settle
  {
    print_Bars( j, j );
    delay(500);
  }

  lcd.clear();

    lcd.setCursor( 3, 0);
    lcd.print("*Magician*");
    
    lcd.setCursor( 5, 1);
    lcd.print("ver. 2a");

  delay(2000);

  lcd.clear();

  for ( uint8_t i = 0; i < 8; i++)
  {
    print_Bars( i, prs_hist[i]);             // Show nice picture
  } 

  lpf_pres = mpl115a2.getPressure();  
  lpf_temp = mpl115a2.getTemperature();  

 /* Set up TIMER 1 - 1 seconds tick-er */
  TIMSK1 = 0x00;
  TCCR1A = 0;
  TCCR1B = 0;
  TCCR1C = 0;

  TCCR1A =  ((1<<WGM11) | (1<<WGM10));       // Mode 15, Fast PWM
  TCCR1B =  ((1<<WGM13) | (1<<WGM12));       // Mode 15, Fast PWM

  TCCR1B |=  ((1<<CS10) | (1<<CS12));        // clk/1024 prescaling.
  OCR1A  = 15625;                            // 1 sec.

  TCNT1  = 0;
  TIFR1   |= (1<<TOV1); 
  TIMSK1  |= (1<<TOIE1);
}
 
void loop(void) 
{
 float    pressureKPA = 0, temperatureC = 0;    
 uint16_t temp;

  if (sec_tick) { 
    pressureKPA = mpl115a2.getPressure();  
//    Serial.print("Pressure (kPa): "); Serial.print(pressureKPA, 4); Serial.println(" kPa");
    temperatureC = mpl115a2.getTemperature();  
//    Serial.print("Temp (*C): "); Serial.print(temperatureC, 1); Serial.println(" *C");
    lpf_pres = 0.99 * lpf_pres + 0.01 * pressureKPA;
    lpf_temp = 0.99 * lpf_temp + 0.01 * temperatureC;

    lcd.setCursor( 9, 1);
    lcd.print( lpf_temp, 2);
    lcd.print("*C");
    
    lcd.setCursor( 9, 0);
    lcd.print( lpf_pres, 1);
    lcd.print("kP");
   
    if (sec_cntr > UPD_HISTR)
    {
      lcd.clear();
      for ( uint8_t i = 0; i < 7; i++)
      {
        prs_hist[i] = prs_hist[i+1];
        print_Bars( i, prs_hist[i]);
      } 
    temp = 2 *(lpf_pres - ABS_MINIM);
    prs_hist[7] = temp;
    print_Bars( 7, prs_hist[7]);

    sec_cntr = 0;
    }
  sec_tick = 0;
  }
}

ISR(TIMER1_OVF_vect)
{
  sec_tick = 1;
  sec_cntr++;
}

void print_Bars( uint8_t location, uint8_t value )
{
  if ( value < 8 )
  {
    lcd.setCursor( location, 1);  
    lcd.write(value);
  }
  else
  {
    lcd.setCursor(location, 1);
    lcd.write(7);
    lcd.setCursor(location, 0);
    lcd.write(value - 8);
  }        
}

Inserisco il codice dopo il comando #include <Wire.h>.

Presumo che il mio errore sia legato alla posizione nella quale inserisco il codice.
Qualcuno potrebbe aiutarmi?
Grazie in anticipo