Исчерпывающий ответ на вопрос есть тут
Если коротко - то для const действуют области видимости, есть тип, и по сути это обычные переменные доступные только для чтения - поэтому там где нужно именно число которое не должно меняться ни при каких условиях я бы использовал именно const int.
#define ценен с директивами #if, #elif, #else и #endif когда необходимо управлять компиляцией частей исходного файла. Например этот оператор можно использовать чтобы один и тот же код компилировался для разных платформ Ардуино.
Пример:
#if defined(__AVR_ATmega168__) || defined(__AVR_ATmega328P__) || defined(__AVR_ATmega328__)
#define LedPinOut() DDRB |= (1<<5)
#define LedPinOn() PORTB |= (1<<5)
#define LedPinOFF() PORTB &= (~(1<<5))
// Arduino Mega
#elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
#define LedPinOut() DDRB |= (1<<7)
#define LedPinOn() PORTB |= (1<<7)
#define LedPinOFF() PORTB &= (~(1<<7))
// Leonardo
#elif defined(__AVR_ATmega32U4__)
#define LedPinOut() DDRC |= (1<<7)
#define LedPinOn() PORTC |= (1<<7)
#define LedPinOFF() PORTC &= (~(1<<7))
// anything else
#else
#error "Board not supported"
#endif
LedPinOut() - порт на котором находится встроенный светодиод как выход
LedPinOn() - зажечь встроенный светодиод
LedPinOFF() - погасить встроенный светодиод
Данные макросы будут работать на платформах Uno(Nano), MEGA, Leonardo