以前、ESP-IDF環境でDigitalOutクラスを使う記事をご紹介しました。
今回はArduino環境でDigitalOutクラスを使ってみます。
このサイトでは今まで ESP-IDF環境でのみ記事を書いてきました。
Arduinoの環境もVSCode + PlatformIOで構築することができるのでご紹介しておきます。
デバッガの動作は遅いのですが、思い通りに動かない場合にステップ実行しながらプログラムの動作を確認していくことができる点ではお薦めです。
Arduino IDEの環境でしか動作させたことがない方は、ぜひ一度体験して頂きたいと思います。
この記事は JTAG でデバッグすることを前提にして書いています。
環境構築については こちら をご覧になってください。
投稿時の開発環境を記しておきます。
PC:
Windows10 OS
開発ボード :
ESP32-DevKitCーVE
(Soc : ESP32-D0WD-V3)
デバッガー(H/W):
FT2232D
デバッガー (S/W) :
Visual Studio Code + PlatformIO + Arduino Framework
DigitalOutクラスとは
C++を使ったGPIOの出力専用クラスです。
コンストラクタの引数にGPIOの番号を指定するだけで使うことができます。
クラス名は mbed のパクリです 笑
Arduino環境にも専用のGPIO出力クラスがなさそうだったので、つくってみました。
(注)
入力専用ポートは使わないようにしてください。
エラー処理は含まれていません。
Lチカ用に追加する回路
LEDをGPIO18につなぐ例です。

プロジェクトをつくる
使っていたプロジェクトを開いていたら、File – Close Folder して閉じておきます。
その後にVSCodeからPlatformIOをOpenします。
以下の内容でプロジェクトを新規に作成します。
Name : ESP32A-DigitalOut
Board : Espressif ESP32 Dev Module
Framework : Arduino Framework
Name : ESP32A の “A” は Framework (Arduino Framework)の頭文字を示しています。
(後から見てわかるように、Arduinoを使うことを明示しています)

platformio.ini に以下の3行を追加して、 Ctrl + s で保存しておきます。
COM[4]の4の部分はデバイスマネージャーのポート(COMとLPT)で Silicon Labs CP210x から始まるCOMの番号を記述します。
debug_tool = minimodule
upload_port = COM[4]
monitor_speed = 115200
(今回のコードでは不要ですが、モニターを使う場合に必要です)
コーディングする
VSCode EXPLORER の src を右クリックして New File から DigitalOut.h と DigitalOut.cpp を追加します。
それぞれを以下のように編集します。
DigitalOut.h
#ifndef DIGITALOUT_H_
#define DIGITALOUT_H_
#include "driver/gpio.h"
class DigitalOut
{
gpio_num_t port;
public:
DigitalOut(gpio_num_t num, gpio_pullup_t pull_up = GPIO_PULLUP_DISABLE, gpio_pulldown_t pull_down = GPIO_PULLDOWN_DISABLE);
void write(int value);
int read();
DigitalOut& operator=(int value);
DigitalOut& operator=(DigitalOut& rhs);
operator int() {
return read();
};
};
#endif // DIGITALOUT_H_
DigitalOut.cpp
#include "DigitalOut.h"
DigitalOut::DigitalOut(gpio_num_t num, gpio_pullup_t pull_up, gpio_pulldown_t pull_down)
: port(num)
{
gpio_config_t io_conf;
io_conf.intr_type = GPIO_INTR_DISABLE;
io_conf.mode = GPIO_MODE_OUTPUT;
io_conf.pin_bit_mask = 1UL << num;
io_conf.pull_down_en = pull_down;
io_conf.pull_up_en = pull_up;
gpio_config(&io_conf);
}
void DigitalOut::write(int value)
{
gpio_set_level(port, value);
}
int DigitalOut::read()
{
uint32_t mask = 1UL << port;
if (GPIO.out & mask)
{
return 1;
}
return 0;
}
DigitalOut& DigitalOut::operator=(int value)
{
write(value);
return *this;
}
DigitalOut& DigitalOut::operator=(DigitalOut& rhs)
{
write(rhs.read());
return *this;
}
main.cpp
main.c を main.cpp に rename してから、以下のようにコーディングします。
Arduinoユーザーにはお馴染みの setup() と loop() ですね。
#include
#include "DigitalOut.h"
void setup() {
// put your setup code here, to run once:
}
void loop() {
// put your main code here, to run repeatedly:
DigitalOut led(GPIO_NUM_18);
led = 1;
led = 0;
led = 1;
led = 0;
while (true)
{
led = !led;
delay(1000);
}
}
プログラムの説明
ほとんど C関数のラッパーです。
自前で実装したのは read() の部分だけです。
GPIO.out という32ビットの構造体(レジスタ)には出力した値が書かれていて、その値を読み出すことができます。
このレジスタの値を番号分、左シフトしたポート番号でマスクしてあげれば、書かれた値を確認することができます。
ビルドして実行する
ビルド後、エラーがないことを確認して F5キーを押して app_main() にカーソルが来るまで待ちます。
その後、F5キーを押してプログラムを実行します。
Lチカすれば成功です。
ソースコードを github esp32a-DigitalOut におきました。
( 環境: VSCode + PlatformIO , Arduino Framework )
Arduino環境で DigitalOutクラス を使ってみたい方は参考になさってください。
参考というほど、できの良いものではありませんけれど (^_^)