M5Core2からアナログ電圧を出力させてみます。PORT.AにDACユニットを接続して出力する方法と、直接MCU(ESP32)のDACポートから出力する方法があります。今回は直接ESP32のDACから出力させてみます。
PORT.BによるDAC出力
MCUのDACポートからアナログ電圧を取り出すにはPORT.Bを使います。M5Core2本体にはPORT.Aしかありませんが、BOTTOMをM5GO BOTTOM2に組み替えてPORT.Bを使います。PORT.Bのpin2(黄線)はM5Core2 BUSのポートG26に接続されており、G26はESP32のポートGPIO26に接続されています。プログラムの中でGPIO26を出力設定します。
ちなみに隣のpin1(白線)はGPIO36でESP32のADCに接続されています。すなわちPORT.Bはpin1がAD入力、pin2がDA出力になっています。
公式サイトのBOTTOM2の回路図よりPORT.Bの回路は下記のようになっています。

引用元:https://m5stack-doc.oss-cn-shenzhen.aliyuncs.com/1007/A014-C_Sch_M5GO2.pdf
ESP32のDAC仕様
ESP32のGPIO36のDACは8bitで0x00〜0xFFを設定することで0V〜3.3Vまで取り出せます。リファレンス電圧はESP32の電源電圧になっています。詳細はESP32のテクニカルリファレンスマニュアルにて確認できます。
DAC出力プログラム
setup()の中でDACポートを初期化します。ESP32のGPIO26をpinMode()関数を使って出力ポートに設定します。アナログ電圧出力はdacWrite()関数を使ってGPIO26に0x00から0xFFまでの値を設定します。0xFFが3.3Vなので1LSB=3.3V/255≒0.0129Vとなります。例えば2.0Vを出力したい場合は、2.0/0.0129≒155=0x9Bを設定します。
下記スケッチは、5msごとにDAC設定値を0から1づつ増加させ、0xFFまで来たらリセットして増加させるプログラムです。
#include <M5Core2.h>
int G26_dac = 26; //PORT.Bのpin2(黄線)はPIN G26に接続されている
int da = 0; //DA値の初期化
void setup() {
M5.begin(); //M5Core2初期化
pinMode(G26_dac, OUTPUT); //G26のPINモードを出力設定
Serial.begin(9600);//デバッグ用serial monitor
M5.Lcd.setTextSize(2);
M5.Lcd.setCursor(0, 0);
M5.Lcd.print("PORT.B DAC OUTPUT:");
}
void loop() {
da += 1;//DAC設定値を1づつインクリメント
da = da % 0xff;//255で割った剰余値を設定。0開始で255まできたら0から再スタート
dacWrite(G26_dac, da); //G26にDAC出力値書き込み(0〜3.3V(0x00〜0xFF))
M5.Lcd.setCursor(0, 25);
M5.Lcd.fillRect(0, 25, 100, 25, BLACK);//画面表示値クリア
M5.Lcd.print(da);
Serial.println(da);//デバッグ用serial monitor
delay(5);
}
Code language: C++ (cpp)
アナログ出力波形
オシロスコープにてDAC出力波形をモニタしました。設定値0x00〜0xFFで0〜3.3Vまで出力されています。よく見るとあまり綺麗な直線になっていないような。256サイクルで前半の勾配より後半の勾配が寝ている感じ。

まとめ
PORT.BからESP32のDACアナログ電圧0V〜3.3Vが出力できることを確認できました。関数pinMode()でDACポートを初期化しdacWrite()で出力電圧を指定するのみです。

