Hi,
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:

as
//-------------------------------------------------------------------------------------------------------------------------
// 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)?

No.

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?