Need help, not adding after 1024

Thanks for the update, but what you're saying doesn't really make sense to me.

First, I don't understand how the code could count backwards (assuming that the finalEnergyDecimal -= (int) finalEnergyDecimal statement was placed inside the if block when you implemented the code). Can you provide some initial values for finalEnergyDecimal, finalEnergyValue, and accumulateEnergy that would reproduce this condition?

Second, if you remove that line, the original problem should re-appear; if finalEnergyDecimal becomes 1024, then it will not longer increase with further additions of accumulateEnergy.

Third, your computed value of finalEnergyValue is now no longer equal to the cumulative sum of accumulateEnergy (which is presumably what you wanted to calculate), because you are now double-counting.

I should have explained it more clearly, it increases without any issues but sometimes, for example when it reaches 101.9999 it decrease back to 100.0000 it happens when the decimals reaches .9999 then I removed this part of the code "finalEnergyDecimal -= (int) finalEnergyDecimal" and now it's working perfectly. Is it because of the minus equals? "-=" you anyway solved the problem for me, Thank you very much I really appreciate it.

Thank you for taking your time to help me, I will also try what you suggested and give you an up. Thank you very much.

The statement finalEnergyDecimal -= (int) finalEnergyDecimal is equivalent to:

finalEnergyDecimal = finalEnergyDecimal - (int) finalEnergyDecimal

The purpose of this statement was to ensure that the variable finalEnergyDecimal only keeps track of the decimals (thus, it would be normal for finalEnergyDecimal to decrease from, say, 0.995 to 0.005 if you add an accumulateEnergy value of 0.010). However, at the same time, the variable finalEnergyValue should increase (by an increment of 1) — this happens in the statement finalEnergyValue += (int) finalEnergyDecimal), which is equivalent to:

finalEnergyValue += finalEnergyValue + (int) finalEnergyDecimal

Like I said above, you may think that removing the finalEnergyDecimal -= (int) finalEnergyDecimal statement fixed the problem you were seeing, but you actually have created some new problems. I'd hate for you to use a program that is generating invalid results.

Would you mind posting the part of your code where you combine the values of finalEnergyValue and finalEnergyDecimal to display a number like "101.9999" (or even better, just post your entire code)? I think the original error may be in that part of the code.

When you post code in the forum, please first click the icon <CODE/> in the toolbar at the top of the forum editing window in your response. You will then see this in the editor window:

```
type or paste code here
```

Next, copy your code, and paste it to replace the text that says "type or paste code here". Please ensure that when typing the text of any comments you wish to add in your response, that you stay away from the two lines with the ``` characters (there should be nothing else on those two lines), and that you don't type anything within your pasted code.

I understand, I will keep the original code you sent and do few more tests. Thank you so much for taking your time to help me I really appreciate it.

If you share what code you are using now, we may be able to spot the problem.

To display the value, you could use something like:

Serial.print(finalEnergyValue,0);
Serial.print(".");
Serial.println(1.E7*finalEnergyDecimal,0);

Below is the code Im testing now, and its incrementing the Energy without any problems. Also I have commented off the "finalEnergyDecimal -= (int)finalEnergyDecimal;" and for weeks nonstop, its working perfectly. Thank you very much for helping me, appriciate it.

float accumulateEnergy = 0;
float finalEnergyDecimal = 0;
int finalEnergyValue = 0;

float voltage = 0;
float current = 0;
float power_factor = 0;
float realPower = 0;

void setup() {

  Serial.begin(9600);

  finalEnergyValue = 1023.9995;  // Start with 1023.9995 to count beyond 1024
}



void loop() {

  voltage = 237.0;
  current = 0.5;
  power_factor = 0.98;

  realPower = voltage * current * power_factor;

  accumulateEnergy = realPower / 3600000.0;  // Energy in kWh

  finalEnergyDecimal = finalEnergyDecimal + accumulateEnergy;

  if (finalEnergyDecimal > 1) {
    finalEnergyValue += (int)finalEnergyDecimal;
    // finalEnergyDecimal -= (int)finalEnergyDecimal;
  }
}

Serial.println(finalEnergyValue, 4);


delay(977);
}

Can you show some sample output to demonstrate this? Based on your code, I would think that the last 4 decimals of the displayed value finalEnergyValue should always stay constant at .9995 (and not get updated in each loop).

Also, as an additional test, please define the following initial conditions in setup(), instead of the one that you are using for your current test:

void setup() {

  Serial.begin(9600);

  finalEnergyDecimal = 1023.9995;  // Start with 1023.9995 to count beyond 1024
  finalEnergyValue = 0.1234;  // Start with small value, to demonstrate double-counting
}

Please note that in your current code (without the -= statement), there is nothing that will prevent finalEnergyDecimal from increasing to a value of 1023.9995. It is unlikely that you ran your tests for so long that this value was reached, which is why I want you to try the initial conditions that I have suggested above.

Without testing this myself, I believe that your output will be something like the following:

1023.1234
2046.1234
3069.1234
...
8184.1234
9207.1234
10230.123x
...
15345.123x
16369.123x
17393.123x
...

(Note: I'm not sure what digit will be displayed where I wrote "x"; and "..." means that I've skipped some rows of output.)

Clearly, the above output is completely incorrect, because the first value should have been 1024.1229 (=0.1234 + 1023.9995), and the remaining values should be incrementing by only 0.000032258 in each loop (not by 1023 or 1024, which is what is happening in my example).

You were right, I have to put back the "finalEnergyDecimal -= (int)finalEnergyDecimal;", I did this on print "Serial.println(finalEnergyValue + finalEnergyDecimal, 4);" I also added these two lines to the "Setup" so it can start from "1023.9995" "finalEnergyValue = 1023; finalEnergyDecimal = 0.9995;"
Below is the complete code and the results:


float accumulateEnergy = 0;
int finalEnergyValue = 0;

float finalEnergyDecimal = 0;

float voltage = 0;
float current = 0;
float power_factor = 0;
float realPower = 0;

unsigned long Energy_Counter = 0;
const long Energy_count = 977;  

void setup() {

  Serial.begin(9600);

  finalEnergyValue = 1023;  // Start with 1023.9995 to count beyond 1024
  finalEnergyDecimal = 0.9995;
}

void loop() {
  unsigned long timeNow = millis();
  if (timeNow - Energy_Counter >= Energy_count) {
    Energy_Counter = timeNow;

    voltage = 237.0;
    current = 0.5;
    power_factor = 0.98;

    realPower = voltage * current * power_factor;

    accumulateEnergy = realPower / 3600000.0;
  
    finalEnergyDecimal = finalEnergyDecimal + accumulateEnergy;

    if (finalEnergyDecimal > 1) {
      finalEnergyValue += (int)finalEnergyDecimal;
      finalEnergyDecimal -= (int)finalEnergyDecimal;
    }

    Serial.println(finalEnergyValue + finalEnergyDecimal, 4);
  }
}

Results:
1023.9999
1023.9999
1024.0000
1024.0000
1024.0000
1024.0000
1024.0000
1024.0001
1024.0001
1024.0001
1024.0001
1024.0002
1024.0002
1024.0002
1024.0003
1024.0003
1024.0003
1024.0003
1024.0004
1024.0004
1024.0004
1024.0004
1024.0006
1024.0006
1024.0006
1024.0006
1024.0007
1024.0007
1024.0007

Its working perfectly... Thank you very much for sorting this out for me, I really appreciate it..!!!

Glad that I could help you with your decimal problem. Before concluding, we may want to revisit some of the feedback you receive in post #18.

First, your unit conversions:

I assume that voltage has units of volt (V), current has units of ampere (A), and that power_factor is dimensionless. In that case, the computed value of realPower will have units of watt.

However, the calculation of cumulative energy consumption (accumulateEnergy) in your code above does not seem to be correct. Assuming that the factor 3600000.0 has units of s/kh (seconds per thousand hours), then the resulting value of accumulateEnergy will have the following units:

W / (s/kh) = kWh/s (=Wh/ms)

Therefore, for finalEnergyValue to have units of kWh (kilowatt-hours), you would need to multiply accumulateEnergy by a time-interval measured in seconds. Alternatively, if you multiply accumulateEnergy by a time-interval measured in milliseconds, the final result will have units of Wh (watt-hours).

Second, as noted in post #18, you need to estimate energy consumption by computing a numerical integral. Therefore, in order for your results to be valid (at least in an approximate sense), you need to factor in the actual length of the time-interval (Energy_count) into your calculations. For example, you could do use a backward Euler algorithm for numerical integration, and do the following:

accumulateEnergy = Energy_count * realPower / 3.6E6; // Energy in watt-hour

or

accumulateEnergy = Energy_count * realPower / 3.6E9; // Energy in kilowatt-hour

The accuracy of your results will depend on how quickly the power consumption changes between the sampling intervals.

Yes, the accuracy of the accumulated Energy will depend on the timing. You have thought me so much, thank you for taking your time to help me to slove this, Im truly grateful and I really appreciate it, Thank you very much.

You're welcome!

It will also depend on the validity of your formulas. If you do not include the multiplication by Energy_count (and the modified conversion factor) as I showed in post #31 above, then your results will only be valid if you define Energy_count = 1 (to get results in Wh) or Energy_count = 1000 (to get results in mWh).