Instantly share code, notes, and snippets.
Last active
December 1, 2021 14:01
-
Star
(0)
0
You must be signed in to star a gist -
Fork
(0)
0
You must be signed in to fork a gist
-
Save KeitetsuWorks/a5b98d38c9c10f40d41fb5825c53e4b6 to your computer and use it in GitHub Desktop.
Arduino Sample Sketch: Button and LED
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* @file button_led_blink.ino | |
* @brief Button and LED | |
* @author Keitetsu | |
* @date 2021/10/17 | |
* @copyright Copyright (c) 2021 Keitetsu | |
* @par License | |
* This software is released under the MIT License. | |
*/ | |
#define BTN_PIN 2 /**< ボタンスイッチ接続したデジタルピン */ | |
#define BTN_COUNT_THRESH 2 /**< ボタンスイッチの状態の確定閾値 (x INTERVAL_TIME ミリ秒) */ | |
#define LED_PIN 12 /**< LEDを接続したデジタルピン */ | |
#define LED_OFF HIGH /**< LEDはHIGHで消灯 */ | |
#define LED_ON LOW /**< LEDはLOWで点灯 */ | |
#define LED_BRINK_PERIOD 25 /**< LEDの点灯時間または消灯時間 (x INTERVAL_TIME ミリ秒) */ | |
#define LED_BRINK_COUNT 5 /**< LEDの点滅回数 */ | |
#define INTERVAL_TIME 20 /**< 周期実行の間隔 (ミリ秒) */ | |
/** | |
* @struct button_st | |
* @brief ボタンスイッチ管理構造体 | |
* | |
* @typedef BUTTON_T | |
* @brief ボタンスイッチ管理構造体 | |
*/ | |
typedef struct button_st | |
{ | |
uint8_t pin; /**< 接続ピン */ | |
uint8_t last_val; /**< 前回の入力値 */ | |
uint8_t count; /**< 最後に入力値が変化してからのカウント値 */ | |
uint8_t state; /**< 状態 */ | |
} BUTTON_T; | |
/** | |
* @enum led_blink_state_e | |
* @brief LED点滅状態 | |
* | |
* @typedef LED_BLINK_STATE_E | |
* @brief LED点滅状態 | |
*/ | |
typedef enum led_blink_state_e | |
{ | |
LED_STOP_OFF = 0, /**< LED点滅停止中,LED消灯 */ | |
LED_BLINK_OFF, /**< LED点滅中,LED消灯 */ | |
LED_BLINK_ON /**< LED点滅中,LED点灯 */ | |
} LED_BLINK_STATE_E; | |
BUTTON_T btn; /**< ボタンスイッチ */ | |
LED_BLINK_STATE_E led_blinking_state; /**< LEDの点滅状態 */ | |
uint8_t led_blinking_start; /**< LEDの点滅開始フラグ */ | |
uint8_t led_blinking_count; /**< LEDの点滅回数カウント値 */ | |
uint8_t led_blinking_period; /**< LEDの点滅周期カウント値 */ | |
unsigned long prev_time; /**< 周期実行の前回実行時刻 */ | |
unsigned long interval_time; /**< 周期実行の間隔 */ | |
/** | |
* @brief ボタンスイッチ管理構造体を初期化する | |
* @param[in,out] btn ボタンスイッチ管理構造体のポインタ | |
* @param[in] pin ボタンスイッチの接続ピン | |
*/ | |
void initBtn(BUTTON_T *btn, uint8_t pin) | |
{ | |
btn->pin = pin; | |
pinMode(btn->pin, INPUT); | |
btn->last_val = digitalRead(btn->pin); | |
btn->count = 0; | |
btn->state = btn->last_val; | |
return; | |
} | |
/** | |
* @brief ボタンスイッチの状態を更新する (周期実行) | |
* @param[in,out] btn ボタンスイッチ管理構造体のポインタ | |
* @retval true ボタンスイッチの状態に変化あり | |
* @retval false ボタンスイッチの状態に変化なし | |
*/ | |
uint8_t updateBtnState(BUTTON_T *btn) | |
{ | |
uint8_t is_changed; | |
uint8_t btn_val; | |
is_changed = false; | |
btn_val = digitalRead(btn->pin); | |
if (btn_val != btn->last_val) | |
{ | |
// 入力値が変化した場合はカウント値を0にする | |
btn->last_val = btn_val; | |
btn->count = 0; | |
} | |
else | |
{ | |
if (btn->count < 255) | |
{ | |
// 入力値が変化していない場合はカウントアップ | |
btn->count++; | |
} | |
if (btn->count == BTN_COUNT_THRESH) | |
{ | |
// 最後に入力値が変化してからのカウント値が | |
// BTN_COUNT_THRESHに達した場合,ボタンスイッチの状態を確定する | |
is_changed = true; | |
btn->state = btn_val; | |
} | |
} | |
return is_changed; | |
} | |
/** | |
* @brief ボタンスイッチの状態を取得する | |
* @param[in] btn ボタンスイッチ管理構造体のポインタ | |
* @return ボタンスイッチの状態 | |
*/ | |
uint8_t getBtnState(BUTTON_T *btn) | |
{ | |
return btn->state; | |
} | |
/** | |
* @brief 点滅させるLEDを初期化する | |
*/ | |
void initLEDBlink() | |
{ | |
pinMode(LED_PIN, OUTPUT); | |
led_blinking_count = 0; | |
led_blinking_period = 0; | |
digitalWrite(LED_PIN, LED_OFF); | |
led_blinking_state = LED_STOP_OFF; | |
led_blinking_start = false; | |
return; | |
} | |
/** | |
* @brief LEDの点滅を開始する | |
*/ | |
void startLEDBlink() | |
{ | |
if (led_blinking_state == LED_STOP_OFF) | |
{ | |
// LED点滅停止中,LED消灯の場合はLED点滅開始 | |
led_blinking_start = true; | |
} | |
return; | |
} | |
/** | |
* @brief LEDの点滅状態を更新する (周期実行) | |
*/ | |
void updateLEDBlinkState() | |
{ | |
switch (led_blinking_state) | |
{ | |
case LED_BLINK_ON: | |
led_blinking_period++; | |
if (led_blinking_period >= LED_BRINK_PERIOD) | |
{ | |
// LED点滅中,LED消灯にする | |
led_blinking_period = 0; | |
digitalWrite(LED_PIN, LED_OFF); | |
led_blinking_state = LED_BLINK_OFF; | |
} | |
break; | |
case LED_BLINK_OFF: | |
led_blinking_period++; | |
if (led_blinking_period >= LED_BRINK_PERIOD) | |
{ | |
led_blinking_count++; | |
if (led_blinking_count >= LED_BRINK_COUNT) | |
{ | |
// LEDの点滅回数が設定値に達した場合は, | |
// LED点滅停止中,LED消灯にする | |
led_blinking_count = 0; | |
led_blinking_period = 0; | |
digitalWrite(LED_PIN, LED_OFF); | |
led_blinking_state = LED_STOP_OFF; | |
} | |
else | |
{ | |
// LED点滅中,LED点灯にする | |
led_blinking_period = 0; | |
digitalWrite(LED_PIN, LED_ON); | |
led_blinking_state = LED_BLINK_ON; | |
} | |
} | |
break; | |
case LED_STOP_OFF: | |
default: | |
if (led_blinking_start) | |
{ | |
// LED点滅中,LED点灯にする | |
led_blinking_count = 0; | |
led_blinking_period = 0; | |
digitalWrite(LED_PIN, LED_ON); | |
led_blinking_state = LED_BLINK_ON; | |
led_blinking_start = false; | |
} | |
break; | |
} | |
return; | |
} | |
/** | |
* @brief セットアップ関数 | |
*/ | |
void setup() | |
{ | |
// ボタンスイッチの初期化 | |
initBtn(&btn, BTN_PIN); | |
// LEDの初期化 | |
initLEDBlink(); | |
// 周期実行の初期化 | |
prev_time = 0; | |
interval_time = INTERVAL_TIME; | |
} | |
/** | |
* @brief ループ関数 | |
*/ | |
void loop() | |
{ | |
unsigned long curr_time; | |
uint8_t btn_is_changed; | |
uint8_t btn_state; | |
// 現在時刻を取得する | |
curr_time = millis(); | |
// 周期実行 | |
if ((curr_time - prev_time) >= interval_time) | |
{ | |
prev_time += interval_time; | |
// ボタンスイッチ押下を判定する | |
btn_is_changed = updateBtnState(&btn); | |
btn_state = getBtnState(&btn); | |
if (btn_is_changed && (btn_state == LOW)) | |
{ | |
startLEDBlink(); | |
} | |
// LEDの点滅状態を更新する | |
updateLEDBlinkState(); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment