What is Mid-scale adc and why do we need this for ADC readings

I am using esp32 to read analog signals (AC current and voltage) and some examples I found read the values only when it’s in between the middle 10% of the measurement range.

For example, my pin can accept voltage from 0-3.3V and thus only from 0.453.3 to 0.553.3 can be read into the system for further calculation.

Why do we need this?

the comments says that “Waits for the waveform to be close to ‘zero’ (mid-scale adc) part in sin curve.”

The code I was referring to is from line 82 to 87 on this file:

// 1) Waits for the waveform to be close to ‘zero’ (mid-scale adc) part in sin curve.
unsigned long start = millis(); //millis()-start makes sure it doesnt get stuck in the loop if there is an error.

while(1) //the while loop…
startV = analogRead(inPinV); //using the voltage waveform
if ((startV < (ADC_COUNTS0.55)) && (startV > (ADC_COUNTS0.45))) break; //check its within range
if ((millis()-start)>timeout) break;

Fortunately, my crystal ball is working and I happen to recognise that you’re referring to the part of emonlib and the method where real power is calculated.

emonLib doesn’t (can’t) sample the mains waveform like the text books do, with an exact number of samples for each cycle of mains. But, for the maths and the averaging to be right, you really want to sample an exact whole number of cycles. If you can’t do that, the next best thing is to start and end as close as you can to the point where the voltage crosses zero.

Knowing that, does that bit of code make sense? What happens when condition in the line you’re looking at is met, or perhaps more importantly, what happens when it’s not met, why is it not met and when will it be met?

Thanks for your explanation. I still have some questions about these codes.

According to my understanding, supposing ADC_COUNTS is 12 bit, then ADC_COUNTS x 0.55=4095 x 0.55=2252 which corresponds to 1.815v and ADC_COUNTS x 0.45=4095 x 0.45=1842 which corresponds to 1.415v. The code in Line85 only reads the samples between 1.485v and 1.815v. The samples larger than 1.815v or smaller than 1.485v won’t be read by Emonlib. Is my understanding correct?

Taking one period of a sine wave as an example,

the code on Line85 read the samples on waveform from A to B and from D to F, which is not an exact whole number of cycles. I was thinking it should read the samples from A->B->C->D->E, which is a whole cycle to calculate RMS. Why does the Emonlib only read the samples in that small range(1.485v ~1.815v)?


Let us assume that when the method starts at line 69, the mains is at point ‘C’ on your diagram. It enters the ‘while’ loop at line 85. What happens then? How long does it stay inside that loop, how does it come out of the loop, and where does it go to next?

What happens if it starts when the voltage is inside the middle band (between 45% and 55% of full scale)?

What happens if it starts when the voltage is outside the middle band in the negative half-cycle?

If you still don’t understand, that does line 79 tell you?
One more clue: What variable is used to store the voltage that is read inside that ‘while’ loop, and what happens to it afterwards?

Thanks for your clues!!!

In my understanding, the “startV” is the value that stored the crossing point or ‘zero’ for checking if the sampleV (in line 143 and line 102) has crossed the initial voltage, which is startV. Is that correct?

Another question, why choose 45%-55% of the full scale to be the mid-scale? Can I choose 48%-52% of the full scale for the initial voltage (startV)? Wouldn’t it be more accurate?

Correct. What happens is, it waits until the voltage is close to zero, and then starts measuring voltage and current samples, at the same time counting each crossing so that it knows when to stop - which is when it has a whole number of cycles (because you set the number of crossings to be an even number).

You want to be as close as possible to the 50% point, but not so close that you miss it! If a sample comes at 47.9% and the next at 52.1%, you don’t see it and have to wait for the next crossing and hope you see it this time. If you miss it, the start will be delayed, if you miss the end, you will count more cycles than you wanted.
Therefore, you must consider how far apart consecutive samples are, at the highest and lowest mains voltages that you expect, and be sure that one will always fall inside the range of values set in the test.

That makes sense. Thanks!!!