Main Content

Circuitos_1

Today we will build two circuits to calculate the value of a resistor.

The principle used in these circuits is the voltage division. The measurement is made with an analog port of a micro-controller.

Hoje iremos construir dois circuitos para calcular o valor de uma resistência.

O principio usado nestes circuitos é o da divisão de tensão. A medição é feita com uma porta analógica de um micro-controlador.
CSEduino was used but it could have been used any other Arduino.

Using Ohm’s law it is possible to calculate the resistance of which we do not know the value (Rx). In order to calculate the value of the resistance we first have to calculate the value of the voltage that passes in that resistance. Assuming that the voltage given to the circuit is 5 V. The formula is as follows: VR1 = 5 - VRx. The current is i = VR1 / R1 = (5 - VRx) / R1 since the Rx and R1 are connected in series, the current passing through them is identical. Hence the unknown resistance Rx = Vx / i.

However this simple method has a problem which is when the difference between the R1 and the Rx is large, the calculation of the Rx value is extremely inaccurate. This happens because almost all the voltage will fall in the resistance of greater value which will prevent the measurement of the other resistance.

The second circuit attempts to eliminate this situation by creating an “auto-ranging” system. The microcontroller will control the state of each of the pins that is connected to each of the known resistors and realize the most suitable resistance to make the measurement. To avoid the “fly-back” that would exist due to the fact that we have multiple resistors connected, we use the technique of “disconnecting” the remaining pins placing them in a state called “high impedance”.

This circuit was based on the circuit that is in the following link.

Schematic

Circuitos_3_Schematics

Bill of materials (BOM)

Circuit 1:

  • 1x 1K Ohms Resistor (R1)

Circuit 2:

  • 1x 220 Ohms Resistor (R2)
  • 1x 680 Ohms Resistor (R3)
  • 1x 1K Ohms Resistor (R4)
  • 1x 2.2K Ohms Resistor (R5)
  • 1x 4.7K Ohms Resistor (R6)
  • 1x 10K Ohms Resistor (R7)
  • 1x 22K Ohms Resistor (R8)

The resistors R9 and R10 are the ones that the circuit will calculate the value.

For accuracy reading values it is advisable to use resistors with 1% tolerance or less.

IC/Components Pin-out

Circuitos15_4_Pinout_Resistencias

Code

The first sketch tests using a simple voltage divider.

const int resistorPin = A0;

int raw = 0;
const int Vin = 5;
float Vout = 0;
float R1 = 1000;
float Rx = 0;
float buffer = 0;

void setup() {
  Serial.begin(9600);
}

void loop() {
  raw = analogRead(resistorPin);
  Vout = (5.0 / 1023.0) * raw;
  buffer = (Vin / Vout) - 1;
  Rx = R1 / buffer;
  Serial.print("Voltage: ");
  Serial.println(Vout);
  Serial.print("Rx: ");
  Serial.println(Rx);
  delay(1000);
}
// Sketch uses 4,134 bytes (12%) of program storage space. Maximum is 32,256 bytes.
// Global variables use 234 bytes (11%) of dynamic memory, leaving 1,814 bytes for local variables. Maximum is 2,048 bytes.

The second sketch tests using a set of resistors. If you do not have the values of the resistance of the scheme you can set the value of the resistors in the code, always placing them in ascending order.

const byte resistorPin = A0;
const byte resistorPins[] = {5, 6, 7, 8, 9, 10, 11};

# define NUMBERPINS sizeof(resistorPins)
const int resistorValues[NUMBERPINS] = {220, 680, 1000, 2200, 4700, 10000, 22000};  // Valor das resistências
int resistorReads[NUMBERPINS] = {};

double vx;
float rx;
double i;
boolean novalue;

void setup() {
  pinMode(resistorPin, INPUT);
  Serial.begin(9600);
  while (!Serial) ;
  Serial.println("CSEduino Ohmmeter");
}

int readvalues(byte mask) {
  for(byte p = 0; p < NUMBERPINS; p++) {
    pinMode(resistorPins[p], INPUT); // High-impedance
  }

  for(byte p = 0; p < NUMBERPINS; p++) {
    if ((mask & (1 << p)) != 0) {
      pinMode(resistorPins[p], OUTPUT);
      digitalWrite(resistorPins[p], HIGH);
    }
  }
  return analogRead(resistorPin);
}

void loop() {
  for(byte p = 0; p < NUMBERPINS; p++) {
    resistorReads[p] = readvalues(1 << p);
  }
  novalue = true;
  for(byte p = NUMBERPINS; p > 0; p--) {
    if (resistorReads[p-1] >= 450) {
      vx = (resistorReads[p-1]) * (5.0 / 1024.0);
      i = (5.0/vx) - 1;
      rx = (resistorValues[p-1] / i);
      novalue = false;
      break;
    }
  }
  if (novalue) {
    vx = (resistorReads[0]) * (5.0 / 1024.0);
    i = (5.0/vx) - 1;
    rx = (resistorValues[0] / i);
  }

  if(vx > 4.8) {
    Serial.println("----INFINITY----");
  } else {
    if(rx < 1000) {
      Serial.print(rx);
    } else {
      rx = rx / 1000;
      Serial.print(rx);
      Serial.print("k");
    }
    Serial.println(" Ohms");
  }
  delay(200);
}
// Sketch uses 5,056 bytes (15%) of program storage space. Maximum is 32,256 bytes.
// Global variables use 291 bytes (14%) of dynamic memory, leaving 1,757 bytes for local variables. Maximum is 2,048 bytes.