Community
OpenEnergyMonitor

Community

Can there be a correlation between Emonlib current increase and unsyncing of RTC?

emonlib
rtc
Tags: #<Tag:0x00007f10a4f5af80> #<Tag:0x00007f10a4f5ae40>
(Diogo Santos) #1

I’m having this weird issue where my data Send interval gets screwed up when the monitored current goes above 27A. Basically, it keeps adding several seconds to my interval, here’s an example:

Database:
Current | Time
16A | 10:00:30
16A | 10:10:30
16A | 10:20:30

16A | 12:00:30
27A | 12:10:35
27A | 12:20:40
27A | 12:30:45

27A | 13:21:05
16A | 13:31:10
16A | 13:41:10

The arduino I’m using is an MKR 1300 with RTC integrated. And here’s the code for visbility: Also, by the way, the RTC library is RTCZero.

/* INITIAL_TIME */
const byte seconds = 0;
const byte minutes = 0;
const byte hours = 0;
const byte day = 17;
const byte month = 12;
const byte year = 18;


byte second_alarm = 0;
byte minute_alarm = 0;
byte hour_alarm = 0;
int SEND_LOOP = 10; //5

float totalKW;
int time_running = 0;
int alarm_Triggered = 0;
int correction_var = 0;
long seq_value = 0;

void setup()
  LoRa Network agreement code (removed)

  analogReadResolution(9);
  emon1.current(1, 90.5);  
  emon2.current(2, 90.3);
  emon3.current(3, 90.3);
  time_running = 0;

  rtc.begin(); // initialize RTC

  rtc.setAlarmTime(hour_alarm, minute_alarm, second_alarm);
  rtc.enableAlarm(rtc.MATCH_HHMMSS);
  rtc.attachInterrupt(triggerAlarm);

  // Set the time
  rtc.setHours(hours);
  rtc.setMinutes(minutes);
  rtc.setSeconds(seconds);

  // Set the date
  rtc.setDay(day);
  rtc.setMonth(month);
  rtc.setYear(year);


}

void loop() {
  if (alarm_Triggered == 1) {
    dataMonitor();
    alarm_Triggered = 0;
  }
}

void dataMonitor() {

  float totalWatt = 0;

  float Irms1 = emon1.calcIrms(600);
  if (Irms1 < 0.3) Irms1 = 0;
  float Watt1 = Irms1 * 230;

  float Irms2 = emon2.calcIrms(600);
  if (Irms2 < 0.3) Irms2 = 0;
  float Watt2 = Irms2 * 230;

  float Irms3 = emon3.calcIrms(600);
  if (Irms3 < 0.3) Irms3 = 0;
  float Watt3 = Irms3 * 230;

  totalWatt = Watt1 + Watt2 + Watt3;
  totalKW = totalKW + totalWatt / 1000;

  sendDataChecker();
  setAlarm();
  time_running = time_running + 1;

}

void sendDataChecker() {
  if (time_running >= SEND_LOOP) {
    String msg = String(seq_value)+";"+String(totalKW);
    int err;
    modem.beginPacket();
    modem.print(msg);
    err = modem.endPacket(true);
    if (err > 0) {
      //message sent correctly
      time_running = 0;
      totalKW = 0;
      seq_value++;
    } else {
      Serial.println("ERR");
      time_running = 0;
    }

    delay(1000);

    if (!modem.available()) {
      //Now downlink message
      return;
    } else {
      char rcv[64] {};
      int i = 0;
      while (i < 64 && modem.available()) {
        rcv[i++] = (char)modem.read();
      }
      String data_received = rcv;
      if (data_received == "") {
        Serial.println("Null");
      } else {
        //JsonObject& root = jsonBuffer.parseObject(data_received);
        correction_var = data_received.toInt();
      }
    }
  }
}


void setAlarm() {
  int INTERVAL = 60; //60
  second_alarm += INTERVAL;
  minute_alarm += second_alarm / 60;
  second_alarm %= 60;
  hour_alarm += minute_alarm / 60;
  minute_alarm %= 60;
  hour_alarm %= 24;

  rtc.setAlarmTime(hour_alarm, minute_alarm, second_alarm);
  correct();
}

void correct() {
  if (correction_var == 0) {
    return;
  }
  if (correction_var == 1) {
    rtc.setSeconds(rtc.getSeconds() + 1);
    correction_var = 0;
    return;
  }
  if (correction_var == -1) {
    if ((rtc.getSeconds() - 1) < 1) {
      rtc.setSeconds(0);
      correction_var = 0;
      return;
    } else {
      rtc.setSeconds(rtc.getSeconds() - 1);
      correction_var = 0;
      return;
    }
  }
  correction_var = 0;
  return;
}

void triggerAlarm() {
  alarm_Triggered = 1;
}
0 Likes

(Robert Wall) #2

Can there be a correlation between Emonlib current increase and unsyncing of RTC?

I would have said no, but that appears to be what you are seeing. And I cannot remember ever seeing a problem like this one before. Weird it certainly is.

Is the time printed in your database from another clock somewhere?

Does it always run 5 seconds slow in 10 minutes when the current is greater than 27 A, or does the amount depend on current?
If the Arduino timer was being interfered with, so that it made the clock run slow, then I would not expect it to depend on the current.

Is the real-time clock running slow, or is the alarm time being updated wrongly?

Is the RTC being corrected correctly? (It is not receiving the current or power value to correct the RTC? )

Could there be a memory allocation / access bug in a library? It is unlikely, but try introducing a dummy variable to move the data in memory, and see if there is any change.

0 Likes

(Diogo Santos) #3

The time is obtained from the server, but there is a secondary server that receives the data and it’s time is also the same, besides I have another sensor running that does not pull as much Amps and the timings are okay.

As for always the 5 second I would say it’s more like between 4 and 6 but the current is normally about the same 27.3~28.1 and I’m not really seeing a pattern on the increase. The overall feel here is that the bigger the current the bigger the delay but it’s only really noticeable after 27A is passing.

I kind of assumed that too but I have another sensor running the exact same code but pulling less Amps and it’s running fine.

The RTC only goes up by 1 and -1 depending on the variable it receives from the message, so if it was an error there it would not be increments of 5 seconds.

Sorry, I don’t understand this part, how would I do that? I did make some tests for buffer overflows but nothing really seemed out of the normality.

0 Likes

(Robert Wall) #4

Just add something like
long dummy;
That will allocate 4 bytes and move every variable defined after it by 4 bytes. Put it either at the start of the global variables, or inside one or more functions. I would hope there will be no change, no matter where you put it. If there is, you move it about to try to find exactly where the problem lies.

0 Likes

(Diogo Santos) #5

Ah got it, I don’t have the arduino with me but I’ll give a try when I am able. Thank you.

0 Likes

(Robert Wall) #6

I think we have to assume for the now (until proven otherwise) that a number, either in emonLib or in your sketch, has got larger, and the more significant byte that has come into use is also being used by the rtc. That should never happen, but if there is a mistake in the code somewhere, with C & C++, it is possible.

0 Likes

(Diogo Santos) #7

Yes, that’s what I thought initially and I also changed all my doubles to floats, but same issue. Gonna try directly dividing the Watt into kW but don’t think it’ll be that.

I can try and make prints to the analogRead(inPinI) and the total sum to see if there’s anything too big in there.

0 Likes

(Bill Thomson) #8

That stands to reason as doubles are the same as floats in the Arduino “environment.”
(with one exception as noted at the link below)

Ref: https://www.arduino.cc/reference/en/language/variables/data-types/double/

0 Likes

(Diogo Santos) #9

Oh well. But in that case the sumI within EmonLib can’t be changed either since it’s a double even if it’s too big (which I doubt that’s the issue).

Welp, dummy variable is all I have left.

0 Likes

(dBC) #10

There’s a reasonable chance that exception also includes the MKR 1300 in use here. It’s based on the Arduino Zero which also uses an ARM (like the Due referenced in your exception). But it’s a different SAM device so it’s possible they only support double on one and not the other. To find out for sure you could do something like:

printf("float: %ld\n", sizeof(float));
printf("double: %ld\n", sizeof(double));

That’s standard C, you might need to Adruino-ise that… println Vs printf… I’m a bit rusty on Arduino programming.

0 Likes

(Diogo Santos) #11

Float: 4,
Double: 8.

So I really should be using double either way.

0 Likes

(dBC) #12

There’s one more consideration: does the FPU in your CPU do double precision? If it does, then yes, double is the way to go. If it doesn’t then the double precision will all be emulated in software and so will be quite a bit slower than float. Then the decision comes down to a trade-off between speed and precision.

0 Likes

(Diogo Santos) #13

Update: The SRAM is going fine, 28103 free memory at any given point.

0 Likes

(dBC) #14

It’s a long shot, but you might try making alarm_Triggered volatile.

Where you check to see if each Irms is less than 0.3, it might also be interesting to add something like…

if (IrmsN > 16.0) IrmsN = 16.0;

Effectively clip the result at 16A. Then run your 27A through it and see which way it goes. If the problem still shows up with that, dig deeper into the emon library but if that “fixes” the problem, dig deeper into the addition/transmission code.

0 Likes

(Diogo Santos) #15

Thank I’ll actually give that a try. But instead of capping the output from emonlib i’ll cap the outpud from the ADC and see how it goes. Or do both actually.

Also, I’ve tried a lot of tests today but there’s one specific that is bugging me. The one sensor where this happens uses an SCT-013-000 (100A:50mA) where I placed, outside a burden resistor of 18 Ohm (feeding through Vcc at 3.3V). But I also have one sensor where I use a SCT-013-100 (100A:1V) that is receiving from the main current way above 27A (about 40A I think), I don’t use a burden resistor since there is one inside the CT , and in his case, there seems to be no delay at all.

Is there any chance the resulting voltages from the SCT-013-00 system might be creating this?

0 Likes

(Robert Wall) #16

On identical currents, the SCT-013-000 with the 18 Ω burden should be giving 90% of the voltage that you get from the SCT-013-100. Unless, of course, your burden resistor is not what you think it is.

So if it is current-related, the fault is happening to the wrong input!

One possibly useful test arises from this: If you exchange the two c.t’s, but keep them on their own main cable, does the fault move with the c.t. or does it stay with input channel?

0 Likes

(Diogo Santos) #17

Will try to test this possibility too. I can’t really move the CTs from the cables tho, but I have a voltimeter and I can check the voltages at the end CT and see if the variation is that big.

One weird thing is with the CTs SCT-013-000 i have to use analogReadResolution(9) to get good values, but with the others SCT-013-100 I have normally use analogReadResolution(12). So that might also have a reason in there.

0 Likes

(Robert Wall) #18

I expected that. But my point was - it is the c.t. that is giving the lower voltage that is showing the fault.

I think you should be able to detect a 10% difference in the ratios of the two c.t’s, if you have a clamp ammeter that you can put on the main cable, and a millivoltmeter to measure the c.t. output or the burden voltage.

That might be significant. We did not know that until now. EmonLib assumes, unless it detects otherwise, that the ADC is 10-bit. But even so, I cannot see a mechanism whereby the numbers in emonLib would overflow into the RTC code, or delay the timer interrupt.

0 Likes