Sheet Arduino n.4 (Resistance value measurement)

[Lezione del xx yyy 2019]


La scheda della esercitazione n.4 richiede la misurazione di una resistenza incognita, utilizzando un array di resistenze note.

In questo caso, non avendo l’insieme delle resistenze elecate nella scheda del prof.Morresi, ne abbiamo usato un set con i seguenti valori: 100, 1000, 10000, 100000 e 1000000 di ohm.

Come segue:

Il dettaglio dello sketch è il seguente:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
/* Embedded Systems Architecture - hardware
 *  application on sheet 04
 *  
 *  known r1, vin, vout, measure unknown resistance r2:
 *    (r1+r2)*i = vin
 *    and  r2*i = vout
 *  hence:
 *    (r1+r2)/r2 = vin/vout 
 *    => r1/r2 +1 = vin/vout
 *    => r1/r2 = vin/vout-1
 *    => r1 = r2 *(vin/vout-1)
 *    => r1*(1/(vin/vout-1))=r2
 *  using r1 resistance on port:
 *    * 100 ohm - 2
 *    * 1000 ohm - 4
 *    * 10000 ohm - 7
 *    * 100000 ohm - 8
 *    * 1000000 ohm - 12
 */
#define TO_V       (5.0 / 1024.0)     // convert an analog UNO unit to V
#define Vout_PIN   A0
#define BUF_SZ     5
#define WAIT_TIME  100
#define FOREVER    1
#define Vin        5

unsigned int i;
int PORT[BUF_SZ] = {2, 4, 7, 8, 12};                  // ports to known resistances
long R[BUF_SZ] = {100, 1000, 10000, 100000, 1000000}; // known resistance values
unsigned int Vout;            // Vout measure from A/D converter (it must be converted to V)

/* calculate resistance given r1 and vout;
 * vin is defined
 */
float calc_r(long r1, unsigned int Vout){
    float Vo = Vout * TO_V;
    return r1 * ( 1 / (Vin/Vo - 1));    
}

void setup() {
    for(i=0; i<BUF_SZ ;i++)
      pinMode(PORT[i], INPUT);     // these are our power(s) to known resistance(s)
    Serial.begin(9600);            // init the serial at 9600 baud
}

void loop() {
  float r2;
  int ndx = BUF_SZ;
  delay(1000);
  Serial.print("MEASURE START; time btwn measures: ");
  Serial.println(WAIT_TIME);
  for(i=0; i<BUF_SZ; i++){
      pinMode(PORT[i], OUTPUT);
      digitalWrite(PORT[i], HIGH);  // powering R[i]
      delay(WAIT_TIME);
      Vout = analogRead(Vout_PIN);  // reading Vout
      pinMode(PORT[i], INPUT);
      r2 = calc_r(R[i], Vout);      // calculating r2
      if(r2<=(float)R[i]){          // if r2 > R[i] we continue to measure with a bigger R[i] resistance
          ndx = i;                  // otherwise we stop here
          break;
      }
  }
  /* printing measure to serial monitor*/
  Serial.print("MEASURE STOP at index ");
  Serial.println(ndx);
  delay(1000);
  if (ndx<BUF_SZ){
      Serial.print("MEASURE IS ");
      Serial.print(r2, 2);
      Serial.println(" ohm");
  }
  else {
      Serial.print("MEASURE IS NOT RELIABLE; IT'S MORE THAN 1 MOhm");
      Serial.print("However it is ");
      Serial.print(r2, 2);
      Serial.println(" ohm");
  }
  while(FOREVER){};   // halting ops
}

E la su logica è incerniata sul seguente schema:

_images/sh04.svg

dove \(R_2\) è la resistenza da calcolare, \(R_1\) la resistenza nota, \(V_{in}\) la tensione in ingresso al circuito (i 5V di Arduino), e la \(V_{out}\) è la tensione misurata presente tra resistenza incognita e nota.

In questo circuito la corrente tra \(V_{in}\) e ground è la stessa che scorre tra \(V_{out}\) e ground.

Di conseguenza il seguente sistema

\[\begin{split}\begin{equation} \begin{cases} (R_1+R_2) \cdot i = V_{in}\\ R_2 \cdot i= V_{out} \end{cases}\,. \end{equation}\end{split}\]

rapportando i termini diviene:

\[\begin{split}\begin{equation} \frac {(R_1+R_2) \cdot i} {R_2 \cdot i} = \frac{V_{in}}{V_{out}}\\ \frac {(R_1+R_2)} {R_2} = \frac{V_{in}}{V_{out}}\\ \cdots\\ R_1 \cdot \frac {1} {\frac{V_{in}}{V_{out}} - 1} = R_2 \end{equation}\end{split}\]

La funzione calc_r alla ln 35 calcola l’equazione predetta, conosciuti i valori \(R_1\), \(V_{out}\) e la \(V_{in}\).

Il resto è abbastanza immediato. Un vettore (PORT) in cui memorizzare i numeri di porta che usiamo per alimentare, una per volta, le resistenze. E un vettore (R) con i relativi valori delle resistenze.

Dopo di che basta ciclare dando corrente alla resistenza i-esima, partendo dalla più piccola. Misurare la relativa \(V_{out}\) e calcolare la relativa r2. E verificare se il valore misurato è inferiore della \(R[i]\) corrente. Se è così, ci possiamo fermare: stiamo utilizzando la prima resistenza con valore superiore alla corrente. Quindi è la migliore misura che possiamo effettuare.