How can I output an error message through the compiler with a class?

I'm trying with my class to programm an traffic light pole and we are still at the beginning but now we are working on a button class.
The button class has a static method which is calling an interupt routine on Pin 2 or 3, now I want to output an error message if the wrong pin(integer) was set in the .ino file.

I've seen this example but i couldn't figure out how to implement it in my code.

How can I show an error?
Is there an README file or an Website showing/explaining what I need?
Or is it stupid to do this in an method?

The example:

#define interruptPin 2
//confirm the correct interrupt pin has been selected
#if interruptPin != 2 && interruptPin != 3
#error interruptPin must be 2 or 3!
#endif

The static method:

static void Button::ISRswitch(int pin) {

  if (pin == 2) {
    attachInterrupt(digitalPinToInterrupt(2), isr, FALLING);  
  } else if (pin == 3) {
    attachInterrupt(digitalPinToInterrupt(3), isr, FALLING);
  } else {
   //confirm the wrong interrupt pin has been selected
  
  }
}
void Button::isr() {
  // Something would come in here
}

You mean:

  if (pin == 2) {
    attachInterrupt(digitalPinToInterrupt(2), isr, FALLING);  
  } else if (pin == 3) {
1 Like

oh my god, yes. I didn't see that, Thanks

Sorry I can't help with generating a compile-time error in run-time code. I don't think you can. To find an error at compile time you have to be working with compile-time constants. I don't see how you can determine if the argument to a function is going to be a 2, a 3, or something else.

I see, I could make an work around with some #ifdef and #if/#else but this would be a bit unnecessary and to complicated for the stuff that I needed for.

But thank you very much!

What about this?

void isr() {
  // Something here.
}

template <uint8_t pin> void ISRswitch() {
  static_assert(pin == 2 or pin == 3, "interruptPin must be 2 or 3");
  attachInterrupt(digitalPinToInterrupt(pin), isr, FALLING);
  Serial.println(pin);
}


void setup() {
  Serial.begin(9600);
  
  ISRswitch<2>();  // Prints '2'.
  ISRswitch<3>();  // Prints '3'.
  //ISRswitch<4>();  // Gives: "error: static assertion failed: interruptPin must be 2 or 3".
}

void loop() {}

Or if you want to use a static member function:

class Button {
public:
  static void isr() {
    // Something here.
  }

  template <uint8_t pin> static void ISRswitch() {
    static_assert(pin == 2 or pin == 3, "interruptPin must be 2 or 3");
    attachInterrupt(digitalPinToInterrupt(pin), isr, FALLING);
    Serial.println(pin);
  }
};


void setup() {
  Serial.begin(9600);

  Button button;
  button.ISRswitch<2>();  // Prints '2'.
  button.ISRswitch<3>();  // Prints '3'.
  //button.ISRswitch<4>();  // Gives: "error: static assertion failed: interruptPin must be 2 or 3".
}

void loop() {}
1 Like

Inlude that example before every call to Button::ISRswitch(). with the actual pin number. Possibly #undef interruptPin is required between calls.

Why can't you use the #defined pin number as a constant in your code?

Or a macro like this (untested!)

#define checkPin(pin) \
#if pin != 2 && pin != 3
#error ...
#endif
1 Like

I haven't used/worked with macros and I'm too stupid right now to use it correctly.
Maybe I will use these macros later if I understand them, but now i will go templates.

This will work perfectly fine, I didn't know there was such thing like templates.
Thank you very much, this will work for this project :smile:

C++ is a huge language. I suspect few people know all the ins and outs, I certainly do not.

I would prefer templates, inline functions, constants, etc. over macros any time. You may want to read: So, what's wrong with using macros? near the bottom of the page.

1 Like

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.