Non resetting variable

Hello,

I have tried searching for a bit of help but I think my wording is making it very hard for a search engine but i can't think of a better way to describe it :S

I have a system that measured power useage and then sends the power via powerline communication. However i only want it to send the data if there has been a 5% change. So far I have:

  if(powerreal > 10)
  {
    if((powerreal < (0.95*powerold)))
    {
      Serial.println("less");
      senddata(currentrms,voltagerms,powerreal);
    }
    if((powerreal > (1.05 * powerold)))
    {
      Serial.println("more");
      senddata(currentrms,voltagerms,powerreal);
    }
  }

  powerold = powerreal;

  delay (3000); // delay before next set of readings.

}

The only problem is when void loop starts for the next run powerold is reset to 0, is there anyway for it to hold the old number? It works holding the number if no data is sent, but if data is sent it resets, i think it has something to do with calling another function, however i want to keep everything in separate functions else the program is going to be really messy :S

Show all your code, not just a snippet.

How to use this forum

I think you might want Static....

Ok full code show below

void setup(){ // Setup function
  Serial.begin (9600); // Set serial to 9600

}

static float powerold;

void loop(){ //Main program for AC current test.
  float voltagein = 0; // define voltage input as a floating point variable and set to 0.
  float voltagemeasure = 0; // define measured voltage as a floating point variable and set to 0.
  float voltagesum=0;
  float voltagerms=0;
  float voltageavg=0;
  float currentmeasure = 0; // define measured current as a floating point variable and set to 0.
  float currentavg=0;
  float currentsum=0;
  float currentrms=0;
  float a20current=0; // define acs712 20a as a floating point varible and set to 0.
  float powerin =0;
  float powersum = 0;
  float powerreal =0;
  int current2dp=0;
  int voltage2dp=0;
  int powerreal2dp=0;

  int n=0; 

  do{
    voltagein=(analogRead(A3)-114); // Set voltagein to the reading from the voltage divider input at pin A4.
    delay(1); // 1ms to make up for the phase shift.
    a20current = analogRead(A1); // Set a5current to the reading from the 5a acs712 input at pin A2.
    if(voltagein > 0){
      voltagemeasure=voltagein; // voltagesum is set to be a running total
      currentmeasure = a20current - 512;
      currentmeasure = abs(currentmeasure);
      voltagesum = voltagesum + voltagemeasure;
      currentsum = currentsum + currentmeasure;
      powerin = (voltagemeasure * currentmeasure);
      powersum = powersum + powerin;
      n++;
    }

  }
  while (n < 500); // run 500do while cycles.


  currentavg = (currentsum/n); // Calculate average current.
  currentavg = ((currentavg)*0.0489);
  currentrms =(currentavg * 1.01 ); // Covert from average current to current rms.
  Serial.print("Current rms= "); // Print to serial.
  Serial.println(currentrms); // Print the value of current to serial monitor.

  voltageavg = voltagesum/n;
  voltageavg = voltageavg * 2.206;
  voltagerms = 1.11*voltageavg; // Covert from average voltage to voltage rms.
  Serial.print("Voltage rms= "); // Print to serial.
  Serial.println(voltagerms);

  powerreal = (powersum/n)*0.1030; // 0.0489 for current 2.106 for voltage.
  Serial.print("Power = "); // Print to serial.
  Serial.println(powerreal);
  Serial.print("Powerold = "); // Print to serial.
  Serial.println(powerold);

  if(powerreal > 10)
  {
    if((powerreal < (0.95*powerold)) || (powerreal > (1.05*powerold)))
    {
    senddat(currentrms,voltagerms,powerreal);
    }
  }

  powerold = powerreal;

  delay (3000); // delay before next set of readings.

}

void senddata(float currentrms, float voltagerms, float powerreal)
 {
 int current2dp=0;
 int voltage2dp=0;
 int powerreal2dp=0;
 
 current2dp = currentrms * 100;
 voltage2dp = voltagerms * 100;
 powerreal2dp = powerreal * 100;
 
 char buffer[5];
 
 Serial.print("#S|LOGTEST|[");
 Serial.print(itoa((current2dp), buffer, 10));
 Serial.print(";");
 Serial.print(itoa((voltage2dp), buffer, 10));
 Serial.print(";");
 Serial.print(itoa((powerreal2dp), buffer, 10));
 Serial.println("]#");
 
 }

JimboZA:
I think you might want Static....

I did see something about static and gave it ago, but i think i put it in the wrong place after reading that article. Will give it a go inside the function this time :slight_smile:

  while (n < 500); // run 500do while cycles.

That will either loop forever (if n < 500) or do nothing.

No, it's the hideous do... while stuff.

If for whatever reason powerreal can be 0, this fragment of your code will prevent its being sent but not its resetting powerold.

  if(powerreal > 10)
  {
    if((powerreal < (0.95*powerold)) || (powerreal > (1.05*powerold)))
    {
    senddat(currentrms,voltagerms,powerreal);
    }
  }

  powerold = powerreal;

The simplest change is:

  if(powerreal > 10)
  {
    if((powerreal < (0.95*powerold)) || (powerreal > (1.05*powerold)))
    {
    senddat(currentrms,voltagerms,powerreal);
    powerold = powerreal;
    }
  }

Your code is logically flawed. If it changes gradually, your 5% criterion will never be achieved,
because you are always comparing it to the previous value.

You need to set "powerold" only when you have reported a change, and then keep that value
until it is 5% different again.

spatula:
No, it's the hideous do... while stuff.

Oh, sorry, didn't spot that. Better indentation maybe?