Raspberry Pi 3とタクトスイッチでLEDを制御する(C言語)

今回は、ラズパイを用いて、いわゆるLチカというやつをやってみたいと思います。

とはいっても、ただLEDを光らせるだけでは面白くないので、ソフトウェアエンジニアリングらしく「入力」と「出力」を意識したデモをやってみます。

やること

ゴール

  • スイッチを押すと、LEDの状態が変化する(トグルする)。
  • この機能をC言語で実装する。

こんな感じになります。

準備するもの

  • OSインストール済のRaspberry Pi 3 一式
  • ブレッドボード
  • LED(今回は緑色を使用)
  • 抵抗 1kΩ × 2個(スイッチ用)
  • 抵抗 270Ω × 1個(LED用)
  • タクトスイッチ
  • ジャンパー線数本

 実際にやってみよう

準備は整いましたか?

では、さっそくやっていきましょう!

ハードウェアの準備

回路の実装

今回は、LEDもスイッチもActive LOWで設計しております。

回路図はこんな感じ。

  • LED制御はGPIO32
  • スイッチ入力はGPIO25

に設定しました。

ちなみに、ブレッドボードにするとこんな感じです。

ピンぼけしててすみません…

LEDとタクトスイッチには向きに注意して下さい。

Raspberry PiのGPIO

Raspberry Pi 3 model Bの場合、ピンヘッダの配置は下図の通りです。

ちなみに、Raspberry PiのGPIOは3.3Vです。

<出典 : https://www.raspberrypi.org/documentation/usage/gpio/README.md>

ソフトウェアの実装

さあ、いよいよプログラミングを始めましょう。

ソフトウェア実装の流れ

  • gitのインストール
  • wiringPiのインストール
  • コーディング
  • コンパイル
  • プログラム実行

ざっと、流れはこんな感じです。

では、順番に見ていきましょう。

Gitのインストール

Raspberry Piで以下のコマンドを実装します。
$ sudo apt-get install git
以下のコマンドで正常にインストールできていることを確認します。
$ git --version
git version 2.1.4

wiringPiのインストール

wiringPiとは、Raspbery PiのGPIOをC言語で操作できるライブラリです。

以下のコマンドでwiringPiをクローンします。
$ git clone git://git.drogon.net/wiringPi

クローン後、ダウンロードしたフォルダに移動します。
$ cd wiringPi

その後、ビルドします。
$ ./build

ビルドが完了すると、以下のコマンドでwiringPiが実装できていることを確認してください。
$ gpio -v

これでwiringPiのインストールは完了です。

コマンドでGPIOを操作してみる

ちなみに、wiringPiはコマンドラインからGPIOを操作できるので、早速やってみましょう。

本記事で回路を実装しているという前提でお話を進めます。

まずはLEDを光らせてみましょう。

まず、使用するGPIOの設定をしてやります。
$ gpio -g mode 23 out

次に、GPIOの出力を指示してLEDを光らせます。
今回はActive LOW(GPIO電圧が0VでLED点灯)なので、0を指定します。
$ gpio -g write 23 0

LEDを消す場合は以下のコマンドです。
$ gpio -g write 23 1

次に、タクトスイッチの状態を取得しましょう。
今回はRaspberry Piにとっては入力となるのでGPIOの設定はこうなります。
$ gpio -g mode 25 in

次に、スイッチを押さない状態でGPIOの状態を読み取りましょう。
$ gpio -g read 25
1

タクトスイッチを押しながら読み取ると、以下の様になると思います。
$ gpio -g read 25
0

ここまでで、プログラミングをする準備が整いました。

コーディング

まず、ワークスペースを作りましょう。
$ mkdir test
$ cd test

ファイルを作成します。
$ nano led.c

ここからがコーディングです。
まずは、ソースコードを見てみましょう。

#include <wiringPi.h>

#define PIN_LED  23
#define PIN_SW   25

#define GPIO_ON  0
#define GPIO_OFF 1

#define DEBOUNCE 15

int toggleLed( int );
int isSwitchOn( int *, int );

int main ( void ) {

  int i;                    // For loop
  int status_sw[DEBOUNCE];  // Switch status buffer
  int status_sw_filtered;
  int status_sw_temp;

  /* Initialize wiringPi */
  if( wiringPiSetupGpio() == -1 ) return 1;

  /* Initialize GPIO */
  pinMode( PIN_LED, OUTPUT );
  pinMode( PIN_SW,  INPUT  );
  for( i=0; i<DEBOUNCE; i++ ){
    status_sw[i] = GPIO_OFF;
  }
  status_sw_filtered = GPIO_OFF;

  /* Start main routine */
  for( ;; ) {

    /* Shift Status Buffer */
    for( i=0; i<DEBOUNCE-1; i++ ) {
      status_sw[i+1] = status_sw[i];
    }

    /* Read Current Switch Status */
    status_sw[0] = digitalRead( PIN_SW );

    /* toggle LED */
    status_sw_temp = isSwitchOn( status_sw, PIN_SW );
    if( status_sw_temp == GPIO_ON ) {
      if( status_sw_filtered == GPIO_OFF ) {
        toggleLed( PIN_LED );
      }
    }
    /* save */
    status_sw_filtered = status_sw_temp;

  }

  return 0;
}

/* ================================
 * toggleLed
 *   
 *   Toggle LED.
 *
 *   + Augment
 *       pin_id ... Number of GPIO connected to LED
 *   + Return
 *       LED status
 * ================================
 */
int toggleLed( int pin_id ) {
  int result;

  if( digitalRead( pin_id ) == GPIO_ON ) {
    digitalWrite( pin_id, GPIO_OFF );
    result = GPIO_OFF;
  } else {
    digitalWrite( pin_id, GPIO_ON );
    result = GPIO_ON;
  }

  return result;
}

/* ================================
 * isSwitchOn
 *
 *   Return "true" when swicth is pushed.
 *   This function includes debounce filtering.
 *
 *   + Augment
 *       status_sw ... Array of switch status row data
 *       pin_id ... Number of GPIO connected to LED
 *   + Return
 *       Switch status after filtering
 * ================================
 */
int isSwitchOn( int *stasut_sw, int pin_id ) {
  int i;
  int result = GPIO_ON;

  for( i=0; i<DEBOUNCE; i++ ) {
    if( digitalRead( pin_id ) == GPIO_OFF ) result = GPIO_OFF;
  }

  return result;
}

ソースコードの解説はまた後日追記します。

スイッチのチャタリング対策を入れているので、多少コードが複雑になっています。

Ctrl + Oでファイルを保存し、Ctrl + Xでエディタを閉じましょう。

コンパイル

led.cをコンパイルして、実際で動くようにしましょう。

以下のコマンドでコンパイルを行います。
$ gcc -o led led.c -lwiringPi

-lwiringPiを忘れないようにして下さい。
wiringPiライブラリをリンクする必要があります。

エラーがあれば修正して下さい。

実行

ここまででエラーがなければ、ディレクトリに実行ファイルができているはずですので、以下のコマンドでプログラムを実行しましょう。
$ sudo ./led

いかがでしょう?

スイッチを押す度にちゃんとLEDのON/OFFが入れ替わっておりますでしょうか?

最後に、プログラムを止める場合はCtrl + Cを押して下さい。

今回は以上になります。

お疲れ様でした!!

The following two tabs change content below.
株式会社クリエイターズ・ラボ 代表取締役。株式会社078 取締役。 中学生の時に父の自作PCを譲り受け、はじめてのウェブ制作を経験する。見よう見まねで自分のウェブサイトにチャット機能や掲示板を自作で実装したのがはじめてのプログラミング経験。 大学在学中にLinuxとC言語を学ぶ。大学卒業後はエンジニアとして自動車メーカーで油圧制御プログラムの開発や、シミュレーションソフト開発に従事。その後、半導体商社にて組込みソフトエンジニアとして、産業機器や家電、IoT等の組込みソフトウェア開発に従事。 2015年9月に株式会社クリエイターズ・ラボを設立。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

CAPTCHA


このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください

%d人のブロガーが「いいね」をつけました。