#define Preprocessor Problem

I would like to be able to use a macro to set and clear pins that aren't supported by Arduino. I can do that easily with:

bitClear(PORTD, 7)

What I would like to do is this:

#define ALERTLED     PORTD,7

bitClear(ALERTLED);

But I get an error during compilation:

error: macro "bitClear" requires 2 arguments, but only 1 given

Is this possible? Am I doing something wrong?

Thanks,

John

In my opinion, this is preprocessor abuse even if it worked. The only thing I can think of is that for some reason it is turning the comma from an argument separator into a comma operator.

Did you have some extra parentheses that you aren't showing?

No, that is straight out of the sketch.

Your call on the comma makes sense.

I need an elegant way to manipulate pins that aren't defined in Arduino. Do you know of a good way to do that?

#define MANIP_ALERTLED bitSet(PORTD,7)

A truly elegant approach would be extending digitalWrite() to accept higher pin numbers. In that, it maintains interface compatibility with the other pins, and anyone who has ever programmed an Arduino would instantly understand it.

I was afraid you were going to say that. :smiley:

I'm not sure why I was avoiding that. I guess my OCD wanted it to look more "code" like.

Thanks for the help,

John

KeithRB:
#define MANIP_ALERTLED bitSet(PORTD,7)

This is okay, but MANIP is pretty weird. I'd use SET.

#define ALERTLED     PORTD,7

#define bitOn(p) bitSet(p)

void setup() 
{
  bitOn(ALERTLED);
}

void loop() {}

CB your experience is showing.

Either that or I just did what the compiler told me to do...

error: macro "bitClear" requires 2 arguments, but only 1 given

:smiling_imp:

Shouldn't it be - macro "bitSet" requires 2 arguments?

This works also:

#define BITSET(...)   bitSet(__VA_ARGS__)
#define BITCLEAR(...) bitClear(__VA_ARGS__)
#define ALERTLED PORTB,0 //pin D8

void setup() {                
  // initialize the digital pin  8 as an output.
  pinMode(8, OUTPUT);     
}

void loop() {
  BITSET(ALERTLED);
  delay(500);
  BITCLEAR(ALERTLED);
  delay(500);
}

I couldn't find an explanation, that I could understand, of these situations.

Kind of obviously, any literal 'p' that is seen in bitOn, will be substituted in bitSet during compilation, no?

LarryD:
This works also:

#define BITSET(...)   bitSet(__VA_ARGS__)

#define BITCLEAR(...) bitClear(VA_ARGS)
#define ALERTLED PORTB,0 //pin D8

What goes in the place of the ellipses?

Also, looking at things and using what little understanding I have, this would work as well?

#define ALERTLED     PORTB,0
#define ACTIVITYLED  PORTB,1
#define HEARTBEATLED PORTB,2
#define BITSET(...)   bitSet(__VA_ARGS__)
#define BITCLEAR(...) bitClear(__VA_ARGS__)

Thanks for all the ideas and help,

John

Don't ask. Try. You have an Arduino. Create a complete sketch (with setup and loop) and try to upload your code to the Arduino.

Larry would not have posted "this works" unless he had done exactly that. You did notice that his sketch was a complete, running version of Blink?

ellipsis "..." is used to indicate that one or more arguments must be passed

jecottrell:
Kind of obviously, any literal 'p' that is seen in bitOn, will be substituted in bitSet during compilation, no?

Correct. The whole thing works because the preprocessor applies macros iteratively / recursively. You may be able to deduce when the iteration / recursion is applied by the fact that your original attempt did not work.

Also:

If your macro is complicated, you may want a more descriptive name for the variable argument than VA_ARGS. CPP permits this, as an extension. You may write an argument name immediately before the ‘...’; that name is used for the variable argument.

This
#define BITSET(...) bitSet(VA_ARGS)
Could be this:
#define BITSET(args...) bitSet(args)