INPUT ANALOGICO: Esempio POTENZIOMETRO (versione 17/05/2017)

Il potenziometro è una componente che permette di variare la resistenza durante il funzionamento in un circuito. Ha tre terminali: A e B si trovano alle estremità di una resistenza su cui si può spostare un contatto strisciante collegato al terminale C. Quando il contatto è ruotato completamente in senso antiorario, la corrente che entra da A non percorre alcun tratto della resistenza, poichè esce immediatamente su C (resistenza zero). Situazione opposta quando il contatto è ruotato completamente in senso orario: in questo caso la corrente che entra da A deve percorrere tutta la resistenza prima di uscire da C (resistenza massima). Ovviamente tra i due estremi sono possibili tutti i valori intermedi di resistenza.

Codice Sorgente A

Obiettivo progetto: Costruire un circuito che consenta la lettura del piedino C di un potenziometro tramite la porta analogica A0.

soluzione:

Costruire il seguente circuito (serve un potenziometro)

 

Ecco l'immagine del circuito

1° Versione A: mostro il valore letto ogni tot secondi

/* -----------------------------------------------------------------------------------
 Esempio creato partendo dal codice: ReadAnalogVoltage di pubblico dominio.
 Legge un input di tipo analogico sul pin 0 e mostra il risultato sul Serial Monitor
----------------------------------------------------------------------------------- */
void setup() 
{
  // inizializza la comunicazione seriale a 9600 bit per secondo:
  Serial.begin(9600);
}

void loop() 
{
	// Leggo l'input sul PIN A analogico 0 (valore da 0 a 1023)
	int sensorValue = analogRead(A0);
	// Converte la lettura (range da 0 a 1023) in voltaggi (0 - 5V):
	float voltage = sensorValue * (5.0 / 1023.0);
	// Stampo il voltaggio letto:
	Serial.print("Valore sul sensore: ");
	Serial.print(sensorValue);
	Serial.print(" - Voltaggio: ");
	Serial.println(voltage);
	delay(1000); // attendo un secondo
}
L'esecuzione mostra ogni secondo il valore letto sul potenziometro

1° Versione B: Una versione alternativa può essere ottenuta utilizzando la funzione map() :

/* -----------------------------------------------------------------------------------
 Esempio equivalente con la funzione map()

    long map(long x, long in_min, long in_max, long out_min, long out_max)

dove:
    x: valore da mappare in [out_min,out_max] - valore intero
    [in_min, in_max] : range di partenza - valori interi
    [out_min, out_max] : range di arrivo - valori interi
----------------------------------------------------------------------------------- */
void setup() 
{
  // inizializza la comunicazione seriale a 9600 bit per secondo:
  Serial.begin(9600);
}

void loop() 
{
	// Leggo l'input sul PIN A analogico 0 (valore da 0 a 1023)
	int sensorValue = analogRead(A0);
	// Converte la lettura (range da 0 a 1023) in voltaggi (0 - 5V) a 2 decimali:
	float voltage = (float)map(sensorValue, 0, 1023, 0, 500)/100;
	// Stampo il voltaggio letto:
	Serial.print("Valore sul sensore: ");
	Serial.print(sensorValue);
	Serial.print(" - Voltaggio: ");
	Serial.println(voltage);
	delay(1000); // attendo un secondo
}

2° Versione:

Supponiamo di voler invece mostrare il valore letto solo quando cambia. Avremo bisogno di una variabile globale (prec_sensorValue) che memorizzi l'ultima lettura in  modo da poterla confrontare con quella attuale. Se cambia la stampo altrimenti non faccio nulla. Ecco una possibile soluzione

Algoritmicamente corretta non raggiunge gli scopi prefissati a causa di piccole variazioni nella lettura dovute agli effetti di rimbalzo generati dai vari impulsi spuri tipici di una contattazione meccanica.

/* -----------------------------------------------------------------------------------
 Esempio creato partendo dal codice: ReadAnalogVoltage di pubblico dominio.
 Legge un input di tipo analogico sul pin 0 e mostra il risultato sul Serial Monitor
----------------------------------------------------------------------------------- */
int prec_sensorValue=-1;

// La routine di "setup" parte appena premo il tasto di reset:
void setup() 
{
  // inizializza la comunicazione seriale a 9600 bit per secondo:
  Serial.begin(9600);
}

// La loop routine continua a girare:
void loop() 
{
  // Leggo l'input sul PIN A analogico 0:
  int sensorValue = analogRead(A0);
  if (prec_sensorValue!=sensorValue)
  {
    // Converte la lettura (range da 0 a 1023) in voltaggi (0 - 5V):
    float voltage = sensorValue * (5.0 / 1023.0);
    // stampo il valore letto:
    Serial.print("Valore sul sensore: ");
    Serial.print(sensorValue);
    Serial.print(" - Voltaggio: ");
    Serial.println(voltage);
    delay(2000); // attendo 2 secondi
  }   
  prec_sensorValue=sensorValue;
}

Versione Finale: implementa un sistema antirimbalzo. La scelta del numero di cifre decimali in arrotonda() permette di eliminare le lievi variazioni che nel precedente programma determinavano la scrittura di una nuova lettura nonostante il potenziometro non venisse minimamente toccato.

/* -----------------------------------------------------------------------------------
 Esempio creato partendo dal codice: ReadAnalogVoltage di pubblico dominio.
 Legge un input di tipo analogico sul pin 0 e mostra il risultato sul Serial Monitor
----------------------------------------------------------------------------------- */
double prec_VoltValue=-5;
// Funzione che arrotonda alla cifra-esima cifra decimale
double Arrotonda(const double v , const int cifre)
{
  int i;
    i=(int)(v*pow(10,cifre));
    return((double)(i/pow(10,cifre))); 
}
// La routine di "setup" parte appena premo il tasto di reset:
void setup() 
{
  // inizializza la comunicazione seriale a 9600 bit per secondo:
  Serial.begin(9600);
}

// La loop routine continua a girare:
void loop() 
{
  // Leggo l'input sul PIN A analogico 0:
  int sensorValue = analogRead(A0);
  // Converte la lettura (range da 0 a 1023) in voltaggi (0 - 5V):
  double voltage = Arrotonda(sensorValue * (5.0 / 1023.0),1);
  if ( abs(prec_VoltValue-voltage) > (5.0 / 1023) )  
  {
    // stampo il valore letto:
    Serial.print("Valore sul sensore: ");
    Serial.print(sensorValue);
    Serial.print(" - Voltaggio: ");
    Serial.println(voltage);
    delay(2000);
  }   
  prec_VoltValue=voltage;
}