|
/** |
|
* @file button_4leds_blink_int.ino |
|
* @brief Button and LED |
|
* @author Keitetsu |
|
* @date 2022/01/26 |
|
* @copyright Copyright (c) 2022 Keitetsu |
|
* @par License |
|
* This software is released under the MIT License. |
|
*/ |
|
|
|
#define SW_PIN 2 /**< タクトスイッチ接続したデジタルピン */ |
|
#define SW_INEFFECTIVE_TIME 400 /**< タクトスイッチの無効時間 (ミリ秒) */ |
|
/* LEDはHIGHで消灯,LOWで点灯 */ |
|
#define LED_NUM 4 /**< LEDの数 */ |
|
#define LED1_PIN 9 /**< LED1を接続したデジタルピン */ |
|
#define LED2_PIN 10 /**< LED2を接続したデジタルピン */ |
|
#define LED3_PIN 11 /**< LED3を接続したデジタルピン */ |
|
#define LED4_PIN 12 /**< LED4を接続したデジタルピン */ |
|
#define LED_BLINK_LEFT 0 /**< LEDは左方向に点滅 */ |
|
#define LED_BLINK_RIGHT 1 /**< LEDは右方向に点滅 */ |
|
#define INTERVAL_TIME 1000 /**< LEDの点滅周期 (ミリ秒) */ |
|
|
|
static volatile unsigned long sw_prev_time; /**< 外部割込み処理の前回実行時刻 */ |
|
static unsigned long sw_ineffective_time; /**< タクトスイッチの無効時間 */ |
|
/** |
|
* @brief LEDを接続したデジタルピン |
|
*/ |
|
static const uint8_t leds_pin[LED_NUM] = {LED1_PIN, LED2_PIN, LED3_PIN, |
|
LED4_PIN}; |
|
static uint8_t leds; /**< LEDの点滅状態 (下位4bit: LED4, LED3, LED2, LED1) */ |
|
static volatile uint8_t led_blinking_dir; /**< LEDの点滅方向 */ |
|
static unsigned long prev_time; /**< 周期実行の前回実行時刻 */ |
|
static unsigned long interval_time; /**< 周期実行の間隔 */ |
|
|
|
/** |
|
* @brief LEDの点滅方向を切り替える |
|
*/ |
|
void toggleBlinkingDir() { |
|
unsigned long sw_curr_time; |
|
|
|
// 現在時刻を取得する |
|
sw_curr_time = millis(); |
|
|
|
// チャタリング対策として |
|
// 外部割込み処理の前回実行時刻から一定以上の時間が経過しているかどうかを判定 |
|
if ((sw_curr_time - sw_prev_time) >= sw_ineffective_time) { |
|
sw_prev_time = sw_curr_time; |
|
|
|
if (led_blinking_dir != LED_BLINK_RIGHT) { |
|
led_blinking_dir = LED_BLINK_RIGHT; |
|
} else { |
|
led_blinking_dir = LED_BLINK_LEFT; |
|
} |
|
} |
|
} |
|
|
|
/** |
|
* @brief LEDの点滅状態を更新する |
|
* @param[in] leds LEDの点滅状態 |
|
*/ |
|
void updateLEDs(uint8_t leds) { |
|
for (uint8_t i = 0; i < LED_NUM; i++) { |
|
digitalWrite(leds_pin[i], leds & 0b00000001); |
|
leds >>= 1; |
|
} |
|
} |
|
|
|
/** |
|
* @brief セットアップ関数 |
|
*/ |
|
void setup() { |
|
// タクトスイッチの初期化 |
|
pinMode(SW_PIN, INPUT); |
|
attachInterrupt(digitalPinToInterrupt(SW_PIN), toggleBlinkingDir, FALLING); |
|
sw_prev_time = 0; |
|
sw_ineffective_time = SW_INEFFECTIVE_TIME; |
|
|
|
// LEDの初期化 |
|
for (uint8_t i = 0; i < LED_NUM; i++) { |
|
pinMode(leds_pin[i], OUTPUT); |
|
} |
|
leds = 0b01110111; |
|
updateLEDs(leds); |
|
led_blinking_dir = LED_BLINK_RIGHT; |
|
|
|
// 周期実行の初期化 |
|
prev_time = 0; |
|
interval_time = INTERVAL_TIME; |
|
} |
|
|
|
/** |
|
* @brief ループ関数 |
|
*/ |
|
void loop() { |
|
unsigned long curr_time; |
|
|
|
// 現在時刻を取得する |
|
curr_time = millis(); |
|
|
|
// 周期実行 |
|
if ((curr_time - prev_time) >= interval_time) { |
|
prev_time += interval_time; |
|
|
|
// LEDの点滅状態を更新する |
|
if (led_blinking_dir != LED_BLINK_RIGHT) { |
|
leds = ((leds & 0b10000000) >> 7) | (leds << 1); |
|
} else { |
|
leds = ((leds & 0b00000001) << 7) | (leds >> 1); |
|
} |
|
updateLEDs(leds); |
|
} |
|
} |