Variable not changing with ++ increment and --decrement

Hi,

I know I am missing something really simple here but I have been debugging for about 4 hours now and I just can't see it.

I will use the Aduino to turn dump loads on and off based on a voltage reading I get from 3 PZEM004T meters on a 3 phase circuit.

It is for a hydro electric project I have on a waterfall at home and there always needs to be a load on the generators. If I am not using enough power at the house I need to create a load to stop the turbines over speeding = too high voltage

The code is below. I am using 'if' and 'else if' statements to try to change 3 level variables (1 per phase) up one increment if the voltage for that phase is above a high set point and v.v. if its below a low set point.

The level variable is then used to decide which relays are on/off, the relays control heating elements creating the dump load. (I know its not very efficient but it is phase one of the project to give me stable, useable power. Phase two will be to use it more efficiently.)

The problem I am having is the level variables...

byte brLevel = 3;
byte blLevel = 3;
byte grLevel = 3;

...go straight to 1 and stay there. I even tried //ing out the 'if' statements leaving simply

++brLevel;

but

Serial.println(brLevel);

always returns 1

Help, and thanks.

// Written for Arduino Nano

#include <SoftwareSerial.h> // Arduino IDE <1.6.6
#include <PZEM004T.h>

// Voltage setpoint high and low limits
const int voltstpth = 210;
const int voltstptl = 209;

// Variable for dump load level
byte brLevel = 3;
byte blLevel = 3;
byte grLevel = 3;

// PZEM004T coms for brown, black and grey phases
// Arduino TX, RX pins (PZEM004T RX, TX)
PZEM004T pzembr(2, 3);
PZEM004T pzembl(4, 5);
PZEM004T pzemgr(6, 7);
IPAddress ip(192, 168, 1, 1);

// Dump load relay control pins for brown, black and grey phases
// Using Analog pins A0 - A5 as digital out pins
const byte br1 = 14; //1000w
const byte br2 = 15; //1500w
const byte bl1 = 16; //1000w
const byte bl2 = 17; //1500w
const byte gr1 = 18; //1000w
const byte gr2 = 19; //1500w


void setup()
{
  // Open Serial coms for debugging and set PZEM004T meter addresses
  Serial.begin(9600);
  pzembr.setAddress(ip);
  pzembl.setAddress(ip);
  pzemgr.setAddress(ip);

  // set relay control pins as output
  pinMode(br1, OUTPUT);
  pinMode(br2, OUTPUT);
  pinMode(bl1, OUTPUT);
  pinMode(bl2, OUTPUT);
  pinMode(gr1, OUTPUT);
  pinMode(gr2, OUTPUT);
}

void loop()
{

  // Read voltage from brown PZEM
  int vbr = pzembr.voltage(ip);

  // Adjust brown dump load level if volage is outside limits
  // and maintain level setting between 1 - 4

  if (vbr > voltstptl)
  {
    ++brLevel;
  }
  if (vbr < voltstptl)
  {
    --brLevel;
  }
  constrain(brLevel, 1, 4);

  // Set relay pins according to level
  if (brLevel = 1) {
    digitalWrite(br1, LOW);
    digitalWrite(br2, LOW);
  }
  else if (brLevel = 2) {
    digitalWrite(br1, HIGH);
    digitalWrite(br2, LOW);
  }
  else if (brLevel = 3) {
    digitalWrite(br1, LOW);
    digitalWrite(br2, HIGH);
  }
  else if (brLevel = 4) {
    digitalWrite(br1, HIGH);
    digitalWrite(br2, HIGH);
  }

  // Read voltage from black PZEM
  int vbl = pzembl.voltage(ip);

  // Adjust black dump load level if volage is outside limits
  if (vbl > voltstpth) {
    ++blLevel;
  }
  else if (vbl < voltstptl) {
    --blLevel;
  }

  // Maintain level setting within limits
  constrain(blLevel, 1, 4);

  // Set relay pins according to level
  if (blLevel = 1) {
    digitalWrite(bl1, LOW);
    digitalWrite(bl2, LOW);
  }
  else if (blLevel = 2) {
    digitalWrite(bl1, HIGH);
    digitalWrite(bl2, LOW);
  }
  else if (blLevel = 3) {
    digitalWrite(bl1, LOW);
    digitalWrite(bl2, HIGH);
  }
  else if (blLevel = 4) {
    digitalWrite(bl1, HIGH);
    digitalWrite(bl2, HIGH);
  }

  // Read voltage from grey PZEM
  int vgr = pzemgr.voltage(ip);

  // Adjust grey dump load level if volage is outside limits
  //and maintain level setting within limits
  if (vgr > voltstpth) {
    ++grLevel;
  }
  else if (vgr < voltstptl) {
    --grLevel;
  }
  constrain(grLevel, 1, 4);

  // Set relay pins according to level
  if (grLevel = 1) {
    digitalWrite(gr1, LOW);
    digitalWrite(gr2, LOW);
  }
  else if (grLevel = 2) {
    digitalWrite(gr1, HIGH);
    digitalWrite(gr2, LOW);
  }
  else if (grLevel = 3) {
    digitalWrite(gr1, LOW);
    digitalWrite(gr2, HIGH);
  }
  else if (grLevel = 4) {
    digitalWrite(gr1, HIGH);
    digitalWrite(gr2, HIGH);
  }

  // /*
  // De bugging

  Serial.print("Brown V =  ");
  Serial.println(vbr);
  Serial.print("Brown lvl  ");
  Serial.println(brLevel);

  Serial.print("Black V =  ");
  Serial.println(vbl);
  Serial.print("Black lvl  ");
  Serial.println(blLevel);

  Serial.print("Grey V  =  ");
  Serial.println(vgr);
  Serial.print("Grey lvl   ");
  Serial.println(grLevel);
  Serial.println();

  delay(2000);

  // End debugging
  // */

  // Delay in the loop is not normally necessary
  // because the PZEM004T reply is not instant
}
constrain(brLevel, 1, 4);

Does nothing that way :wink: That function does nothing to brLevel, it returns a constrained version of it. So if you want to constrain brLevel itself it should be:

brLevel = constrain(brLevel, 1, 4);

Next, the real error:

if (brLevel = 1) {

= vs == :wink: Need t say more?

Ha ha, it took a few seconds of staring blankly at the code. Now it has clicked and I'm laughing out loud.

Thanks for the help and pointing out my other error.

This is really the first code I have written start to finish so any other pointers to make things more efficient or even conventional please feel free to criticize.

Some free tips

  • Start counting at 0 like uC :wink:

  • Use longer but more descriptive variable names. Yes, you might save a split second not having to type if fully but it makes reading the code a lot harder. Future you will thank you for it :wink:

  • Use arrays if you start counting. You now basically do the same stuff tree times, with an array you only need to do it once :slight_smile:

Corrections made and its working perfectly.

Advise noted,

originally brLevel was an integer and went from 0 to 3. I decided to change to a byte and wasn't sure how it would handle

--brLevel;

when brLevel was 0 so I changed the range from 1 to 4.

I will definitely start using better variable names and look into using arrays.

Thanks again for all your help.

Incrementing a unsigned variable of 0 (like a bye) will result in the max value (so 255 for a byte). But most of the time it's just easier to only increment (or decrement) when the range still allows it.

if(var > 0){
  var--;
}

etc

septillion:
Incrementing a unsigned variable of 0 (like a bye) will result in the max value (so 255 for a byte). But most of the time it's just easier to only increment (or decrement) when the range still allows it.

if(var > 0){

var--;
}



etc

Got it. Thanks.