# Logic Behind MQx Sensors Calibration

Would you please explain the logic behind this snippet of code which is taken from here for calibrating MQx Sensor(s):

``````def MQResistanceCalculation(self, raw_adc):
``````

in which `raw_adc` is the `MCP3008` reading, and `RL_VALUE` is the load resistance on the board, in kilo ohms and equals 5.

The thing is, as far as I understand it, the ADC works according to this equation:

``````Resolution of ADC / System Voltage = ADC Reading / Analog Voltage Measured
``````

but I cannot see it implemented in the above-code (because I was following this tutorial but for Arduino).

Furthermore, to get the value of `RS` in a gas according to the second above-mentioned tutorial, we follow this equation:

``````RS = [(VC x RL) / VRL] - RL
``````

which also not seen in the entire code of the project that the first snippet of code comes from.

The Schema of this design is:

``````MQx Sensor -> Logic Level Converter -> MCP3008 -> RPi
``````

I'm sure I'm missing something, or maybe I'm mixing up things.

Starting from Ohm's Law: `V = R * I` in which V: Voltage, R: Resistance and I: Current.

and in the simplest circuit of a Voltage Divider like this: to measure any voltage we need two points, so Vout can be measured in one of two ways: (Vin - Vout) = R1 * I1 : in which Vin here is the positive side of the electricity source.

OR (Vout - Vin) = R2 * I2 : in which Vin here is the negative side and equals 0.

We choose the easier choice where Vin = 0, so Vout = R2 * I2.

Now, because there is no consumption of the current, we can assume Itotal = I1 = I2. So re-writing the above equation: Vout = R2 * Itotal.

Now because R1 and R2 connected in series, the law says Rtotal = R1 + R2.

Back to Ohm's Law we can say: Vin = Rtotal * Itotal --> Itotal = Vin / Rtotal.

Using the last equation, we will have: Vout = R2 * (Vin / Rtotal), re-writing it again: Vout = R2 * (Vin / R1 + R2).

Now the job is to find R1:

Vout / R2 = Vin / (R1 + R2) -> (R2 * Vin)/Vout = R1 + R2.

Finally:

R1 = [(R2 * Vin)/Vout] - R2. Which we also can re-write it in this way: R1 = [(Vin/Vout)-1] * R2.

which receives a voltage value and convert it to an approximate corresponding digital value.

Resolution determines the scale/level of the conversion, so for example, if we have a 2-bit ADC which can read up to 10V as input, the possible corresponding values will be:

``````Voltage     2-Bit Digital Rep.

0 to 2.5        00
2.5 to 5        01
5 to 7.5        10
7.5 to 10       11
``````

So, it's 22 = 4 different numbers. So the range of Digital Values is: 0 to 3, The same way, if we have 10-bit ADC -> 210 = 1024, the range of Digital Values is: 0 to 1023.

The ADC reports a ratiometric value. This means that for 10-bit ADC assumes 5V (System Voltage) is 1023 and anything less than 5V will be a ratio between 5V and 1023.

We use this simple equation:

``````ADC Resolution / System Voltage = ADC Reading / Analog Voltage Measured
``````

Now, re-writing it:

`````` System Voltage = (Analog Voltage Measured * ADC Resolution) / ADC Reading
``````

in which System Voltage and Analog Voltage Measured correspond to the Vin and Vout in the Voltage Divider Equation respectively.

Using this in the Voltage Divider Equation gives us:

R1 = [((Analog Voltage Measured * ADC Resolution) / ADC Reading) / Analog Voltage Measured - 1] * R2

Keep re-writing it:

R1 = [(Analog Voltage Measured * ADC Resolution) / (ADC Reading * Analog Voltage Measured) - 1] * R2 ->