Help to declare variables for switch...case

Hello!
I am currently using a switch case function to control how 3 relay contacts will operate based on the conditions.
Below is only a portion of the switch case.
Creds to @Blackfin for providing the code in a previous post :slight_smile:

This Arduino program is meant to be controlled from Node-Red. i.e. in Node-Red, a button called ‘Power’ can be pressed and the case called “ST_POWER” will be activated, which will, in turn, activate the case “ST_CHARGING”, which will then operate the relay switches named K1-K3.

void loop()
{
  const int ST_POWER = LOW;
  const int ST_CHARGING = LOW;
  const int ST_MANUAL = LOW;
  const int ST_CHECK_CURRS = LOW;
  static byte stateControl = ST_POWER;

  switch ( stateControl )
  {
    case  ST_POWER:
      //Power
      if ( digitalRead( Power ) == HIGH ) {
        stateControl = ST_CHARGING;
      }

      break;

    case  ST_CHARGING:
      //Charging on?
      if ( digitalRead( Charging ) == LOW ) {
        //No
        stateControl = ST_MANUAL;
      }
       
      else {
        //Yes
        digitalWrite( K1, LOW );
        digitalWrite( K2, LOW );
        digitalWrite( K3, HIGH );
        stateControl = ST_CHARGING; //redundant, presented for illustrative purposes
      }//else

      break;

I don’t really know how to declare the case variables “ST_CHARGING” and “ST_MANUAL”, but I know that the variable must be constant. If I let the variables = LOW, I get the “Duplicate case value” error.

  const int ST_POWER = 41;
  const int ST_CHARGING = 42;
  const int ST_MANUAL = 43;
  const int ST_CHECK_CURRS = 44;

If I assign random pin numbers to the case names, the program compiles fine but it does not run as intended.

How do I solve this error? Thanks!!

Use enumerated types (“enum”) instead of "const int"s

Example from link:

enum Color { red, green, blue };
Color r = red;
switch(r)
{
   case red  : std::cout << "red\n";   break;
   case green: std::cout << "green\n"; break;
   case blue : std::cout << "blue\n";  break;
}

The ST_ constants are states. This code appears to implement a simple state machine. As long as the ST_ constants are unique then their value shouldn’t matter.

Otherwise, your program must not be working for a different reason. Post your entire sketch if you would like help.

Power_Broker:
Use enumerated types (“enum”) instead of "const int"s

I will try this. Thanks!

ToddL1962:
The ST_ constants are states. This code appears to implement a simple state machine. As long as the ST_ constants are unique then their value shouldn’t matter.

Otherwise, your program must not be working for a different reason. Post your entire sketch if you would like help.

My theory is that somehow the ST_constants are seen as the same variable by the compiler.

//using Arduino Mega 2560
//Virtual Node-red relay input IN1
const byte IN1 = 22; 
const byte IN2 = 24;
const byte IN3 = 26;
//Physical relay output K1
const byte K1 = 23; 
const byte K2 = 25;
const byte K3 = 27;
//Virtual Node-red switches
const byte Power = 28;   
const byte Charging = 30;
const byte Manual = 32;
const byte GetValues = 19;  //Interrupt Pin 19 on Mega2560

volatile int InterruptState = LOW;
//Sensor variables
float shuntvoltage_PV = 0;
float busvoltage_PV = 0;
float current_mA_PV = 0;
float loadvoltage_PV = 0;
float power_mW_PV = 0;

float shuntvoltage_Load = 0;
float busvoltage_Load = 0;
float current_mA_Load = 0;
float loadvoltage_Load = 0;
float power_mW_Load = 0;

int current_mA_Batt = 0;  

void setup()
{
  pinMode( IN1, INPUT );
  pinMode( IN2, INPUT );
  pinMode( IN3, INPUT );
  pinMode( K1, OUTPUT );
  pinMode( K2, OUTPUT );
  pinMode( K3, OUTPUT );
  pinMode( Power, INPUT );
  pinMode( Charging, INPUT );
  pinMode( Manual, INPUT );
  pinMode( GetValues, INPUT );

  attachInterrupt( digitalPinToInterrupt( GetValues ), ISR_GetValues, RISING );

  Serial.begin(9600);
}//setup

void loop()
{
  const int ST_POWER = LOW;
  const int ST_CHARGING = LOW;
  const int ST_MANUAL = LOW;
  const int ST_CHECK_CURRS = LOW;
  static byte stateControl = ST_POWER;

  switch ( stateControl )
  {
    case  ST_POWER:
      //Power
      if ( digitalRead( Power ) == HIGH ) {
        stateControl = ST_CHARGING;
      }

      break;

    case  ST_CHARGING:
      //Charging on?
      if ( digitalRead( Charging ) == LOW ) {
        //No
        stateControl = ST_MANUAL;
      }

      else {
        //Yes
        digitalWrite( K1, LOW );
        digitalWrite( K2, LOW );
        digitalWrite( K3, HIGH );
        stateControl = ST_CHARGING; //redundant, presented for illustrative purposes
      }//else

      break;

    case  ST_MANUAL:
      //Manual mode on?
      if ( digitalRead( Manual ) == LOW ) {
        //No
        stateControl = ST_CHECK_CURRS;
      }

      else {
        //Yes
        //Manual Operation of IN1, INT2, IN3
        //assumed to return false when "finished" manual operation
        //when done, go back to charging state
        if ( !HandleManualInputs() ) {
          stateControl = ST_CHARGING;
        }
      }//else

      break;

    case  ST_CHECK_CURRS:
      //Is Ipv > 0A?
      if ( current_mA_PV > 0.0 ) {
        //Yes
        digitalWrite( K2, HIGH );
        //Is Il = Ipv?
        if ( current_mA_Load == current_mA_PV ) {
          //Yes
          digitalWrite( K1, LOW );
          digitalWrite( K3, LOW );
        }//if
        //No
        //Is Il > Ipv?
        else if ( current_mA_Load > current_mA_PV ) {
          //Yes
          digitalWrite( K1, HIGH );
          digitalWrite( K3, LOW );
        }//else if
        //No
        //Is Il < Ipv?
        else {
          //Yes
          digitalWrite( K1, HIGH );
          digitalWrite( K3, LOW );
        }//else

      }//if
      //No
      //Is Il <= Ibatt?
      else if ( current_mA_Load <= current_mA_Batt ) {
        //Yes
        digitalWrite( K1, LOW );
        digitalWrite( K2, HIGH );
        digitalWrite( K3, HIGH );
      }//else if
      //No
      //Is Il > Ibatt?
      else {
        //Yes
        digitalWrite( K1, HIGH );
        digitalWrite( K2, LOW );
        digitalWrite( K3, LOW );
      }//else
      //No
      //Go back to chargin state
      stateControl = ST_CHARGING;
      break;
  }//switch
}//loop

bool HandleManualInputs( void )
{
  //"Manual Operation of IN1, IN2 and IN3"
  if ( digitalRead(Manual) == HIGH ) {
    digitalWrite( K1, LOW );
    digitalWrite( K2, LOW );
    digitalWrite( K3, LOW );
  }
}//HandleManualInputs

void ISR_GetValues( void )
{
  //"Get voltage/current of PV, Gen, Load and Batt"
  if (InterruptState = digitalRead(GetValues))
  {
    Serial.println("              INA219_PV  |   INA219_Load   ");
    Serial.print("Load Voltage:  "); Serial.print(loadvoltage_PV); Serial.print("      | "); Serial.print(loadvoltage_Load); Serial.println(" V");
    Serial.print("Current:       "); Serial.print(current_mA_PV); Serial.print("       | "); Serial.print(current_mA_Load); Serial.println("  mA");
    Serial.print("Power:         "); Serial.print(power_mW_PV); Serial.print("         | "); Serial.print(power_mW_Load); Serial.println("     mW");
    Serial.println("");
    /*Serial.print("Charge:   "); Serial.print(soc); Serial.println(" %");
    Serial.print("Voltage:   "); Serial.print(volts); Serial.println(" mV");
    Serial.print("Current:   "); Serial.print(current); Serial.println(" mA");
    Serial.println("--------------------------------------------------------");*/
  }
}//ISR_GetValues
 const int ST_POWER = LOW;
  const int ST_CHARGING = LOW;
  const int ST_MANUAL = LOW;
  const int ST_CHECK_CURRS = LOW;

Because each of these have the same value the switch/case cannot distinguish between them to decide which code to execute, hence the error.

Give each of them a different value

  const int ST_POWER = 0;
  const int ST_CHARGING = 1;
  const int ST_MANUAL = 2;
  const int ST_CHECK_CURRS = 3;

As suggested previously using an enum is a handy way to do it.

Either way the switch/case will be able to distinguish between them and run the associated code.