Go Down

Topic: Non resetting variable (Read 556 times) previous topic - next topic

Passive

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:

Code: [Select]
  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

Nick Gammon

http://www.gammon.com.au/electronics

JimboZA

Roy from ITCrowd: Have you tried turning it off an on again?
I'm on LinkedIn: http://www.linkedin.com/in/jimbrownza

Passive

#3
Mar 23, 2013, 11:32 am Last Edit: Mar 23, 2013, 11:36 am by Passive Reason: 1
Ok full code show below

Code: [Select]
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("]#");

}





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 :)

Nick Gammon

Code: [Select]

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


That will either loop forever (if n < 500) or do nothing.
http://www.gammon.com.au/electronics

spatula


Code: [Select]

  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.

spatula

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

Code: [Select]

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

  powerold = powerreal;


The simplest change is:
Code: [Select]

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


michinyon

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.

Nick Gammon


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


Oh, sorry, didn't spot that. Better indentation maybe?
http://www.gammon.com.au/electronics

Go Up
 

Quick Reply

With Quick-Reply you can write a post when viewing a topic without loading a new page. You can still use bulletin board code and smileys as you would in a normal post.

Warning: this topic has not been posted in for at least 120 days.
Unless you're sure you want to reply, please consider starting a new topic.

Note: this post will not display until it's been approved by a moderator.
Name:
Email:

shortcuts: alt+s submit/post or alt+p preview