Case labels only if global variables exist

14 hours ago 1
ARTICLE AD BOX

I am writing an Arduino program that takes in commands via serial. One of these commands is "Read the specified analog input". The relevant code basically looks like this:

switch (Channel) { case 0: write(analogRead(A0)); break; case 1: write(analogRead(A1)); break; case 2: write(analogRead(A2)); break; case 3: write(analogRead(A3)); break; // ...... }

Different boards/controllers have different numbers of analog inputs (possible non-contiguous). I don't want to have to edit the code and comment-out sections (and then potentially forget to un-comment those later) when using this for different boards. Ideally, I would like something like this:

switch (Channel) { #ifdef A0 case 0: Serial.write(A0); break; #endif #ifdef A1 case 1: Serial.write(A1); break; #endif #ifdef A2 case 2: Serial.write(A2); break; #endif #ifdef A3 case 3: Serial.write(A3); break; #endif // ...... }

This would work if A0, A1, etc. were preprocessor macros, but they are not. They are declared in hardware-specific "pins_arduino.h" files as static const uint8_t A0 = ...; (global, i.e. not inside a class).

How can I "activate" (so to speak) a case label and the corresponding code if a specified global variable exists? I suspect that some SFINAE template magic would be possible.

Additional notes:

It does not have to be a case label. It could also be a long chain of these:

if constexpr (A0 exists) { if (Channel == 0) { Serial.write(A0); return; // (Can't chain else-if here) } } if constexpr (A1 exists) { if (Channel == 1) { Serial.write(A1); return; // (Can't chain else-if here) } }

I intend to use this from Arduino IDE 2 with whatever compiler that uses (e.g. avr-gcc). MSVC's __if_exists isn't available here.

Feel free to point out Arduino-specific workarounds in the comments, but I might need this kind of thing in other situations too, so I won't accept a workaround as an answer.

I've noticed that some boards (e.g. Arduino Leonardo) declare A0 and such like static const uint8_t A0 = PIN_A0;, where PIN_A0 is a macro (e.g. #define PIN_A0 (14)). So #ifdef Pin_A0 would work. But not all boards do this, so it's not a viable workaround.

Read Entire Article