Using constants that might not be declared for some boards

Hi all,

I need to use a constant in my code which in some cases, e.g. for some boards, will not be declared. How can I do this without getting a compiler error?

Context: Assume I want to convert an ESP32's physical touch pin number (e.g. pin 32) to the "human readable" touch pin index number (e.g. 9 for touch9) with the function

int touchPinToIndex(int pin);

Of course, I'll need to use the constants defined in the ESP32's pins_arduino.h for that:

static const uint8_t T0 = 4;
static const uint8_t T1 = 0;
...
static const uint8_t T9 = 32;

Implementation is straightforward, e.g. with an array {T0, T1, T2, T3, T4, T5, T6, T7, T8, T9}, where I can look up the pin number, or with a long switch statement.

Now here's the part I'm struggling with: Not all ESP32 boards use all 10 available touch pins. The const declarations for the d-duino-32, for example, stop at T6, as this board only has seven touch pins available.

As a consequence, the above implementations will not compile, because T7...T9 are not declared.

Is there an easy way to work around this that I'm not seeing? Something like the preprocessor's #ifdef for constants?

Jan

This is precisely what #ifdef is used for - but you need to know which #define's are pertinent to the boards in question as the preprocessor only knows about preprocessor things, not const definitions.

You mean #ifdef arduino_board_d-duino-32 or whatever the correct macro name is for identifying boards?

This would be neither a simple nor a safe solution, as it would only safeguard against existing boards, not against boards added to the core in the future.

Jan

Huh? You ifdef to guard the code refering to the board-specific stuff, so it is safe against other boards.

Let's assume I use a switch statement.

  switch (pin) {
    case (T0): {
        result = 0;
        break;
      }
...
#ifndef arduino_board_d-duino-32 // or whatever the correct macro is called
    case (T7): {
        result = 7;
        break;
      }
    case (T8): {
        result = 8;
        break;
      }
    case (T9): {
        result = 9;
        break;
      }
#endif
  }

First, I'd have to check all existing pin_arduino.h to see what other boards don't use all 10 pins, and second this would only work for existing boards.

Jan

The trick is NORMALLY to use more "proximate" symbols.

  switch (pin) {
    case (T0): {
        result = 0;
        break;
      }
...
#ifdef T7
    case (T7): {
        result = 7;
        break;
      }
#endif
#ifdef T8
    case (T8): {
        result = 8;
        break;
      }
#endif
// etc

Unfortunately, I don't believe that this will work if the symbols are a "more modern" static const int style :frowning:

... take a look under the hood for ideas.

Yes, it's funny that the accepted good practice today is to use consts, not #defines, yet in this specific case it would have made things easier. Not that it's an argument for #defines, but noteworthy nevertheless.

Ok. I assume you're thinking more precisely of the digitalPinToTouchChannel() function and the touch_sensor_channel_io_map. I wasn't aware of them, you're right, and I'm ready to mark this as an overly cryptic, yet correct solution.

However, it is only a solution for this specific case.

I'd still be interested if there's a way around the general problem, which I think could come up in other constellations as well, particularly as today's above mentioned good practice is to give up on macro defines in favor of const declarations.

From the discussion up to now I take it that there simply is no easy answer to my initial question, though, but maybe there's still other thoughts.

Jan

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