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):
      return float(self.RL_VALUE*(1023.0-raw_adc)/float(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.


This is the full answer:

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:

voltage divider

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.


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

Analog to Digital Converter (ADC):

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

Overview about ADC Resolution:

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.

Relating ADC Value to Voltage:

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 ->

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

R1 = [(ADC Resolution) /ADC Reading) - (ADC Reading/ADC Reading)] * R2 ->

R1 = [(ADC Resolution - ADC Reading)/ADC Reading)] * R2 ->


R1 = R2 * (ADC Resolution - ADC Reading)/ADC Reading) : in which R1 is Sensor Resistance (Rs), R2 is Load Resistance (RL) and ADC Resolution is 1023.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.