Macro expansion and expected token error in ENUM for pinMode variables

Hi All, can anyone please explain, shine a light or show me the way kindly :sob:. I can't seem to understand the error. My hypothesis is that INPUT_PULLUP AND INPUT_PULLDOWN are hard defined as in 0x04, 0x05 and I am causing an issue enumerating it. here is the part of my code that wont compile:

#include <EdgeDebounceLite.h>

//PINS & BUTTONS//
byte routinePin[2] = {3, 4}; //push buttons to be used with debounce

// Switch states
enum SwitchStates {IS_OPEN, IS_RISING, IS_CLOSED, IS_FALLING };
SwitchStates switchState[2] = {IS_OPEN, IS_OPEN }; // both switches are in is open initially

// 
enum SwitchModes {PULLUP, PULLDOWN}; //the two possible modes the pins could be in
SwitchModes switchMode[2] = {PULLUP, PULLUP}; // I am focused on states where both switches are in pullup mode.


//FLAGS
bool hasRout1_strtd() {                     //Routine 1 active?
  switchMachine(0);                           //Read switch 0
  if (switchState[0] == IS_FALLING)           //If it is in the state IS_FALLING
    return true;                                //R1 started, return true
  else                                        //If not
    return false;                               //return false
}

bool hasRout2_strtd() {                     //Routine 2 active?
  switchMachine(1);                           //Read switch 1
  if (switchState[1] == IS_FALLING)           //If it is in the state IS_FALLING
    return true;                                //R2 started, return true
  else                                        //If not
    return false;                               //return false
}

void switchMachine(byte i) {
  byte pinIs = debounce.pin(routinePin[i]);
  if (switchMode[i]) == PULLUP) //check the mode of the pin, if in pullup change state
    switch (switchState[i]) {
      case IS_OPEN:    {                                //State is IS_OPEN
      if(pinIs == HIGH)                                 //If the pin is HIGH
        switchState[i] = IS_RISING;                       //We just changed form LOW to HIGH: State is now IS_RISING 
      break;                                            //Get out of switch
    }
    case IS_RISING:  {                                //State is IS_RISING
      switchState[i] = IS_CLOSED;                       //It is not rising anymore, State is now IS_CLOSED
      break;                                            //Get out of switch
    }
    case IS_CLOSED:  {                               //State is IS_CLOSED
      if(pinIs == LOW)                                 //If the pin is LOW
        switchState[i] = IS_FALLING;                     //We just changed from HIGH to LOW: State is now IS_FALLING 
      break;                                           //Get out of switch 
    }
    case IS_FALLING: {                               //State is IS_FALLING
      switchState[i] = IS_OPEN;                        //It is not falling anymore, State is now IS_OPEN    
      break;                     
    }
  }
}

I get an error here:

// 
enum SwitchModes {PULLUP, PULLDOWN}; //the two possible modes the pins could be in
SwitchModes switchMode[2] = {PULLUP, PULLUP}; // I am focused on states where both switches are in pullup mode.

errors:

  1. error: expected unqualified-id before numeric constant
  2. error: expected '}' before numeric constant
  3. note: in expansion of macro 'PULLUP' enum SwitchModes {PULLUP, PULLDOWN};

I wonder if the fix would be the result of the pinMode, so instead of the states being either PULL UP or PULL DOWN, they would be HIGH or LOW?

Try to change it to something less common, for example MY_PULLUP

post the entire code and the complete error message

the error message will identify the line # of the error.

Macro expansion and expected token error in ENUM for pinMode
suggests the error involves "pinMode()" but the posted code doesn't have it

also i don't believe "INPUT_PULLDOWN" exists

Okay the entire code is a bit long but here it goes. it's a 4 stage dosing system. with currently two push buttons. There is a state machine and flag system tied in with a debouncer library. It essentially allows me to go from an IS_OPEN state to a IS_FALLING when the signal is low (reverse clause).

I use this to drive my flags as a button pressed, true or false for my main state machine. I got the example of this from here.

#include <Adafruit_MotorShield.h>
#include <EdgeDebounceLite.h>


//to do figure out timing intervals and whether or not you will remove the delay
EdgeDebounceLite debounce;


Adafruit_MotorShield AFMS = Adafruit_MotorShield();
Adafruit_DCMotor *Dose1 = AFMS.getMotor(1);   //pump 1
Adafruit_DCMotor *Dose2 = AFMS.getMotor(2);  //pump 2
Adafruit_DCMotor *Dose3 = AFMS.getMotor(3); //pump 3
Adafruit_DCMotor *Dose4 = AFMS.getMotor(4);//pump 4


/*GLOBAL VARIABLES */

//PINS & BUTTONS//
byte routinePin[2] = {3, 4}; //push buttons to be used with debounce

#define Gledstatus 6
#define Bledstatus 7
#define Rledstatus 8 

/*ROUTINE 1 TIMING VARIABLES*/
//Global to routine 1 and 2 maybe?? as time tracking variables//
unsigned long mDc_on; // similar to how previousMillis= currentmillis, a variable for how long a dose has run for
unsigned long Routine1Millis; //how long since routine 1 button was pressed

//Changing timwe intervals//
//I have left them all the same value for now for my brain

unsigned long mD1wait_interval = 2500; // Pump off time
unsigned long mD1run_interval = 5000; // Pump on time
//dose 2 with motor 2
unsigned long mD2wait_interval = 500; //
unsigned long mD2run_interval = 15000; //
// dose 3 with motor 3
unsigned long mD3wait_interval = 500; //
unsigned long mD3run_interval = 15000; //
//dose 4 with motor 4
unsigned long mD4wait_interval = 500; //
unsigned long mD4run_interval = 15000; //

/*ROUTINE 2 TIMING VARIABLES*/

//routine 2 as time tracking variables unsure if I need these//
unsigned long mDc2_on; // similar to how previousMillis= currentmillis, a variable for how long a dose has run for
unsigned long Routine2Millis; //how long since routine 2 button was pressed

//Changing time intervals//
//I have left them all the same value for now for my brain

unsigned long mD1bwait_interval = 2500; // Pump off time
unsigned long mD1brun_interval = 5000; // Pump on time
//dose 2 with motor 2
unsigned long mD2bwait_interval = 500; //
unsigned long mD2brun_interval = 15000; //
// dose 3 with motor 3
unsigned long mD3bwait_interval = 500; //
unsigned long mD3brun_interval = 15000; //
//dose 4 with motor 4
unsigned long mD4bwait_interval = 500; //
unsigned long mD4brun_interval = 15000; //

/*MAIN STATE MACHINE STATES*/

enum DosingSystemStates{idle, DOSINGA, DOSINGB, DOSEFINISH };
DosingSystemStates dosingSystemState = idle;

// Switch states
enum SwitchStates {IS_OPEN, IS_RISING, IS_CLOSED, IS_FALLING };
SwitchStates switchState[2] = {IS_OPEN, IS_OPEN }; // both switches are in is open

// 
enum SwitchModes {PULLUP, PULLDOWN}; //the two possible modes the pins could be in
SwitchModes switchMode[2] = {PULLUP, PULLUP}; // I am focused on states where both switches are in pullup mode.


//FLAGS
bool hasRout1_strtd() {                     //Routine 1 active?
  switchMachine(0);                           //Read switch 0
  if (switchState[0] == IS_FALLING)           //If it is in the state IS_FALLING
    return true;                                //R1 started, return true
  else                                        //If not
    return false;                               //return false
}

bool hasRout2_strtd() {                     //Routine 2 active?
  switchMachine(1);                           //Read switch 1
  if (switchState[1] == IS_FALLING)           //If it is in the state IS_FALLING
    return true;                                //R2 started, return true
  else                                        //If not
    return false;                               //return false
}

void switchMachine(byte i) {
  byte pinIs = debounce.pin(routinePin[i]);
  if (switchMode[i]) == INPUT_PULLUP)
    switch (switchState[i]) {
      case IS_OPEN:    {                                //State is IS_OPEN
      if(pinIs == HIGH)                                 //If the pin is HIGH
        switchState[i] = IS_RISING;                       //We just changed form LOW to HIGH: State is now IS_RISING 
      break;                                            //Get out of switch
    }
    case IS_RISING:  {                                //State is IS_RISING
      switchState[i] = IS_CLOSED;                       //It is not rising anymore, State is now IS_CLOSED
      break;                                            //Get out of switch
    }
    case IS_CLOSED:  {                               //State is IS_CLOSED
      if(pinIs == LOW)                                 //If the pin is LOW
        switchState[i] = IS_FALLING;                     //We just changed from HIGH to LOW: State is now IS_FALLING 
      break;                                           //Get out of switch 
    }
    case IS_FALLING: {                               //State is IS_FALLING
      switchState[i] = IS_OPEN;                        //It is not falling anymore, State is now IS_OPEN    
      break;                     
    }
  }
}

void DosingSystem(){
switch(dosingSystemState) {
  case idle: 
    //check the time, I'm not sure yet whether this is logically illegal
    //but I think if it is global to the case/state then it applies to all
    //aspects of the if statement within it, please correct otherwise
    unsigned long currentMillis = millis(); //
    
    if (hasRout1_strtd())
    Routine1Millis = currentMillis; //if routine 1 button is pressed/TRUE start routine 1 timer/ get a snapshot of the time for void DoseR1()
    dosingSystemState = DOSINGA; // go to dosing state A
    
    if (hasRout2_strtd())          //if routine 2 button is pressed/TRUE same for the above
    Routine2Millis = currentMillis;
   
    dosingSystemState = DOSINGB;// go to dosing state B

    //might add connection to https server here, depends on my ESP32 abilities
    //might be my 2nd forum post when I break it :3
    
    break;
    
  case DOSINGA:
   DoseR1(); /// dose r2 is idential for now for simplicity, but essentially, r1 is the concept I am going for
    // How do we link/track the execution of this function
    // and the main stateso that the main state machine progresses
    // when DoseR1(); is completed, how does the below line execute?
    dosingSystemState = DOSEFINISH;
    break;
    
  case DOSINGB:
  DoseR2();
  dosingSystemState = DOSEFINISH;
    break;
 
  case DOSEFINISH:
  //do somethinggggggg then return to idle I guess
  dosingSystemState = idle;
    break;
}
}

  // put your setup code here, to run once:
void setup() {
  // put your setup code here, to run once:
Serial.begin(9600);           // Serial connection for Debug
  Serial.println("Starting Unity");
  
  // put your setup code here, to run once:
if (!AFMS.begin()) {         // create with the default frequency 1.6KHz
  // if (!AFMS.begin(1000)) {  // OR with a different frequency, say 1KHz
    Serial.println("MDriver not working");
    while (1);
  }
  Serial.println("MDriver working.");

//Setting buttons as pull ups
for (int i = 0 ; i < 2 ; i++)             //For each switch
    pinMode(RoutinePin[i], INPUT_PULLUP);
}

void loop() {
  // put your main code here, to run repeatedly:
void DosingSystem()
}

void DoseR1()
{
static enum {DOSE1ra, DOSE1a, DOSE2ra, DOSE2a, DOSE3ra, 
DOSE3a, DOSE4ra, DOSE4a, DOSEr1CMP} pumpR1State = DOSE1ra;

//1ra wait state
//1a dose state

  switch (pumpR1State)
  {
    case DOSE1ra:
      //Serial.println("pump1 should have been on after .5 seconds");
      if (currentMillis - Routine1Millis >= mD1wait_interval)
      {
        Dose1->setSpeed(150);
        Dose1->run(FORWARD);
        mDc_on = currentMillis;
        pumpR1State = DOSE1a;
      }
      break;

    case DOSE1a:
      if (currentMillis - mDc_on >= mD1run_interval) //will shut down after the run interval is met
      {
        Dose1->fullOff();
        mDc_on = currentMillis;//resetting the difference everytime 
        pumpR1State = DOSE2ra;
      }
      break;
      
    case DOSE2ra:
       if (currentMillis - mDc_on >= mD2wait_interval) //wait then run
      {
        Dose2->setSpeed(150);
        Dose2->run(FORWARD);
        mDc_on = currentMillis; //resetting the difference everytime 
        pumpR1State = DOSE2a;
      }
    break;
    
   case DOSE2a:
       if (currentMillis - mDc_on >= mD2run_interval) //will shut down after the run interval is met
      {
        Dose2->fullOff();
        mDc_on = currentMillis; //resetting the difference everytime 
        pumpR1State = DOSE3ra;
      }
    break;
    
   case DOSE3ra:
       if (currentMillis - mDc_on >= mD3wait_interval) //wait then run
      {
        Dose3->setSpeed(150);
        Dose3->run(FORWARD);
        mDc_on = currentMillis;
        pumpR1State = DOSE3a;
      }
    break;

    case DOSE3a:
       if (currentMillis - mDc_on >= mD3run_interval) //will shut down after the run interval is met 
      {
        Dose3->fullOff();
        mDc_on = currentMillis; //resetting the difference everytime
        pumpR1State = DOSE4ra;
      }
    break;
    
    case DOSE4ra:
       if (currentMillis - mDc_on >= mD4wait_interval) //wait then run 
      {
        Dose4->setSpeed(150);
        Dose4->run(FORWARD);
        mDc_on = currentMillis;
       pumpR1State = DOSE4a;
      }
    break;
    
    case DOSE4a:
       if (currentMillis - mDc_on >= mD4run_interval) //will shut down after the run interval is met 
      {
        Dose4->fullOff();
        mDc_on = currentMillis; //resetting the difference everytime
        pumpR1State = DOSEr1CMP;
      }
    case DOSEr1CMP:
// DO something with the web interface probably a data logging or function tracking statement, some led's, some buzzer, still thinking for now.
        mDc_on = currentMillis; //resetting the difference everytime
        pumpR1State = DOSE1ra;
  }
}
       
void DoseR2(){
  }

where is the error listing with the line #s


what about simply

bool isFalling ( int id )
{
    return IS_FALLING == switchState [id];
}

instead of

[quote="vindictae, post:1, topic:1065122"]

bool hasRout1_strtd() {                     //Routine 1 active?
  switchMachine(0);                           //Read switch 0
  if (switchState[0] == IS_FALLING)           //If it is in the state IS_FALLING
    return true;                                //R1 started, return true
  else                                        //If not
    return false;                               //return false
}

bool hasRout2_strtd() {                     //Routine 2 active?
  switchMachine(1);                           //Read switch 1
  if (switchState[1] == IS_FALLING)           //If it is in the state IS_FALLING
    return true;                                //R2 started, return true
  else                                        //If not
    return false;                               //return false
}

what is a 4-stage dosing machine?

would like to know what it is intended to do before an explanation of how it is implemented with flags and state machine

enum SwitchModes {PULLUP, PULLDOWN}; //the two possible modes the pins could be in

line 76 it throws issue with using PULLUP, PULLDOWN

where is the error message ????

Simply, 4 motors will dose materials separately over timed intervals. I want two separate routines for now, when I press button 1, I'll do one kind of dosing routine. When I press button 2, I'll do another. All non blocking ofc.

Please copy exact error message, do not describe it in words

According to the error messages, the define PULLUP already used in system files of the esp32 core:

esp32-hal-gpio.h:49:27: error: expected '}' before numeric constant
 #define PULLUP            0x04

So you must choose the another name

That means that somewhere in your code (possibly in Adafruit_MotorShield.h or EdgeDebounceLite.h) is a #define PULLUP. The macro is replacing your enum name and causing confusion. The full error message might have useful information about the source of the macro.

Update: @b707 beat me to it. The macro in the core:
#define PULLUP 0x04
makes your code look like:

enum SwitchModes { 0x04, PULLDOWN}; //the two possible modes the pins could be in
SwitchModes switchMode[2] = { 0x04,  0x04}; // I am focused on states where both switches are in pullup mode.

You can't use 0x04 as an identifier so you can't put it in an enum.

1 Like
 error: expected identifier before numeric constant
 #define PULLUP            0x04

in expansion of macro 'PULLUP'
 enum SwitchModes {PULLUP, PULLDOWN}; //the two possible modes the pins could be in

error: expected '}' before numeric constant
 #define PULLUP            0x04

in expansion of macro 'PULLUP'
 enum SwitchModes {PULLUP, PULLDOWN}; //the two possible modes the pins could be in

ote: to match this '{'
 enum SwitchModes {PULLUP, PULLDOWN}; //the two possible modes the pins could be in

error: expected unqualified-id before numeric constant
 #define PULLUP            0x04

note: in expansion of macro 'PULLUP'
 enum SwitchModes {PULLUP, PULLDOWN}; //the two possible modes the pins could be in

 error: expected declaration before '}' token
 enum SwitchModes {PULLUP, PULLDOWN}; //the two possible modes the pins could be in


Had to delete my last post as I'm using the lab, however yes I am using the esp 32 and I'm pretty sure alot of arduino type boards use pullup/pull down etc.

\hardware\esp32\2.0.5\cores\esp32/Arduino.h:36,
                 from C:\Users\somorin.jo\AppData\Local\Temp\arduino-sketch-224BFA39AFAA94EF9A2FBFA8CAA373CF\sketch\UNITY_1.2d.ino.cpp:1:
C:\Users\somorin.jo\AppData\Local\Arduino15\packages\esp32\hardware\esp32\2.0.5\cores\esp32/esp32-hal-gpio.h:49:27: error: expected identifier before numeric constant
 #define PULLUP            0x04

Hi @johnwasser nice to see you here, I responded to your help on my other post! Thanks alot.

Okay my question to you all is that from the verbose i see it is coming out of the hardware package itself:

\Arduino15\packages\esp32\hardware\esp32\2.0.5\cores\esp32/esp32-hal-gpio.h:49:27: error: expected unqualified-id before numeric constant
 #define PULLUP            0x04
                           ^~~~```

Note that all your "deleted" messages in the forum available for everyone, just click to the "edit" icon above the message

Okay, so reading all of your helpful comments, I simply must use slightly different names?

so you should rename your enum

Slightly different or very different, as long as you don't use "PULLUP". :slight_smile:

Yes thank you very much hahah I'm wading deep into these things and it's all coming at once, its an oversight. Very very appreciative that you guys help out this way!

Thank you very much @gcjr @johnwasser @b707

let me go tinker with it and I will close this when compiled!!