Suggestions on how to proceed with new EMON homestead installation using ESP32

Yes, but HOW LONG did it take to collect those samples? What I’m trying to get at is the sample rate - how many samples per second is emonLib collecting?

Ok…looking at the >> 60 crossings & 1200 timeout << data it looks like 10K samples per second roughly is what is being processed by Emon.
[sample time: 495 samples: 5366]

130 crossings & 1200 timeout<< was just about maxing out the timeout window.

This is much much faster than I envisioned. But then again my data may be incorrect so I included my modification to EmonLib.cpp for your review/critique.



Crossings : 15   Timeout: 300

 emon1stop millis:  44569  emon start millis:  44439   sample time:   130       samples:  1412    

 emon2 stop millis:  46001  emon start millis:  45879   sample time:   122       samples:  1325   


Crossings : 30   Timeout: 600

 emon1 stop millis:  11417  emon start millis:  11171   sample time:   246       samples:  2665     

 emon2 stop millis:  13267  emon start millis:  13027   sample time:   240       samples:  2610     


Crossings : 60   Timeout: 1200


 emon1 stop millis:  13145  emon start millis:  12650   sample time:   495       samples:  5366      

 emon2 stop millis:  15845  emon start millis:  15355   sample time:   490       samples:  5315      


Crossings : 130   Timeout: 1200


emon1 stop millis:  17708  emon start millis:  16629    sample time:   1079      samples:  11692    
 
emon2 stop millis:  20991  emon start millis:  19918    sample time:   1073      samples:  11633    


Crossings : 200   Timeout: 1200


emon1 stop millis:  11118  emon start millis:  9918     sample time:  1200       samples:  12998    

emon2 stop millis:  14528  emon start millis:  13328    sample time:  1200       samples:  12999   


Crossings : 400   Timeout: 1200

emon1 stop millis:  14540  emon start millis:  13340    sample time:   1200      samples:  13001   

emon2 stop millis:  17950  emon start millis:  16750    sample time:   1200      samples:  13001   

EmonLib.cpp code section:


```cpp
int emon_sample_start_millis = millis();

  start = millis();

  while ((crossCount < crossings) && ((millis() - start) < timeout)) {
    numberOfSamples++;          //Count number of times looped.
    lastFilteredV = filteredV;  //Used for delay/phase compensation

    //-----------------------------------------------------------------------------
    // A) Read in raw voltage and current samples
    //-----------------------------------------------------------------------------
    sampleV = analogRead(inPinV);  //Read in raw voltage signal
    sampleI = analogRead(inPinI);  //Read in raw current signal

    //-----------------------------------------------------------------------------
    // B) Apply digital low pass filters to extract the 2.5 V or 1.65 V dc offset,
    //     then subtract this - signal is now centred on 0 counts.
    //-----------------------------------------------------------------------------
    offsetV = offsetV + ((sampleV - offsetV) / ADC_COUNTS);
    filteredV = sampleV - offsetV;
    offsetI = offsetI + ((sampleI - offsetI) / ADC_COUNTS);
    filteredI = sampleI - offsetI;

    //-----------------------------------------------------------------------------
    // C) Root-mean-square method voltage
    //-----------------------------------------------------------------------------
    sqV = filteredV * filteredV;  //1) square voltage values
    sumV += sqV;                  //2) sum

    //-----------------------------------------------------------------------------
    // D) Root-mean-square method current
    //-----------------------------------------------------------------------------
    sqI = filteredI * filteredI;  //1) square current values
    sumI += sqI;                  //2) sum

    //-----------------------------------------------------------------------------
    // E) Phase calibration
    //-----------------------------------------------------------------------------
    phaseShiftedV = lastFilteredV + PHASECAL * (filteredV - lastFilteredV);

    //-----------------------------------------------------------------------------
    // F) Instantaneous power calc
    //-----------------------------------------------------------------------------
    instP = phaseShiftedV * filteredI;  //Instantaneous Power
    sumP += instP;                      //Sum

    //-----------------------------------------------------------------------------
    // G) Find the number of times the voltage has crossed the initial voltage
    //    - every 2 crosses we will have sampled 1 wavelength
    //    - so this method allows us to sample an integer number of half wavelengths which increases accuracy
    //-----------------------------------------------------------------------------
    lastVCross = checkVCross;
    if (sampleV > startV) checkVCross = true;
    else checkVCross = false;
    if (numberOfSamples == 1) lastVCross = checkVCross;

    if (lastVCross != checkVCross) crossCount++;
  }
  //  ********************************************
  int emon_sample_stop_millis = millis();
  int emon_sample_time = (emon_sample_stop_millis - emon_sample_start_millis);
  
  Serial.println();
  Serial.print(F("  emon stop millis:  "));
  Serial.print(emon_sample_stop_millis);
  Serial.print(F("  emon start millis:  "));
  Serial.print(emon_sample_start_millis);
  Serial.print(F("  emon sample time:   "));
  Serial.print(emon_sample_time);
  Serial.print("     ");
  Serial.print(F("  Number of samples:  "));
  Serial.print(numberOfSamples);
  Serial.print("     ");

Wow - I concur, better than 10k sample pairs per second.

I can see a minor problem with your code, but though it would never catch you out here, it might in the future if you aren’t aware. You should have used an unsigned long integer for the times, because millis( ) returns an unsigned long. If you do this, it gets the sums right when it rolls over. There used to be an explanation here Arduino Playground - HomePage for the details. but it’s gone. There appears to be a very convoluted explanation here: Using millis() for timing. A beginners guide - Introductory Tutorials - Arduino Forum

Unfortunately the last two experiments don’t help a great deal, because it hit the timeout for both. This is only there to prevent the sketch hanging if it can’t count zero crossings - the timeout should always be longer than you anticipate for the number of crossings you ask for.

With this said, I see between 10,800 and 10,890 (and both are outliers for the difference of 15 crossings), most other combinations give around 10830 - and this is for the two samples and the per sample pair maths that’s done inside the innermost loop. This gives you 180 samples per cycle - way more than you need.

Sampling rate isn’t a problem. I think you can choose whatever sampling period (number of crossings) makes sense to you. 30 (250 ms) sounds reasonable, 40 (333 ms) if you want a bit longer.

Bear in mind it will be measuring the two legs of your supply consecutively, so the longer the sampling period, the more chance there is that the two measurements won’t be consistent.

With 180 samples per cycle, you could do both voltages and currents simultaneously - but it would entail a very significant change to emonLib.

I originally had it with unsigned long but I changed it to int just to see if there would be a change. I appreciate the heads up though.

I wanted to see where the crossover beyond the timeout was at with the sampling rate.

The person on the Arduino forum, who told me to check my pin assignments related to the 0 voltage value issue, mentioned that there should be a slight pause exiting the first instance to allow the ADC registers to “recover” before getting hit by the 2nd instance. But with what you are saying optimally the two instances would run simultaneously to give a true representation of the split phases precisely at time X.

To reveal my ignorance on microprocessors I have to ask how you could execute a simultaneous execution of the the two instances with a single cpu processor? Would you perform mini steps on each instance going back and forth until you reach the end?

Not quite - you could not do it with two instances, C++ doesn’t work that way. It would mean a rewrite using the principles and a lot of the maths in emonLib, but not emonLib itself. In broad outline, you’d sample one voltage, one current, the second voltage, the second current and then do the maths on each sample pair individually and accumulate the numbers that ultimately give you the voltage & current rms averages and the power average, then do the next set of 4 samples likewise. This would be relatively staightforward, and you’d end up with one instance of a completely new class that handles your split-phase system. But I don’t suggest you go down this route, I was only putting it up as a thought of what might be possible.

No worries. hahaha…

The last week and a half has been rather hectic here at the homestead and my Emon project installation has been delayed. We received 14+ inches of rain in 24 hours and it has created numerous headaches including migration of dirty water into my well cistern which necessitated emptying and cleaning. And I have a 110 volt circuit at my well house with 220 volts on it. Still am bewildered by that. Maybe one of the split phases has connected with the neutral underground? I don’t know. I am getting a pulsing action on the circuit with an analog meter. The voltage goes up to 95 volts and back down to 70 volts over about 3 secs. ??? Digging a new service to one of my outbuildings is probably the easiest solution. Never a dull moment with Mother Nature.

A couple of 120 V tungsten filament lamps (of equal wattage) connected in series would be your best test gear on this sort of fault. The lamps would give a load and give you and idea how much current the fault is capable of. If they pulled the voltage down to near zero, it’s a high resistance fault.

I think you have two faults - probably (but not necessarily) at the same location, I’d guess that both the neutral is broken and the insulation has failed, it might well be that water is seeping into the cable, conducting electricity and boiling, and the heat is drying the fault area and it’s ceasing to conduct. Repeat as more water seeps in. I don’t know this is the mechanism, but it seems likely.

Check all the fuses/breakers and terminations before you dig! How hard is it to replace the cable? If it’s a lot of digging, it might be worth locating the fault with Time Domain Reflectometry,

The other thing I’d question is, was the right type of cable used in the first place, and has it been installed correctly? Your local regulations should have something to say about this. In the UK, for cable “buried direct”, PVC sheathed wire armoured cable is normal and it’s laid in a bed of sand, and deep enough to not be damaged, e.g. by digging or by vehicles passing over.

@Bill.Thomson might be better able to advise you.

If the neutral leg were to come into contact with one of the hot legs, you’d quite likely know about it by way of a tripped circuit breaker.

Classic symptoms of a bad neutral connection.

If that particular circuit is the only one showing the goofy behavior, then your “bad”
neutral connection is either in the load center (breaker box - at the neutral bus bar) or somewhere in the wiring itself. i.e. at the receptacle, a splice, etc.

If more than one circuit is acting wierd e.g. really bright lights in one room and very noticeably dim ones in another room. (i.e. it doesn’t necessarily have to be the exact same behavior you’ve described) then the faulty neutral connection is either on the main neutral lug in the load center, or upstream of the load center. e.g. at the service entrance weatherhead.

BTW, the “numbers” are actually 120 and 240.
110/220 Volts is a holdover from many moons ago. (c. 1930s)

1 Like

The run is in pvc electrical conduit. But where I live that is not a sure thing wiith all the rocks and such in the ground. Fortuately I am looking at only about 20- 25 feet of digging between the service panel and the outbuilding so that will not be too bad.

I live in the Ozark Mountains of northern Arkansas in the U.S. There are no regulations/inspections to speak of in this rural environment when you are a do-it yourselfer. haha I do have an electrical background so “most” everything I installed is at code level. Once issue I have is that everything is 30 years old and mother nature has a way of degrading things over time.

This is quite possibly what is happening. I am going to just do a new install and not try to dig up an existing run.