I'm trying to program an Arduino Due to PWM a LED matrix by turning the LEDs on and off very quickly. In order to control brightness I want to add extra instructions between the on and off states of the LEDs. The brightness should be set by a preprocessor variable. The Arduino has a 84MHz Cortex-M3 ARM processor.
This is a simplification of how my code currently increases the brightness:
uint8_t volatile dummy = 0;
uint8_t i;
for (i=0;i<1<<current_layer;i++) { // every next layer has double the amount of pulses
LED_STATE = ON; // several pulses in one go speeds up the for loop
dummy = 0; // increases ON-time
LED_STATE = OFF;
LED_STATE = ON;
dummy = 0;
LED_STATE = OFF;
LED_STATE = ON;
dummy = 0;
LED_STATE = OFF;
LED_STATE = ON;
dummy = 0;
LED_STATE = OFF;
}
Now I want to be able to increase the brightness based on a preprocessor variable like so:
#define BRIGHTNESS 2
// inside loop
LED_STATE = ON; // several pulses in one go speeds up the for loop
#if BRIGHTNESS > 0
dummy = 0; // increases ON-time
#if BRIGHTNESS == 2
dummy = 0; // increases ON-time even more
#endif
#endif
LED_STATE = OFF;
LED_STATE = ON;
#if BRIGHTNESS > 0
dummy = 0;
#if BRIGHTNESS == 2
dummy = 0;
#endif
#endif
LED_STATE = OFF;
LED_STATE = ON;
#if BRIGHTNESS > 0
dummy = 0;
#if BRIGHTNESS == 2
dummy = 0;
#endif
#endif
LED_STATE = OFF;
LED_STATE = ON;
#if BRIGHTNESS > 0
dummy = 0;
#if BRIGHTNESS == 2
dummy = 0;
#endif
#endif
LED_STATE = OFF;
As you can see, this makes the code very unreadable. I would like to define a preprocessor macro that adds these dummy statements based on the value of BRIGHTNESS
.
This is how the code should look like:
#define BRIGHTNESS 2
#define B1 ... // adds dummy=0; when BRIGHTNESS > 0 or else nothing at all
#define B2 ...
#define B3 ...
#define B4 ...
// inside loop
LED_STATE = ON;
B1 B2 B3 B4 // adds a number of dummy statements based on the value of BRIGHTNESS
LED_STATE = OFF;
LED_STATE = ON;
B1 B2 B3 B4
LED_STATE = OFF;
LED_STATE = ON;
B1 B2 B3 B4
LED_STATE = OFF;
LED_STATE = ON;
B1 B2 B3 B4
LED_STATE = OFF;
Even better would be a function that inserts those statements based on a variable:
#define ADD_DUMMIES ...
// inside loop
LED_STATE = ON;
ADD_DUMMIES(BRIGHNESS)
LED_STATE = OFF;
How would I define preprocessor macros so that they insert dummy statements based on the value of BRIGHTNESS
?
This is how the dummy = 0;
statements can be added with the help of the preprocessor:
#define BRIGHTNESS 2
#define _GETFOO(n) _FOO ## n
#define ADD_DUMMIES(n) _GETFOO(n) ()
#define _FOO0()
#define _FOO1() dummy = 0;
#define _FOO2() dummy = 0; dummy = 0;
#define _FOO3() dummy = 0; dummy = 0; dummy = 0;
#define _FOO4() dummy = 0; dummy = 0; dummy = 0; dummy = 0;
uint8_t volatile dummy = 0;
// inside loop
LED_STATE = ON;
ADD_DUMMIES(BRIGHTNESS)
LED_STATE = OFF;
LED_STATE = ON;
ADD_DUMMIES(BRIGHTNESS)
LED_STATE = OFF;
LED_STATE = ON;
ADD_DUMMIES(BRIGHTNESS)
LED_STATE = OFF;
LED_STATE = ON;
ADD_DUMMIES(BRIGHTNESS)
LED_STATE = OFF;
The compiler inserts the same store instruction as many times inbetween the lines as the value of BRIGHTNESS
dictates, as long as it is within the boundaries.