« タイニーBASICの簡易拡張準備-4 拡張関数の仕様を策定 | トップページ | ESP32 WROOM/WROVER GPIO16,17使用可否実機検証 »

2024年4月 1日 (月)

★★タイニーBASIC GPIO+AnalogIOの簡易拡張成功

E S P 3 2
豊四季タイニーBASIC WiFi Telnet版
GPIO・PWM・ADC・DAC
操作関数 拡張成功

2024-4-13追記 高速PWM出力・高精度ADC対応のプチ改良版もあります。

先日策定した仕様に基づき、DigitalIO(PWM)とAnalogIO(ADC、DAC)の操作関数の拡張に成功しました。
また、GPIO・時間待ち関数の名称も前回作成のものから今回見直しました。

GPIOとAnalogIOの操作で割り当てるポートは、TinyBasicの実行環境で使えそうなポートに限定するチェック機能も盛り込みました。
TablePhoto_20240331084301
ArduinoIDEでのコンパイルでは、Espressif社のArduino ESP32のAPIと関数名等異なる所もありましたが、エラーメッセージで修正案を提示してくれるので、それに従い修正すればOKでした。
前回の経験が生きて、今回のコーディングは約半日で完了でき、今日実機とオシロでの波形観測で動作確認まで出来たので、先ずは拡張成功と考えています。
尚、ライブラリのバージョンは Arduino ESP32 version 2.0.15 (現時点のLatest版)を使っています。


今回の簡易拡張で参照した主な情報源(本ブログ記事を除く)をまとめました。
・豊四季TinyBasic WiFiTelnet版のソースファイル
 GitHub - robo8080/ttbasic_ESP32_WiFiTelnet: ESP32 WiFi Telnet対応版 豊四季タイニーBASIC
・拡張で役立った記事
 mbed版 豊四季タイニーBASICの機能を拡張してみた。(1) - robo8080のブログ (goo.ne.jp)
・豊四季タイニーBASICオリジナル版制作者鈴木氏の著書(アマゾンでも入手可
 タイニーBASICをCで書く(鈴木 哲哉) | 書籍 本 | ソシム (socym.co.jp)
・豊四季タイニーBASICの文法
 豊四季タイニーBASICの文法 | 電脳伝説 (wordpress.com)
 補足:SAVE [BOOT]、LOAD の拡張とエスケープシーケンス対応がWiFiTelnet版は拡張されています。
・Espressif社の最新Arduino-ESP32のAPIライブラリ説明
 Libraries - - — Arduino ESP32 latest documentation (espressif.com)



今回主に工夫した点

今回工夫した点は、ADCのピン毎の減衰量指定での定数の与え方です。
TinyBasicでは16bitsの符号付整数しか扱えないので、表向きは0~3で指定する事にし、インタープリター内では3なら analogSetPinAttenuation(pin, ADC_11db) を実行する事で対処しました。ADC_11dbの部分は、PC内のライブラリ esp32-hal-adc.h 内にenum列挙を見つけたので記述順に従い、3を渡してみましたが、コンパイルすると adc_attenuation_t型ではないとして、エラーが発生してしまいました。この辺の仕組みは私には良く分かりませんし、上手い回避策があるのかもしれませんが、ArduinoIDE環境でそのまま使える、内部定義値をそのまま渡してコンパイルした方が、安全かつ確実な方法との考えに辿り着きました。
今後APIライブラリ内の定数宣言が不明とか、型が合わないとかの場合には、同じ手が使えそうです。
以下その部分の抜粋。赤数字がTinyBasicユーザープログラムでの指定値、青文字がArduino-ESP32 APIへ渡す定数、ifで1:1に対応させました。
if(attn == 0) analogSetPinAttenuation(pin, ADC_0db);
if(attn == 1) analogSetPinAttenuation(pin, ADC_2_5db);
if(attn == 2) analogSetPinAttenuation(pin, ADC_6db);
if(attn == 3) analogSetPinAttenuation(pin, ADC_11db);

蛇足:ADC_11dbは、参照したArduino ESP32のAPIの説明では、"ADC_ATTEN_DB_11"になっていて名前が異なりますが、ドキュメントの改定が追い付いていないか、PC内のライブラリが異なるかどちらかなのでしょう。まあコンパイルが成功するなら定数の処理はOKと言う事なので、コンパイルが成功したADC_11db等を使いました。この辺はArduino IDEのライブラリアップデートで変わってしまう可能性があるのかもしれません。

2024-4-7追記 減衰量の指定値の関連情報で esp32_datasheet_en.pdfに以下の表があるのを見つけました。
Atten = 3 など書かれています... 0~3の数値は合っているけど、型の問題だけなのかなー...
Photo_20240408074301

と言う事で、型変換の方法を調べ、以下を試したらコンパイルが成功、実機検証で減衰量設定がきちんと効いている事を確認しました。

analogSetPinAttenuation(pin, static_cast<adc_attenuation_t>(attn));

最初にやった if文4行の記述は、上記1行で足りる事が分かりました。

ソースファイル・拡張方法・前回との差異

今回作成した、basic.cpp はここで公開しますが、前回同様参考で、拡張の仕方としての事例紹介だけになります。
如何なる誤動作・破損・損害の責任は当方は負いません
ESP32で豊四季TinyBasicを走らせたり、独自の拡張に取り組んでみたい方の、
情報源の一つとして少しでも役に立てば幸いです。

利用条件に関しては、以下、豊四季タイニーBASICの作者鈴木氏に従うものとします。
Photo_20240422093701

尚、Arduino IDEでは、 変更していない ttbasic_ESP32_WiFiTelnet.ino と合わせてのコンパイルとESP32への書き込みが必要です。
また、WiFiのssidとpwはご自身のWiFi環境にあわせての変更が必要です。

------------------------------------------------------

今回策定した拡張関数の仕様等に関係し、前回から以下の点が少し異なります。
・拡張する関数名は、Arduino-ESP32のAPIライブラリ関数と、等価な名前とし、引数の順番も合わせました。
 例、"digitalWrite(ポート番号, 出力データ)"⇒"DIGITAL_WRITE ポート番号, 出力データ"
・冒頭で、各拡張関数で指定するGPIOポート番号を限定するため、有効なポート番号を羅列した配列を追加し、
 各拡張関数内では指定されたポートが配列にあるかチェックを行い、
 無い場合は"Invalid port"メッセージを出して処理を中断するようにしました。
 上記対応で、エラーメッセージ配列とそのenumに追記しました。
 有効なポート番号の配列宣言例 const signed char pin_mode_s[]={ 18,19,21,22,23,25,26,32,33,34,35,36,39,-1};
・WiFi接続時の起動メッセージは"ARDUINO(ESP32 WiFi+GPIO+Analog)"に変えました。
・速度低下の原因になってしまうデバッグ用のSerial.printは全て削除しました。

具体的なソースの改変内容は、長くてくどくなるだけな気がするので、前回記事を参照いただくとして、ここでは詳細は省略とします。
やり方的には以下1~4が前回同様で、5が今回追加した部分です。
1,キーワードテーブルへの追加
2,その追加順に合わせ、中間コードenum列挙への追加
3,各拡張関数の呼び出しcase追加
 ・iexe()への戻り値無し拡張関数の呼び出しcase追加
 ・ivalue()への戻り値有の拡張関数の呼び出しcase追加
4,各拡張関数本体の追加
5,今回のチェック機能として追加した冒頭の有効ポート配列宣言の追加、
 及びエラーメッセージ配列への"Invalid port”とそのenumへの追加

また、各拡張関数内では、各設定の範囲チェック、各設定値毎の実機での動作確認など、十分にチェックできていないので、ミス等あればご指摘等頂けると助かります。

特に今回の拡張で追加した、各拡張関数の操作対象のGPIOポート番号は、冒頭の配列宣言にあれば有効としてますが、確認が不十分です。


Photo_20240408193701


実際、手持ちで実機検証に使っているFreenove社ESP32-WROVER-Eの開発ボード(写真右)には、GPIO4と5に間にはGPIO16,17が無くGND 2つに代わっています(左図赤枠部分)。

秋月で売っている開発ボード、ESP32-DevKitC-32E(写真左)と、ESP32-DevKitC-VE(写真中央)では、GPIO16,17が端子に出ています(左図青枠部分)。ピン数は片側19、両側38。

純正DevKitC(ESP32-DevKitC-32E(ESP32-WROOM-32Eモジュールを搭載)や、ESP32-DevKitC-VE(ESP32-WROVER-Eモジュールを搭載))でも、秋月と同様GPIO16,17が出ています。

この事から、通常の開発ボードを配慮すると、有効にしておくべきだと、気づきました。
秋月へ両ボードを注文したので、改めて実機動作確認してみる予定。

2024-4-6追記 GPIO16,17の実機検証をやってみました。WROOMなら使えるが、WROVERでは使えない事が分かりました。

 

------------------------------------------------------

コンパイル成功のメッセージ。全部で772,096バイト使っている様です。 Compile

単純なLチカだけのプログラムが252,624バイトだったので、WiFiとTinyBasicで約500kバイトも使っているんでしょうね。
ESP32なら4MBか8MBのFlashを積んでいるので、まだまだ余裕です。

 

デモの様子

以下、デモで作成したTinyBasicプログラムと実機動作の様子です。

 


PWMのデモプログラム例です。

100 REM ----- GPIO32 PWM OUTPUT TEST, PIN=32 CHN=0 ------
110 REM -------------------------------------------------
120 P=32; C=0; F=500; D=128; REM PARAMETER DEFINITION
130 PIN_MODE P,3
140 LEDC_SETUP_8 C,F; LEDC_ATTACH_PIN P,C; LEDC_WRITE C,D
150 DELAY_MS 5000
160 REM -------------------------------------------------
200 REM SWEEP Frequency from 1000Hz to 5000Hz to 1000Hz
210 D=128; LEDC_WRITE C,D
220 FOR F=1000 to 5000 step 200
230 LEDC_SETUP_8 C,F
240 DELAY_MS 100
250 NEXT F
300 FOR F=5000 to 1000 step -200
310 LEDC_SETUP_8 C,F
320 DELAY_MS 100
330 NEXT F
340 REM ------------------------------------
400 REM Sweep Duty from 0 to 256(100%) to 0
410 F=1000;LEDC_SETUP_8 C,F
420 FOR D=0 TO 256 STEP 1
430 LEDC_WRITE C,D
440 DELAY_MS 10
450 NEXT D
500 FOR D=256 TO 0 STEP -1
510 LEDC_WRITE C,D
520 DELAY_MS 10
530 NEXT D
540 REM ------------------------------------
600 GOTO 200

GPIO32へPWMチャネル0を割り当て、500Hz 50%デューティ(指定値128)を5秒間出力した後、50%デューティで周波数を1000Hz~5000Hz~1000Hzにスイープさせ、その後1000Hz固定でデューティを0%(指定値0)~100%(指定値256)~0%(指定値0)スイープさせました。

オシロ画面を見れば、波形観測された周波数とデューティ、波形の変化が分かります。
周波数は指定通り出ていますし、デューティもきちんと変化してくれています。

PWM動作のデモ動画です。

 


DAC出力とADC入力のデモプログラム例です。

100 REM ------ DAC OUTPUT and ADC INPUT Test ------
110 P=25; PIN_MODE P,192; A=36; PIN_MODE A,192
120 ANALOG_SET_PIN_ATTENUATION A,3
130 GOSUB 300
140 ANALOG_SET_PIN_ATTENUATION A,2
150 GOSUB 300
160 ANALOG_SET_PIN_ATTENUATION A,1
170 GOSUB 300
180 ANALOG_SET_PIN_ATTENUATION A,0
190 GOSUB 300
200 STOP
300 REM ----------- DAC & ADC Subroutine
310 FOR D=0 TO 255 STEP 1
320 DAC_WRITE P,D
330 DELAY_MS 10
340 PRINT ANALOG_READ A,",",
350 NEXT D
360 PRINT;PRINT
400 FOR D=255 TO 0 STEP -1
410 DAC_WRITE P,D
420 DELAY_MS 10
430 PRINT ANALOG_READ A,",",
440 NEXT D
450 PRINT;PRINT
460 RETURN

GPIO25へのDAC出力は、WiFi利用中でも動いたので、ポート選択を有効とし、デモしてみました。
値0~255~0の三角波をDACから出力し、オシロで観測。そのままGPIO36のADC入力へ接続し、ADC変換結果をPRINT文で書き出しました。
GPIO36のADC入力を減衰させるアッテネーション設定を3,2,1,0と変え、ADC変換値が飽和しない入力範囲の確認もラフですが出来ました。

DACとADCのデモ動画です。

横軸DAC値、縦軸ADC変換値のグラフをExcelで作ってみました。
Photo_20240404201001

実際の電圧の測定はしておらず、オシロ画面でのピーク電圧値が3.16Vの表示は目安でしかありませんが、アッテネーション11dBなら3V程度までは入力できそうな感じなのは分かります。
グラフを良く見ると、11dbだと目視で2.5V辺りから直線性が悪くグラフが曲がっています。ネットで調べると11db設定で使用する場合、精度確保のため2.45Vを入力範囲の上限にしている様です。精度を気にしなければ3V程度まではAD変換はしてくれます。
同様に低電圧領域でのAD変換結果を拡大してみると、6dbと11db設定では変換結果は0になっていて反応していないようです。また、0dbと2.5dbではオフセットが出ています。DAC出力電圧は測定していないので、精度は語れませんが、0.15V以下や2.45V以上は誤差が大きい様です。
Photo_20240408195601


注意
:現状DAC用のポート25,26は有効にしていますが、WiFi動作に問題が起きる様な場合は、使わない様にする必要があります。
特に、DAC2(GPIO26)の方はWiFi動作に支障は確認できませんでしたが、0Vから1.73Vの間は指定の電圧が出ず中間レベルになっているので、影響を受けていそうです。DAC1・2から三角波を出すテストプログラムとオシロの波形例です。
CH1(黄)がGPIO25からのDAC1出力、CH2(青)がGPIO26からのDAC2出力。

100 REM ------- DAC1(GPIO25), DAC2(GPIO26) test --------
110 PIN_MODE 25,192; PIN_MODE 26,192
120 REM
200 FOR D=0 TO 255 STEP 1
210 DAC_WRITE 25,D
220 DAC_WRITE 26,D
230 DELAY_MS 10
240 NEXT D
250 REM
300 FOR D=255 TO 0 STEP -1
310 DAC_WRITE 25,D
320 DAC_WRITE 26,D
330 DELAY_MS 10
340 NEXT D
400 GOTO 200
Img_0217


DAC1(GPIO25)で疑似的にSin波形を出した例です。

100 REM Sin wave by DAC
110 @(0)=128;@(1)=167;@(2)=203;@(3)=231;@(4)=249
120 @(5)=255;@(6)=249;@(7)=231;@(8)=203;@(9)=167
130 @(10)=128;@(11)=88;@(12)=52;@(13)=24;@(14)=6
140 @(15)=0;@(16)=6;@(17)=24;@(18)=52;@(19)=88
200 PIN_MODE 25,192
210 for I=0 to 19
220 DAC_WRITE 25,@(I)
230 NEXT I
240 goto 210
Img_0250

188Hzの疑似的なSin波となりました。配列(要素は31個まで)に近似値を入れたので分解能が荒く、多少ガクガクのSin波形です。
#define SIZE_ARRY 32 //Array area size
要素を増やして、より細かい分解能で近似すれば綺麗にはなるでしょうが、そのぶん低速になってしまいます。

まとめ・謝辞

GPIO操作・Analog操作の簡易拡張が、何とか成功しました。

先ずは、やってみたかったPWM・ADC・DACの操作がTinyBasicでできるようになったので、今後簡単で低速で済むアプリ制作などに使っていけそうで、ESP32がぐんと身近になりました。

WiFi使用時のポート制約は、確証がなく保証もできません。あくまで自己責任でお願いします。
何らかの問題が発生する場合には、安全を考え冒頭のポート番号の配列宣言から、問題となるポートの削除をお勧めします。

ESP32の周辺機能はまだまだ沢山ありますが、手を出し始めるときりがありません。
今後ESP32で何か制御したくなって、速度も余り気にならず、TinyBasicで拡張した方が便利そうなら、同じ様に出来る気がしてきました。

今回の自由研究は、もっと時間がかかると思っていましたが、元の豊四季タイニーBASICが改変し易い作りでしたし、改変に必要な情報も見つかり、大変楽しんで取り組みながら、約1ヶ月位でひと息つけるまで出来ました。

大元の豊四季タイニーBASICの作者vintagechipsさん、WiFi Telnet対応のrobo8080さんには、感謝申し上げます。

------------------------------------------------------

続報あればまた。

 

« タイニーBASICの簡易拡張準備-4 拡張関数の仕様を策定 | トップページ | ESP32 WROOM/WROVER GPIO16,17使用可否実機検証 »

電子工作:ESP32 TinyBasic」カテゴリの記事

コメント

コメントを書く

コメントは記事投稿者が公開するまで表示されません。

(ウェブ上には掲載しません)

« タイニーBASICの簡易拡張準備-4 拡張関数の仕様を策定 | トップページ | ESP32 WROOM/WROVER GPIO16,17使用可否実機検証 »