GPIO IN, OUT (ESP-IDF 環境 + C 言語)

プログラムの書き方

GPIO で使われる関数については, ESP-IDF Programming GuideAPI ReferenceGPIO & RTC GPIO を参照して欲しい.

以下に最低限使う必要のある関数を挙げる.

//ヘッダファイルの読み込み
#include "driver/gpio.h" 

// ピン番号の型 gpio_num_t 
gpio_num_t  pin = 13;

// ピンのリセット
gpio_reset_pin( pin );

// ピンの入力の指定
gpio_set_direction(pin, IN);
gpio_set_pull_mode(pin, GPIO_PULLUP_ONLY); //内部的にプルアップ

// ピンの入力値. 戻り値は 0 or 1
gpio_get_level(pin);

// ピンの出力の指定
gpio_set_direction(pin, OUT);

// ピンの出力.第 2 引数は 0 or 1
gpio_set_level(pin, 0);
gpio_set_level(pin, 1);

Lチカの例題

電子工作における hello world と言える L チカを実行する.

プロジェクトの準備

サンプルプロジェクトをコピーする.

$ cd ~/esp

$ cp -r esp-idf/examples/get-started/sample_project ./blink

$ cd blink

プログラムの作成

このサンプルプロジェクトのメインファイルは main ディレクトリ以下の main.c であるので, そのファイルを編集する.エディタとして,vi, emacs, gedit, code などが使える.

#include <stdio.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "driver/gpio.h"

void app_main(void)
{
   // LED ピン
   gpio_num_t pin = 13;                       // ピン番号
   gpio_reset_pin(pin);                       // ピンのリセット
   gpio_set_direction(pin, GPIO_MODE_OUTPUT); // ピンを出力で利用

   while(1) {
      gpio_set_level(pin, 0);                 // ピンの値を0に
      vTaskDelay(1000 / portTICK_PERIOD_MS);  // 1 秒の待ち

      gpio_set_level(pin, 1);                 // ピンの値を1に
      vTaskDelay(1000 / portTICK_PERIOD_MS);  // 1 秒の待ち
   }
}

なお,上記プログラム中の vTaskDelay(1000 / portTICK_PERIOD_MS); の行は, 1 秒 = 1000 ミリ秒だけ動作を止めるという命令である. ESP-IDF 環境では, 待ち時間 (単位 ミリ秒) を portTICK_PERIOD_MS (FreeRTOS の割込み周期)で割り算した結果を vTaskDelay の引数に与える必要がある.

1 番目の LED が定期的に点灯・消灯することを確認されたい.

ビルドとマイコンへの書き込み

idf.py build コマンドを実行する.

$ idf.py build

マイコンに書き込むのは idf.py flash コマンド, 標準出力を表示するのは idf.py monitor コマンドである. まとめて idf.py flash monitor としても良い.

$ idf.py flash monitor

実習ボードの左端の LED が点灯することが確認できるであろう.

monitor を終了するのは Ctrl-] である.

L チカの例題 (2)

スイッチを使ったプログラムを作成する.以下の <穴1>~<穴4> を埋めてプログラムを完成させよ.

#include <stdio.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "driver/gpio.h"

void app_main(void)
{
   // LED ピン
   gpio_num_t pin = <穴1>;                     // ピン番号
   gpio_reset_pin(pin);                        // ピンのリセット
   gpio_set_direction(pin, GPIO_MODE_OUTPUT);  // ピンを出力で利用

   //スイッチピン
   gpio_num_t pin2 = <穴2>;                    // ピン番号
   gpio_reset_pin(pin2);                       // ピンのリセット
   gpio_set_direction(pin2, GPIO_MODE_INPUT);  // ピンを出力で利用
   gpio_set_pull_mode(pin2, GPIO_PULLUP_ONLY); // 出力で使うピンを内部的にプルアップ

   while(1) {
      if ( <穴3> )      //スイッチの ON/OFF の判断
      {
         gpio_set_level(pin, 0);                 //ピンの値を0に
         vTaskDelay(1000 / portTICK_PERIOD_MS);  //1秒の待ち

      }
      else if ( <穴4> ) //スイッチの ON/OFF の判断
      {
         gpio_set_level(pin, 1);                 //ピンの値を1に
         vTaskDelay(1000 / portTICK_PERIOD_MS);  //1秒の待ち
      }            
   }
}