Convertire un valore di tensione dal pin A0 in mBar

Buonasera a tutti e la prima volta che scrivo sul forum, chiedo aiuto in merito al codice da inserire per effettuare la conversione in mBar ricevuta sul pin A0 di un arduino1, di seguito riporto il codice che sto usando:

// C++ code
//
#include <LiquidCrystal.h>

int pressione = 0; 				//variabile per la conversione del valore in mBar

int analog = 0; 						//variabile per valore ADC 

float Bar = 0; 							//variabile per calcolo dei bar

LiquidCrystal lcd_1(2, 4, 13, 12, 8, 7); //imposto l'hardware dell'lcd

void setup()
{
  lcd_1.begin(16, 2); 					// Set up the number of columns and rows on the LCD.
  Serial.begin(9600); 					// inizializzo la seriale
  pinMode(A0, INPUT);					//imposto il pin A0 come input
  lcd_1.clear();						//pulisco lcd
  lcd_1.setCursor(0, 0);				//mando il cursore alla prima riga colonna 0
  lcd_1.print("pressure control"); 		// scrivo una frase di test
  Serial.println("Programma di prova");	// scrivo una frase sulla seriale
}

void loop()
{
  delay(2000); 					// ritardo stabilizzazione
  analog = analogRead(A0); 	//leggi il valore adc A0 e mettilo nella variabile analog
  float voltage= analog * (5.0 / 1023.0); 	//converto il valore della variabile analog in voltaggio
  Bar = (voltage-0.5)*3;  			//formula per convertire il valore da volt in bar
  Serial.print(analog);Serial.println(" dati grezzi");	//scrivi il valore in ingresso ADC
  Serial.print(voltage);Serial.println(" Volt");		//scrivi il valore della variabile volt
  //Serial.print(Bar*1000);Serial.println(" Bar");		//scrivi il valore della dei Bar
  int pressure = map (analogRead(A0),205,1023,0,30000); //imposto i valori di fondoscala e conversione da bar in mBar
  Serial.print(pressure);Serial.println(" mBar");	//scrivi il valore in mBar
}

Il programma funziona e mostra i valori correttamente, ma inserendo un valore di tensione relativo a 2 bar non riesco a centrare il valore, la sonda che utilizzo e industriale a 2 pin con valore di scala da 0 a 30bar, con i relativi mA da 4 a 20, tensione di alimentazione 12V, resistenza in parallelo da 250ohm e in serie una resistenza da 10k di protezione per il pin A0.
Per adesso e costruito tutto in modo virtuale sù thinkercad in attesa di realizzare il manometro via hardware sto testando il firmware.

Grazie per l'aiuto

Ti conviene presentarti, come da regolamento

Poi ne parliamo, del tuo problema

Faccio subito, mi chiamo Salvatore, sono perito Elettrotecnico/Elettronico e studio da non poco tempo arduino e raspberry pi ed a suo tempo le 16f876 della pic, del quale ho costruito un programmatore serio, ho anche costruito un computer basato su Z80, linguaggio Assembly/binario in Ram che riscrivevo con batteria tampone, ho conoscenza della saldatura e funzionamento dei componenti elettronici, da buon appassionato di elettronica studio nuovi sensori e componenti che mi capitano per le mani, in special modo i PLC, sensori di pressione, temperatura ed altro a livello industriale, quindi parliamo di un elevata precisione di lettura, spesso vado in difficoltà per il calcolo matematico e le formule, non ero una cima in matematica o magari per pezzi di codice che non comprendo bene come funzionino e quindi ho deciso di iscrivermi finalmente per rendermi partecipe della comunity, grazie e scusate, pensavo bastasse la presentazione del profilo

forse e dico forse ho trovato il problema, ma chiedo anche a voi che siete più esperti, semplicemente l'adc del arduino1 non riesce a leggere oltre il mV è quindi lo scarto e molto grande, tanto da farlo saltare con i valori, cambiando sonda al banco e inserendo i valori giusti legge perfettamente i mBar fino a 9bar, correggetemi se sbaglio

// C++ code
//
#include <LiquidCrystal.h>

LiquidCrystal lcd_1(2, 4, 13, 12, 8, 7); //imposto l'hardware dell'lcd

void setup()
{
  lcd_1.begin(16, 2); 					// Set up the number of columns and rows on the LCD.
  Serial.begin(9600); 					// inizializzo la seriale
  pinMode(A0, INPUT);					//imposto il pin A0 come input
  lcd_1.clear();						//pulisco lcd
  lcd_1.setCursor(0, 0);				//mando il cursore alla prima riga colonna 0
  lcd_1.print("pressure control"); 		// scrivo una frase di test
  Serial.println("Programma di prova");	// scrivo una frase sulla seriale
}

void loop()
{
  delay(1000);											 // ritardo stabilizzazione
  int analog = analogRead(A0); 							//leggi il valore adc A0 e mettilo nella variabile analog
  int voltage= analog * (5.0 / 1023.0); 				//converto il valore della variabile analog in voltaggio
  int pressure = map (analogRead(A0),286,1023,0,9000); //imposto i valori di fondoscala e conversione da bar in mBar
  Serial.print(analog);Serial.println(" dati grezzi");	//scrivi il valore in ingresso ADC
  Serial.println();										//inserisco uno spazio
  Serial.print(voltage);Serial.println(" Volt");		//scrivi il valore della variabile volt
  Serial.println();										//inserisco uno spazio
  Serial.print(pressure);Serial.println(" mBar");		//scrivi il valore in mBar
  Serial.println();										//inserisco uno spazio
  Serial.println("fine lettura");						//interrompo la lettura
  Serial.println();										//inserisco uno spazio
  lcd_1.clear();	//pulisco lcd_1
  lcd_1.setCursor(0,0);	//sposto il cursore alla riga 1 colonna 0
  lcd_1.print("pres. mBar");	//scrivo che la lettura è in mBar
  lcd_1.setCursor(0,1);	//sposto il cursore alla 2 riga colonna 0
  lcd_1.print(pressure); //scrivo il valore di pressure 
  
}

Buongiorno, blizzard
Benvenuto nella sezione Italiana del forum :slight_smile:

Cortesemente, leggi attentamente il REGOLAMENTO di detta sezione:
[REGOLAMENTO] Come usare questa sezione del forum
(... e, per evitare future possibili discussioni/incomprensioni, prestando molta attenzione al punto 15)
e poi, come da suddetto regolamento (punto 16.7), fai la tua presentazione IN CODA ALL'APPOSITA DISCUSSIONE:
Presentazioni nuovi iscritti: fatevi conoscere da tutti! (Part 2)
spiegando bene quali esperienze hai in elettronica e in programmazione, affinché noi possiamo conoscere la tua esperienza ed esprimerci con termini adeguati.

Grazie
Gianluca

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:

P.P.S.: Evitate di utilizzare la traduzione automatica fatta dal browser ... vi impedisce di capire la lingua della sezione dove andate a scrivere ...

1 Like

Fatto, grazie per le delucidazioni, il punto 15 credo sia veramente importante per i circuiti che vengono trattati

Se è int, non può contenere numeri reali, ma solo interi! Se metti 5000 anziché 5.0, ottieni la tensione in mV.
Inoltre, essendo solo valori positivi, dovrebbe essere unsigned:
uint16_t voltage_mV = analogRead(A0)/1023.0*5000;
ma puoi anche fare un'unica formula che legge direttamente la pressione.

E proprio quella che non riesco a inquadrare o trovare, leggendo varie discussioni in questo forum, ma in inglese, sono riuscito a risalire alla conversione di tensione in mBar, ma non riesco a trovare quella di lettura direttamente in mBar, appena posso cambio il codice in float e vedo come gira

La sensibilità in mV dell'ADC dipende dalla tensione di riferimento e dalla risoluzione in bit che come ben sappiamo è di soli 10 bit.

Se Vref = 5Vdc come di default significa che il valore minimo che puoi leggere è 5/1024 = 4mV.

Se non è sufficiente per i tuoi scopi devi giocoforza optare per un ADC con migliori caratteristiche oppure usare una tensione di riferimento più bassa e rivedere
il valore della resistenza che stai usando per fare la conversione 4-20mA

Su Arduino Uno la Vref interna è 1.1V quindi la resistenza dovrebbe essere di 55 Ohm ed avresti una sensibilità di 1mV circa.

Però ha una tolleranza abbastanza ampia...
Inoltre, abbassando la resistenza ottieni anche una variazione minore del segnale in ingresso, quindi non guadagni nulla.

1 Like

uint16_t pressione = (analogRead(A0)-205)*11;`
205, non 286!

1 Like

È il 286 che non riusciamo a capire

Comunque date le tolleranza dei vari componenti credo che serviranno un paio di variabili da tarare
O in alternativa un paio di trimmer da regolare

Viene dai 4mA di offset.

Non vedo come 4mA su 20 diventi 286 su 1023

Sì, infatti 4mA*250ohm=1V;
1/5*1024=205.

1 Like

Infatti cosa?
Infatti è sbagliato ?

Si giusto, la risoluzione dell'ADC rimane sempre 10 bit quindi in termini di gap in mBar la sostanza non cambia.

La risoluzione è comunque 1/1024.

Oltre al 286, anche il moltiplicatore è sbagliato

1 su 819

Potrebbe diventare 1 su 1024 solo pre trattando in analogico il segnale di ingresso