カテゴリー「電子工作:ESP32 TinyBasic」の20件の記事

2024年5月17日 (金)

ESP32 TinyBasic 目次

記事が多くなってきたので、記事へのリンクだけですが、目次を作りました。
Photo_20240408193701Gpiopintable2TtbfuncImg_0250

2024-5-17更新


■豊四季タイニーBASIC WiFiTelnet版を導入
 ・2023年6月26日 (月) ESP32で走るTinyBasicの準備
 ・2023年6月29日 (木) ESP32でTinyBasicが動いた

■拡張検討
 ・2024年3月 3日 (日) タイニーBASICの簡易拡張準備
 ・2024年3月13日 (水) タイニーBASICの簡易拡張検討 -1 拡張事例調査とpinModeのMODE指定値の検討
 ・2024年3月14日 (木) タイニーBASICの簡易拡張検討 -2 pinModeで指定する数値を確かめる
 ・2024年3月16日 (土) タイニーBASICの簡易拡張準備-2 「タイニーBASICをCで書く」をゲット
 ・2024年3月25日 (月) タイニーBASICの簡易拡張準備-3 各GPIO割り当て表作成
 ・2024年3月31日 (日) タイニーBASICの簡易拡張準備-4 拡張関数の仕様を策定
 ・2024年4月 6日 (土) ESP32 WROOM/WROVER GPIO16,17使用可否実機検証
 ・2024年4月26日 (金) ESP32 EEPROMサイズとTinyBasicのSIZE_LIST上限値が判明

■拡張版開発成功
 ・2024年3月16日 (土) ★タイニーBASIC GPIO操作の簡易拡張成功

 ・2024年4月 1日 (月) ★★タイニーBASIC GPIO+AnalogIOの簡易拡張成功
 ・2024年4月12日 (金) ★★★タイニーBASIC GPIO+AnalogIO拡張 PWM高速化・ADC高精度化
 ・2024年4月28日(日)▼タイニーBASICシリアル版(先祖返り)
 ・
2024年5月17日 (金) ■タイニーBASICシリアル版のCardKB拡張

■その他
 ・2024年4月16日 (火) Arduino ESP32 ライブラリの不用意なバージョンアップは危ないかも
 ・2024年4月23日 (火) ESP32 Builtin Basic を期待した衝動買いは失敗で分解してみた
 ・
2024年5月 2日 (木) CQ出版 「Interface ESP&M5Stack電子工作プログラム集」に豊四季タイニーBASICの記事を発見

■応用・活用例
 ・2024年3月29日 (金) ワンショットリモコンシステムをTinyBasicでIoT化


PWMのデモ動画

 


参照引用元
GitHub - robo8080/ttbasic_ESP32_WiFiTelnet: ESP32 WiFi Telnet対応版 豊四季タイニーBASIC
豊四季タイニーBASICの文法 | 電脳伝説 (wordpress.com)
Libraries - - — Arduino ESP32 latest documentation (espressif.com)
PWM制御とは?Arduino(ESP32)コマンドで使い方を詳しく紹介 | ロジカラブログ (logikara.blog)

 


■タイニーBASICシリアル版のCardKB拡張

先日作成したシリアル版タイニーBASICですが、CardKBの使い方が分かったので、PC上のTeraTermだけでなく、CardKBでも操作できるように拡張してみました。

TFT-LCDの到着が少し先なので、先ずはキーボード入力だけ、PCとCardKBの両方から出来る様にしたものです。

TeraTermからの操作と同様にCardKBからの操作もできる事を確認しました。

以下詳細です。

 


シリアル版タイニーBASICからの変更箇所は以下の点です。

ttbasic_ESP32_Sirial_CardKB.ino内、以下青字2カ所

/*
  TOYOSHIKI Tiny BASIC for Arduino
 (C)2012 Tetsuya Suzuki
 */

#include <Wire.h>

void basic(void);


void setup(void){
  // put your setup code here, to run once:
  Serial.begin(115200);
  randomSeed(analogRead(0));
  Wire.begin();  // I2C interface begin
}
~省略~

 

basic.cpp内の変更箇所は以下です。

c_getch()とc_kbhit()の中身で、Serial版では標準的な関数がそのまま使えましたが、CardKBからの入力やステータス確認は、Wire.h内の関数を使うので、宣言を追加しました。

c_getch()では、シリアル側を優先したいので、
先にシリアルからの読み取り可否を問い合わせ、
  ├ 可なら文字を読み取りリターン。
  └ 否なら次にCardKBへ1バイト読み取り指定後、読み取り可否を問い合わせ、
    ├ 可なら文字を読み取りリターン。
    └ 共に否なら、戻り値-1でリターンです。

c_kbhit()では、シリアル側優先で、
先にシリアルからの読み取り可否を問い合わせ、
  ├ 可ならリターン。
  └ 否なら次にCardKB側の文字入力可否を問い合わせ、
    ├ 可ならリターン、
    └ 共に否なら、戻り値-1でリターンです。

2024-5-21追記
注意:c_kbhit()のCardKB側のif(Wire.available())の前にWire.requestFrom(CARDKB_ADDR, 1)を入れると、CardKB側の[Esc]キーが入らなくなりました。
タイニーBASICではc_kbhit()は、iexe()関数内で強制的な実行の中断に使われ、c_kbhit()で未読文字があれば、次にc_getch()を実行して[Esc]であれば,
処理を中断するためだけに使われています。

//強制的な中断の判定
  if (c_kbhit()) //もし未読文字があったら
    if (c_getch() == 27) { //読み込んでもし[ESC]キーだったら
      err = ERR_ESC; //エラー番号をセット
      break; //打ち切る
    }

この様な処理手順だと、毎回Wire.requestFrom→Wire.available→Wire.readの手順が必須となる訳ではない様です。
現段階では動けばOKと考えています。たぶん、デバッガを使えばより深く調査出来るのでしょうが、そこまではねー。

青字が変更箇所です。

~省略~
#include <EEPROM.h>
#include <Wire.h>
#define CARDKB_ADDR 0x5F

~省略~

// ********************* back to serial version ***************************
#define STR_EDITION "ARDUINO(ESP32 Serial/CardKB GPIO+Analog)"

// Terminal control
#define c_putch(c) Serial.write(c)
// #define c_getch( ) Serial.read()
// #define c_kbhit( ) Serial.available()
// ********************* serial and CardKB version ***************************
char c_getch( ){
  if(Serial.available()){
    return Serial.read();
  }
  Wire.requestFrom(CARDKB_ADDR, 1);
  if (Wire.available()){
    return Wire.read();
  }
  return -1;
}
 
int c_kbhit( ){
  if (Serial.available()){
    return Serial.available();
  }
  if (Wire.available()){
    return Wire.available();
  }
  return -1;
}
~省略~

 

 


モの様子です。
Img_0389_20240517235301

モ動画です。
PCのTeraTermへシリアルでESP32を接続、CardKBからの文字入力も出来る様にしておます。
ESP32のENボタンのリセットで起動メッセージ出力を確認し、メモ帳のテストプログラムをコピペ。
CardKBからのキー操作での実行と中断、リスト表示もきちんと確認できましたし、TeraTermからの操作も同様にできています。

CardKB及びシリアルからのキー入力の確認ができました。

 


CardKBはI2C接続なので、割と簡単なスケッチで、きちんとキーの読み取りができました。
タイニーBASICへの取り込みは、c_getch()とc_kbhit()関数の変更だけで済みましたし、動作確認もできました。

ぶん、CardKBを繋ぐだけなので、ライブラリ取り込みも、変更箇所も、スケッチ記述も、簡単で済んだだけなんでしょう。
ここまでは、自分の技量でできる程度で済みましたが、来週到着予定のTFT-LCDを繋ぐ方は、何倍も大変そうな気がする。

、今回のスケッチファイルは、とっても醜いので、TFT-LCDへの表示が成功したら、少し整理してから掲載する予定です。

 


文している 3.5インチ TFT-LCD ですが、航空便で日本への輸送中の段階で、配達は5/22予定になっていました。
Img_0388


着後は、c_putc(c) を変更して、TeraTerm側とTFT-LCD側の両方に、文字が表示される様にしてみようかと考えています。
ILI9488用が用意されているTFT_eSPIライブラリを使ってみようかと考えています。
文字表示に関する関数だけでも、目を通しておきたいと考えています。

 


 

続報あればまた。

 

2024年5月 2日 (木)

CQ出版 「Interface ESP&M5Stack電子工作プログラム集」に豊四季タイニーBASICの記事を発見

ちょくちょく本屋で立ち読みしますが、大きめの専門誌のある本屋さんにはなかなか行けてません。
少し前に専門誌のある本屋に行った際に、昨年2023年5月2日に発売されていたCQ出版社の単行本「Interface ESP&M5Stack電子工作プログラム集」に、豊四季タイニーBASICの記事があるのを発見しました。

 


Photo_20240502211401

記事と言っても、ESP32で使える開発言語の紹介の最後の方に、

ROM内蔵BASICが起動できなくなったので、BASIC処理系は豊四季タイニーBASICだけ。
Arduino版が動作するが、GPIOやI2Cなど使えず、保存機能もない。
好きなように拡張関数を追加してオリジナル言語を育てる楽しみがあり、トライしてみてほしい。

と言った内容(上記は要約)です。

自分はまさにこの状態。

買ったFreenoveのキットでは、Python開発例のソースや解説pdfもあります。
Pythonはインタープリタで使い易そうで、流行っていそうだし気になるのですが、宣言や定義など前置きが多く、文法も不慣れ。
多分C/C++にすら慣れていない自分が古いんでしょう。
自分的には若い時から使っているBASICが、文法も簡単で覚える事も少なくて良いかな。



続報あったらまた。

 

 

2024年4月28日 (日)

▼タイニーBASICシリアル版(先祖返り)

E S P 3 2

豊四季タイニーBASIC シリアル版

四季TinyBasic WiFiTelnet版はWiFiを使うので、WiFiにも使われるGPIOと、ADC2・DACには使用制約があります。
また、Power on runもWiFi接続後しか実行されないので、応用面で制約となる気もします。

今回、WiFi関係をコメント化して、元のArduino シリアル接続版にしてみました。先祖返りです。
一応、最新のGPIO・LEDC(PWM)・AnalogIO(DAC・高精度ADC版)をベースに、ADC2も使える様にし、プログラム領域4096バイト化もしました。

ースコードと注意・使用方法
今回作成の
ソースコード はここで公開しますが、前回同様参考で、拡張の仕方としての事例紹介だけになります。
如何なる誤動作・破損・損害の責任は当方は負いません
ESP32で豊四季TinyBasicを走らせたり、独自の拡張に取り組んでみたい方の、
情報源の一つとして少しでも役に立てば幸いです。
尚、#ifdefをうまく使えば良いものを、エイヤで何の工夫も無しに単にコメントアウトしただけで、大変みにくいです。
公開は大変躊躇するのですが、本ブログは自分用の記録でもあるので、みにくさはご勘弁を...。
無変更の起動用ソースファイル ttbasic_ESP32_WiFiTelnet.ino と合わせて、コンパイル・書き込みが必要です。

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

WiFiを使わないので、WiFi関連で使えなかったGPIOもADC2・DAC1・2も使えます。
以下に、シリアル版GPIO選択表を修正しました。
ADC2,DACの動作確認も実施しOK、デモにしました。

Gpiopintable2_20240503183101



下、詳細とデモです。

TeraTermにはシリアルで接続するので、初期設定ファイルTERATERM.INIのシリアルのボーレート設定部分(以下)115200に変えておきます。
; Baud rate
BaudRate=115200

ンパイル時のメッセージです。292,949バイトの使用です。WiFi込みだと772KB程度だったので、WiFiだけで479KBも使っていた様です。

最大1310720バイトのフラッシュメモリのうち、スケッチが292949バイト(22%)を使っています。
最大327680バイトのRAMのうち、グローバル変数が26900バイト(8%)を使っていて、ローカル変数で300780バイト使うことができます。

 

Power on runのデモプログラムです。
予めSAVE BOOTでEEPROMに書き込み、モバイルバッテリーに繋いでのPower on run動作検証に使いました。

100 REM GPIO PWM simple test
110 P=32; REM GPIO Number
120 C=0; REM PWM channel = 0
130 R=10; REM resolution
200 F=5
210 M=1
220 D=512
300 LEDC_SETUP C,F,M,R
310 LEDC_ATTACH_PIN P,C
320 LEDC_WRITE C,D
330 DELAY_MS 5000; REM delay
340 LEDC_DETACH_PIN P; REM release GPIO PWM OUTPUT


旦、Arduino IDEを閉じ、TeraTermを起動しておき、ENボタンを押すと、ESP32システムからの起動情報(以下青字)が表示され、その後TinyBasicが起動します。SAVE BOOTしていたので、ユーザープログラムが自動走行しています。

ets Jul 29 2019 12:21:46

rst:0x1 (POWERON_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:1
load:0x3fff0030,len:1344
load:0x40078000,len:13964
load:0x40080400,len:3600
entry 0x400805f0

TOYOSHIKI TINY BASIC
ARDUINO(ESP32 GPIO+Analog) EDITION
Power on run

OK
>

源オンで出てくるシステムからの起動メッセージ(上記青字部分)はブートROMログなどと言うものらしいです。
電源オン起動時にGPIO15をLowにしておくと出てこない様で、手持ちのESP32でも確認できました。

Disabling boot log (MTDO pin) on ESP-WROOM-32 - ESP32 Forum
ESP32 How to turn off automatic log of system output - ESP32 Forum

BOOTストラップと、MTDOと、GPIO15を起動時にLowにすればブートROMログが出なくなる事、これらの意味・関連性がいまいち理解できていませんけどね...
ははは、まだまだ修行がたりません。

画を撮ってみました。
ESP32側には、GPIO15をGNDに接続できる様にスイッチを用意しオフ側にしておきます。
ESP32をUSBに接続すると電源OnでPower on runしLED点滅開始。
TeraTermをシリアルで接続すると、シリアルバッファに溜まっていた送信データが吐き出されるためか、ブートROMログと、TinyBasicの起動メッセージが両方出ます。
USB接続を外し再度接続すると、Power on runしますし、ブートROMログと、TinyBasicの起動メッセージが出ます(念のための確認)。
USB接続を外し、GPIO15をGNDに落とすスイッチを入れておき、USB接続するとPower on runし、TinyBasicの起動メッセージだけが出ます。
USB接続を外し、再度接続しても、同様です(念のための再確認)。
Power on run中に、TeraTermで[ESC]を送ると、実行が中断されます。

 

バイルバッテリーに繋いで、Power on run している動画です。
シリアル化したので、PCから離れても動作可能です。

 

リアル化(先祖返り)版成功です。
WiFi版はWiFi接続後しかPower on runしませんが、シリアル版なら電源オンでPower on runできます。
[ESC]による中断も、USBケーブルをPCに繋いで、TeraTermをシリアルで起動し、[ESC]を押せば中断できます。

シリアル版ならスタンドアロン用途か、GPIO・ADC・DACを多用するアプリ用として、活用できそうです。

 


 

前のWiFi使用環境下の実機測定では、DAC2が中間レベル以上しか出力されなかったので、WiFiライブラリを使わないシリアル版でどうなるか、実機で確認してみました。
結果は、きちんとフルレンジで出力されるのを確認しました。DAC1が黄色、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_0271

 


 

ADC2は使えるのかも、実機で試しました。

GPIO25のDAC1から、0~255のDAC出力を出し、そのままADC2入力のGPIO13,14,15,26,27へ接続し、キャリブレーション有無の2種類のADC変換結果を取得し、グラフ化しました。
横軸はDACコード、縦軸は上のグラフがキャリブレーション有で電圧値出力[mV]、下のグラフがキャリブレーション無でADC出力コード。

キャリブレーション有は電圧値出力で、100mV程度のオフセット有、上は3175mV止まり、電源電圧までなのでこんなもんでしょう。
キャリブレーション無しだと、コード出力で、0~4095まで出ましたが、ADC1同様に直線性が悪く精度が良くない様です。
グラフの点が重なってしまいましたが、実際は各ADC2の各チャンネルは微妙に数値が異なります。

ADC2もきちんと使えるのが確認できました。

100 REM ------ DAC OUTPUT and ADC2 INPUT Test ------
110 @(0)=13;@(1)=14;@(2)=15;@(3)=26;@(4)=27
120 FOR I=0 to 4
130 PIN_MODE @(i),192
140 ANALOG_SET_PIN_ATTENUATION @(i),3
150 NEXT I
160 PIN_MODE 25,192
170 REM
180 FOR D=0 TO 255 STEP 1
190 DAC_WRITE 25,D
200 PRINT #5,D,",",
210 DELAY_MS 10
220 FOR I=0 to 4
230 PRINT #5,ANALOG_READ_MILLIVOLTS @(i),",",
240 NEXT I
250 PRINT
260 NEXT D
Adc2calib
100 REM ------ DAC OUTPUT and ADC2 INPUT Test ------
110 @(0)=13;@(1)=14;@(2)=15;@(3)=26;@(4)=27
120 FOR I=0 to 4
130 PIN_MODE @(i),192
140 ANALOG_SET_PIN_ATTENUATION @(i),3
150 NEXT I
160 PIN_MODE 25,192
170 REM
180 FOR D=0 TO 255 STEP 1
190 DAC_WRITE 25,D
200 PRINT #5,D,",",
210 DELAY_MS 10
220 FOR I=0 to 4
230 PRINT #5,ANALOG_READ @(i),",",
240 NEXT I
250 PRINT
260 NEXT D
Adc2_nocalib

2024-5-3追記 GPIO15(ADC2)を上記で使っていますが、BOOTストラップで使用されるので、利用対象から外しました。

 


 

続報あればまた。

2024年4月26日 (金)

ESP32 EEPROMサイズとTinyBasicのSIZE_LIST上限値が判明

TinyBasicの初期設定では、ユーザープログラムのサイズは、以下 SIZE_LISTの宣言により1023+1とになっていて、中間コードで20バイト列×50行、40バイト列×25行程度 と小さいため、大きいプログラムが書けません。

~省略~
// TOYOSHIKI TinyBASIC symbols
// TO-DO Rewrite defined values to fit your machine as needed
~省略~
#define SIZE_LIST 1023 //List buffer size
~省略~
unsigned char listbuf[SIZE_LIST + 1]; //リスト保存領域+ブートフラグ
~省略~

ここを32767とかに大きくしてみたところ、コンパイルは成功しますが、SAVEやLOADの動作が正しく働きません。
SAVE BOOTをしても、自動実行されませんし、SAVEやLOADそのものが、まともに動かないのです。
悔しいので、少し原因を調べてみました。
間違いや他の原因があるかもしれませんので、あくまで参考です。

不適切な値にしてしまった場合は、TinyBasicの起動後に、WiFiが切れてしまったり、TeraTermとのやり取りがうまくいかなかったり、変な文字が表示されたりもしました。
その場合、一旦電源を切り、BOOTを押しながら電源を入れ、BOOTを離し、念のためENボタンを押すとかで、直りました。

 


因を調べていたら、以下の点に気づきました。関係するコードも書き出しました。
好きに大きくしても、それに見合ったEEPROM領域がないと、まともにSAVEやLOADも出来ないし、BOOTフラグも書けないですね。
誤動作する訳ですよ。

・TinyBasicではSAVE、LOADでEEPROMへの書き込みと読み出しを行っていて、
 SIZE_LISTに宣言されたサイズの範囲を丸ごとfor文で読み書きしている。
 BOOTフラグは、SIZE_LISTの最後に書き込む様にしている。

~省略~
void isave() {

EEPROM.begin(SIZE_LIST+1);
// write a listbuf to all SIZE_LIST+1 bytes of the EEPROM
for (int i = 0; i < SIZE_LIST+1; i++)
    EEPROM.write(i, listbuf[i]);
EEPROM.commit();
EEPROM.end();
}
~省略~
void iload() {
EEPROM.begin(SIZE_LIST+1);
// write a listbuf to all SIZE_LIST+1 bytes of the EEPROM
for (int i = 0; i < SIZE_LIST+1; i++)
   listbuf[i] = EEPROM.read(i);
}
~省略~
case I_SAVE://extend
  cip++;
  if(*cip == I_BOOT){ // BOOTオプションがあったら
    cip++;
    listbuf[SIZE_LIST] = I_BOOT;  // I_BOOTをlistbufの最後に書き込む
  } else {
    listbuf[SIZE_LIST] = 0; // BOOTオプション無しなら0を書き込む
  }
  if(*cip == I_EOL)  // SAVE [BOOT] 命令行の行末(I_EOL)になったらisave()を実行
    isave();
  else
    err = ERR_COM;
  break;
~省略~

・TinyBasicのSAVE,LOADでは、EEPROMへの書き込みと読み込みを、Arduinoと互換の関数を使っている。
 Arduinoでは内蔵EEPROMは1024バイトしかないものの、電源オフ前の状態の保持等で、簡単に使える様になっている。
 注意:Flash 4MBや8MBは、SPIで繋がる外部のFlashメモリで、通常SPIFFSライブラリでアクセスする。

・ESP32の内蔵EEPROMは4KBしかないらしい。疑似EEPROMとの記載があります。
 ESP8266/ESP32でEEPROMにデータを保存する(データチェック付き) | Program Resource
 Photo_20240426203201

こまでの結論としては、TinyBasicのコマンド SAVE,LOADではEEPROMを使用する。SAVE,LOADを利用する場合は、ユーザープログラムサイズを規定するSIZE_LISTの値はEEPROMのサイズ以下(調べた範囲では4KB)とする事。
但し、実際のEEPROMのサイズ、TinyBasicで使用可能なサイズは未調査なので、変える場合は自己責任で。
SAVE,LOADを使わない条件でも、SIZE_LISTの値は内蔵RAMのサイズ(*)を超えられないはず。

(*)コンパイル時のRAMの総量と使用量等のメッセージで分かる。以下はメッセージ例。
 最大327680バイトのRAMのうち、グローバル変数が78836バイト(24%)を使っていて、ローカル変数で248844バイト使うことができます。



2024-4-27追記
だった、実際のEEPROMサイズ等が判明しました。参照したネット情報は以下。2020年4月の記事なので割と最近。
thoughts on esp32 EEPROM management? - Using Arduino / Programming Questions - Arduino Forum

 EEPROM.begin()では4~4096バイトのサイズ指定が出来る事。
 EEPROM.Write()は直ぐには書き込まないので、必ずEEPROM.Commit()を実行し、コピーデータの書き込みをする事。
 EEPROM.End()で、RAMにあるコピーデータを開放する。
 EEPROMライブラリは、SPIFFSのちょうど後の1セクタを使っているとの事。
 等の記載があります。だからESP32では疑似EEPROMと言うんでしょうね。
 Photo_20240427092001


 Arduino ESP32ライブラリでは、Flash Memoryの1セクタ(4Kバイト)をEEPROMとして使える様にエミュレートしているとの事。
 Photo_20240427091501

・Arduino ESP32のEEPROMライブラリは、以下が分かり易いです。
 ESP32 Flash Memory - Save Permanent Data | Random Nerd Tutorials
 ArduinoのEEPROMライブラリと非常に似ていて違いはほとんどない。
 2018年の記事なので情報が古く512バイトまで使えるとありますが、現在は4096バイトのはず。
Photo_20240427093701


論としては、1セクタのサイズ 4096バイトが上限ですね。
内蔵EEPROMがある訳ではなく、4MB/8MB FlashのSPIFFSの後の1セクタ(4096バイト)だけを、Arduinoと互換なEEPROMライブラリで使える様にしてある。4096バイトを超えても、SAVE,LOAD可能なプログラムサイズを確保したければ、FlashメモリをSPIFFSライブラリを使って利用するのが、ESP32では正しい気がする。

SIZE_LISTを4095にして、コンパイル・書き込み、SAVE,LOAD、SAVE BOOTでのPower on run 実行等、全て正しく動作する事を確認しました。
4倍のサイズに出来たので、先ずはここまでで良いかな。

「深追いすれども謎また謎、調べて分かって一歩ずつ、理解を深めて対策・改善。」の繰り返し。
まあ、謎が一つ解ければ、そこそこ面白いし、まあ楽しみながらやれているので、過還暦脳活としては効いてる気がする。
無知から始めた、謎解きテクノロジーパズルなESP32かな。です。


続報あればまた。

 

2024年4月23日 (火)

ESP32 Builtin Basic を期待した衝動買いは失敗で分解してみた

気にAmazonでマイコンボードを検索していたら、以下のお買い得品を見つけました。
ESP32開発ボードに、IO拡張ボードもついて、何と1180円。
Amazonの取り扱い開始が2018/1/8だし、古くて売れず、安売りみたいな感じかな。
古そうならと、以前起動できたBuiltinBasicを期待したがFuseで禁止され起動不可が判明。
おまけに普通のスケッチの書き込みもできず、使えずじまい。
悔しいので、最後はモジュールの蓋を外して中を覗いてみました。
 Img_0309_20240502162001

以下、詳細です。

 


った物は以下です。
Amazon | waves NodeMCU-32 デュアルコア 開発ボード ESP32 WiFi Bluetooth Type-C ワイドバージョン I/O拡張ボード 付き | waves | マザーボード 通販

Photo_20240423194601

ビューを見ていると、古いチップのため、EN端子とGND間に1uFを付けると書き込みが安定するとか、書き込み時はBOOTを押しながらとか記載があります。ESP32を調べ始めた頃にはそんな記事を幾つか見ていたので、古いチップならもしかしてBuiltinBasicが走るかもしれないとの期待が高まりました。2018年度頃のレビューが見当たらないのが少し気になりますけど、まあいいや。
もしダメでも、拡張ボード(後で良く見たら30ピン、少し後悔。本体単体だと1080円だから、おまけだと思う事にします)が手に入るだけでも、まあお買い得だろうと自分を納得させ、衝動買い。

き込みを安定させる方法は、ESP32のプログラム書込みを安定させる #ESP32 - Qiita が参考になりそうです。
上記記事から拝借したEN-GND間への0.1uFコンデンサの取付例。
Photo_20240424165801
当時は、BOOTボタン(GPIO2とGNDをショートさせるSW)を押したまま、ENボタンを押して離し、EN端子に容量を付加して、ENボタンを離した後の時定数を十分に確保し、確実に書き込みモードに入る必要があった様に思えます。
2024-4-24追記 参考で、リセットタイミングの補足を末尾に記載しました。


宅してから、モジュールの写真をチェック、BuiltinBasicが走っていた古いものと、刻印がほぼ同じ。これは期待できるかも。
アマゾンプライム対象商品なので、明日到着予定。
なんか、ワクワクしてます。


なみに、上記のアマゾンの商品紹介のモジュール部分の拡大写真が以下。
Photo_20240423195201Photo_20240424113201

BuiltinBasicの記事の載っているESP32-WROOM-32 (ht-deko.com)の、esp32_rev.jpg (1200×900) (ht-deko.com)と見比べると、ESP-WROOM-32 Rev.1(以下) とそっくりです。文字・記号の配置が若干小さいようですが、文字・記号そのものは全く同じ。
Photo_202404231955012_20240424113201

し、BuiltinBasicが走ったら、幾つかの方法でGPIOのトグルをさせ、波形を見て速度の比較でもしてみようと思います。
Easter Egg of ESP32 | macsbug (wordpress.com) を参考に、レジスタ書き込みの場合、IOSETの場合と、豊四季TinyBasicの場合で、どの程度違うのかとか。

 


2024-4-25追記
手後早速IO12を10KΩでPullUpして、ENを押してみました。
下は、実験の様子。
Img_0266

果は残念、BuiltinBasicの起動のための "Falling back to built-in command interpreter.メッセージは出ず、以下のメッセージが繰り返されるだけ。

rst:0x10 (RTCWDT_RTC_RESET),boot:0x33 (SPI_FAST_FLASH_BOOT)
invalid header: 0xffffffff
invalid header: 0xffffffff
invalid header: 0xffffffff
invalid header: 0xffffffff
invalid header: 0xffffffff
invalid header: 0xffffffff
invalid header: 0xffffffff
invalid header: 0xffffffff
ets Jul 29 2019 12:21:46

これが、エンターキーを連打しても、ただただ流れるだけ。

BOOTボタンを押すと、以下のダウンロードの待機メッセージが出て止まります。

rst:0x10 (RTCWDT_RTC_RESET),boot:0x23 (DOWNLOAD_BOOT(UART0/UART1/SDIO_REI_REO_V ))
waiting for download

IO15をPullDownしても、IO12とIO15に何も繋がなくてもENを押して離すと最初のメッセージの繰り返し
途中、エンターキーを連打しても、BOOTとENの押し方を変えても、BuiltinBasicの起動なんてできそうにない感じです。

ESP32-WROVER-E/ESP32-DevKitC-VE ● Disable ROM Basic の件 - CT5002    dellbee's blog (fc2.com)
を参照すると、全く同じ状況の様ですので、Fuseで禁止されているのでしょう

、アマゾンの取り扱い開始日とパッケージの記号・文字を頼りに、衝動買いしてしまいましたが、空振りでした。

 


2024-4-27追記

き込みが失敗するので、EN-GND間に1uFの容量を半田付けしましたが、結果は変わらず失敗。書き込み中ずっとBOOTボタンを押し続けてもダメ。USBケーブルを幾つか変えてもダメ。
Img_0267

買った物に同梱されていた、拡張ボードに刺して、何をやってもダメ。
Img_0268


ENを押すと、以下のメッセージの繰り返し
rst:0x10 (RTCWDT_RTC_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
invalid header: 0xffffffff

invalid header: 0xffffffff
invalid header: 0xffffffff
invalid header: 0xffffffff
invalid header: 0xffffffff
invalid header: 0xffffffff
invalid header: 0xffffffff
invalid header: 0xffffffff
ets Jul 29 2019 12:21:46

rst:0x10 (RTCWDT_RTC_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
invalid header: 0xffffffff
invalid header: 0xffffffff
invalid header: 0xffffffff
invalid header: 0xffffffff
invalid header: 0xffffffff
invalid header: 0xffffffff
invalid header: 0xffffffff
invalid header: 0xffffffff
ets Jul 29 2019 12:21:46

上記をずっと繰り返すだけ。


BOOTを押すと、以下のダウンロード待ちのメッセージが出るので、この状態で書き込んでも、失敗してしまう。

rst:0x10 (RTCWDT_RTC_RESET),boot:0x3 (DOWNLOAD_BOOT(UART0/UART1/SDIO_REI_REO_V2))
waiting for download

上記のダウンロード待ち状態で書き込んでも、以下のメッセージが出て失敗。


最大1310720バイトのフラッシュメモリのうち、スケッチが292953バイト(22%)を使っています。
最大327680バイトのRAMのうち、グローバル変数が26900バイト(8%)を使っていて、ローカル変数で300780バイト使うことができます。
esptool.py v4.5.1
Serial port COM3
Connecting....
Chip is ESP32-D0WD-V3 (revision v3.1)
Features: WiFi, BT, Dual Core, 240MHz, VRef calibration in efuse, Coding Scheme None
Crystal is 40MHz
MAC: 省略
Uploading stub...
Running stub...
Stub running...
WARNING: Failed to communicate with the flash chip, read/write operations will fail. Try checking the chip connections or removing any other hardware connected to IOs.
Configuring flash size...
Flash will be erased from 0x00001000 to 0x00005fff...
Flash will be erased from 0x00008000 to 0x00008fff...
Flash will be erased from 0x0000e000 to 0x0000ffff...
Flash will be erased from 0x00010000 to 0x00057fff...
Compressed 18992 bytes to 13110...

A fatal error occurred: Packet content transfer stopped (received 8 bytes)
Failed uploading: uploading error: exit status 2

いろいろと調べて、パーテーションを変えてみるとかしても、ダメですね。

れ、もしかして不良品なんでしょうかね。

ちょっとお手上げ、安物買いの銭失いか。


2024-4-29追記
Arduino IDE ツール で Erase All Flash Before Sketch Upload をEnableしても、Flash Frequency を40MHzに落としても、ダメ。
アマゾンで買った物の品名は、waves nodeMCU-32 なので、これを頼りに、以下を参考にいろいろとやってみましたが、ダメ。
ArduinoIDEでNodeMCU-32を使えるようにする‼ – ど素人電子工作 (toccho.net)

いろいろと設定を変えても、EN押す→BOOT押す→EN離す→BOOT離すで、シリアルモニタ画面に以下出るものの、
何をやっても、画面の状態は変わらずそのまま。以下Node32sを選択した例。
Photo_20240429135501

出力画面では、いろいろ設定等変えながら書き込んでも、以下のFlashとの通信異常のメッセージが出るだけ。 Photo_20240429135301_20240501192101


最大1310720バイトのフラッシュメモリのうち、スケッチが292949バイト(22%)を使っています。
最大327680バイトのRAMのうち、グローバル変数が26900バイト(8%)を使っていて、ローカル変数で300780バイト使うことができます。
esptool.py v4.5.1
Serial port COM4
Connecting....
Chip is ESP32-D0WD-V3 (revision v3.1)
Features: WiFi, BT, Dual Core, 240MHz, VRef calibration in efuse, Coding Scheme None
Crystal is 40MHz
MAC: 省略
Uploading stub...
Running stub...
Stub running...
WARNING: Failed to communicate with the flash chip, read/write operations will fail. Try checking the chip connections or removing any other hardware connected to IOs.
Configuring flash size...
Erasing flash (this may take a while)...

A fatal error occurred: Packet content transfer stopped (received 8 bytes)
Failed uploading: uploading error: exit status 2

NodeMCU-32Sで試してもだめ。
アマゾンの商品の詳細説明の、製造元リファレンス ‎ESP32-NM-W-NP を頼りに、選択するボードを探しましたが、該当しそうなものは見つからずです。困った。

以下、参照したネット情報。
Amazon | waves NodeMCU-32 デュアルコア 開発ボード ESP32 WiFi Bluetooth Type-C ワイドバージョン I/O拡張ボード 付き | waves | マザーボード 通販
 BOOTを押し続けるとか、1uFを付けるとか、10分放置するとか、記載があります。
ArduinoIDEでNodeMCU-32を使えるようにする‼ – ど素人電子工作 (toccho.net)
ESP32-WROOM32開発基板NODE MCU ESP-32Sを使う | たまねぎブログ (tamanegi.digick.jp)

Arduino IDEでESP-WROOM-02のボード設定について #Arduino - Qiita
DIO, DOUT, QIO, QOUTって、なんなん? #Arduino - Qiita

ESP32-WROOM-32U Program error - Using Arduino / Project Guidance - Arduino Forum
Boot Mode Selection - ESP32 - — esptool.py latest documentation (espressif.com)
Parts:DevBoard:ESP32-DevKitC-32D - robot-jp wiki

 



2024-4-29追記
のは試しで、以下を参照しesptoolでFLASHの様子を覗いて見ました。
ESP32でesptool.pyの使い方 | Lang-ship
esptoolによるESP32のMicroPythonファームウェアの書き込み – マイクロファン ラボ (microfan.jp)

有益なヒントが見つかるかと期待するも、実行結果は以下です。

Flashとの通信がFail、read/writeは失敗するだろう。Flashサイズも不明。
これじゃーねー。Arduino IDEのメッセージと変わらないし、ヒントも何もなし。


C:\Users\username\esptool-master\esptool-master>esptool.py flash_id
esptool.py v4.7.0
Found 1 serial ports
Serial port COM3
Connecting....
Detecting chip type... Unsupported detection protocol, switching and trying again...
Connecting......
Detecting chip type... ESP32
Chip is ESP32-D0WD-V3 (revision v3.1)
Features: WiFi, BT, Dual Core, 240MHz, VRef calibration in efuse, Coding Scheme None
Crystal is 40MHz
MAC: 省略
Uploading stub...
Running stub...
Stub running...
WARNING: Failed to communicate with the flash chip, read/write operations will fail. Try checking the chip connections or removing any other hardware connected to IOs.
Manufacturer: ff
Device: ffff
Detected flash size: Unknown
Flash voltage set by a strapping pin to 3.3V
Hard resetting via RTS pin...

C:\Users\username\esptool-master\esptool-master>

もしかしてFlashを積んでいない、偽物だったりして。
モジュールの蓋を剥がして中を覗いて見たくなってきました。
その前にやれることはないか、考え中。

...数時間後...

っかくesptoolが使える様にしたので、以下を参照して、efuseの状態を見てみました。

ESP32-WROVER-E/ESP32-DevKitC-VE ● Disable ROM Basic の件 - CT5002    dellbee's blog (fc2.com)

ESP32がCOM3割り当てとなっている事を確認し、以下のコマンドを実行。

>py -m espefuse -p COM3 summary

結果のレポートを見ると、BuiltinBasicの起動を禁止のefuse値がTrue R/W(0b1)
CONSOLE_DEBUG_DISABLE (BLOCK0) Disable ROM BASIC interpreter fallback = True R/W (0b1)

れじゃーBuiltinBasicが走る訳がないですね。
Esp32_efuse_result

回の衝動買いは、BuiltinBasicは起動不可が確認できて完全に失敗書き込みもできないので、普通に使う事もできない状態。
どうしましょう。

 



2024-4-30追記
esptoolが使えるので、flash関係のコマンドを2つ実行してみました。ステータスのリードと消去です。
共に、実効結果は、esptool flash_id 実行時のメッセージと最後の方だけしか変わらないので、最初と最後の方だけのピックアップです。

ステータスのリードの結果


C:\Users\username\esptool-master\esptool-master>esptool.py read_flash_status
esptool.py v4.7.0

Found 1 serial ports
Serial port COM3
Connecting......

省略

WARNING: Failed to communicate with the flash chip, read/write operations will fail. Try checking the chip connections or removing any other hardware connected to IOs.
Status value: 0xffff

続いて消去の結果


C:\Users\username\esptool-master\esptool-master>esptool.py erase_flash
esptool.py v4.7.0
Found 1 serial ports
Serial port COM3
Connecting....

省略

WARNING: Failed to communicate with the flash chip, read/write operations will fail. Try checking the chip connections or removing any other hardware connected to IOs.
Erasing flash (this may take a while)...

A fatal error occurred: Packet content transfer stopped (received 8 bytes)

何をやっても、だめ。本当にFLASH積んでるのって感じです。

うなったら、FLASHを積んでるのか確かめるため、モジュールの蓋を開けてみますかね。


2024-5-1追記
いに決断、モジュールの蓋を開けて、中を覗いて見ました。
確かハンズで以前買っていた、円盤形ダイアモンドリュータービットをドリルチャックに付け、ドリルをゆっくり回しながら押し付け、金属板を少しずつ削りながら、ところどころ穴が貫通気味になったところで、カッターで切れ目を広げ、蓋を剥がす感じで進めました。
Img_0281

30分程格闘し、何とか蓋を切り取りました。
Img_0307

ジュール部分の拡大写真です。文字・数字は写真から読んだので正確ではないかもしれませんが、
ESP32チップがEspressif ESP32-D0WD V3 372023 UGOOMAHO51、
FlashチップがPUYA PY25Q32HB 3E1P83A、
40MHzクリスタルがJWT 40.000CT2、
かな、他チップ部品が多数があります。
一応Flashは積んでいる様ですね。Flash未実装を疑ったが、そこまでひどくはなかったかな。
Img_0297
向きを変えた写真。
Img_0296

側面の金属板は基板に半田付けされているだけなので、ニッパーで一カ所切り、ニッパーで挟んでゴリゴリすれば、簡単に外せました。
Img_0309
Img_0312
Flashメモリ Puya Semiconductor社 PY25Q32HBに関する情報
PY25Q32HB Datasheet V1.3_pdf (puyasemi.com)
普冉半导体(上海)股份有限公司 (puyasemi.com)

Espressif純正ではないコピー品で、最悪Flash無しの偽物商品かと疑いましたが、そこまでひどい状況ではありませんでした。
ですが、スケッチの書き込みもできませんでしたし、分解までしたので電源は危険なのでもう入れません。
単なるモジュール内の観賞用に取っておくだけかな。


続報あればまた。

 



ESP32のリセットタイミングの補足

最新のESP32-WROOM-32Eのデータシートにも、以下の記載がありますね。回路図では0.1uFがENに繋がっていますが、説明文では1uFが推奨の様です。推奨のRC時定数は、RCdelay=10KΩ×1uF=10msになります。
Img_0263
左上EN端子のR1とC3はTBDのままだし、右下R2は0Ω、C4は0.1uFで、ENのスイッチを押して離した際の時定数が重要なのでしょうが、EN端子の内蔵PullUp抵抗値など情報がありません。しょうがないので手持ちのESP32-DevkitC-32EのEN端子を押した後の立ち上がりをシングルトリガーにしてオシロで観測してみました。約100us程度の時定数の様です。
Img_0264
τ=RCの関係からR=τ/C=100us/0.1uF=1KΩとなるので、約1KΩのPullUp抵抗があるように見えました。ボードを良く見たら、R1が1KΩで実装されているのかもしれませんが、プリントパターンも見えないし、チップ部品も小さ過ぎて見えないしシルク印刷も無しで未確認。推奨の時定数に対しては、1/100程度とかなり小さくてすむ理由は分かりません。
Schematic Checklist - ESP32 - — ESP Hardware Design Guidelines latest documentation (espressif.com)を見ると、Chip Power-up and Reset Timing に以下の記載があります。ここで言うCHIP_PUはEN端子の事と思いますが、50usのリセット時間が必要とあり、10KΩと1uFのRC Delayの記載があります。
BOOT Option JP2とありますが、IO0とGNDを接続する、BOOTスイッチかな。

Photo_20240424201301

Photo_20240424201501

 


続報あればまた。

 

2024年4月16日 (火)

Arduino ESP32 ライブラリの不用意なバージョンアップは危ないかも

TinyBasicの拡張をやっている際に、最新APIライブラリの説明と、実際にArduino IDEでコンパイルに使っているバージョンに差がある事が分かったため、少し調べてみました。

Arduino ESP32 の最新APIライブラリの説明を参照すると、ledcAttachや、ledcAttachChannelがあります。
 でも私のArduino IDEの環境では、エラーが出てしまい実際には使えませんでした。
 ledcSetupやledcAttachPinの記載はないものの、こちらの方は問題なく使えたため、コード記述・コンパイルに使いました。

Arduino ESP32 APIの更新情報には、2.Xから3.0への更新の際の差分として、LEDCだけでも以下の記載があります。
 破壊的な更新( breaking changes )として、大々的に変わってしまう様で、詳細なマイグレーションガイドも書かれています。
 Photo_20240415154901
 
正直、こんなに変わってしまって、いいの? って感じです。困ってしまう人が続出しそう。危ない危ない!

・自分のArduino IDEで使っているライブラリは最新のはずだと思っていますが、アップデートの仕組みや仕方が良く分かっていません。
一応、Arduino IDEのボードマネージャーでは、esp32 by Espressif Systemsが2.0.15(プルダウンメニューの最上位)をインストール済み。ボードじゃなくて、ライブラリマネージャーを開いても、それらしき項目を見つけきれません。
 Photo_20240415161601_20240417164601

・気になるのは、今後最新のものに勝手にアップデートがかかってしまうと、コンパイルでエラーが出てしまう点です。
 その場合は3.0ではなく、2.Xに戻せばOKのはずなんだろうとは思います。
 まだライブラリを戻すとかやった事がないので、必要になった時に改めてやり方を調べる予定。
 複数のバージョンを共存させる方法もありそうです。
 └esp32-arduinoの複数バージョンを共存させる | Lang-ship

・もし、不用意にアップデートすると、下の記事の様に余計な手間がかかるみたいで、それはそれで危険そうですしね。
 └[ESP32]Arduino core for the ESP32のバージョンを上げると動作しなくなったことについて | farmsoft
 └Arduino IDE ESP32ボードのバージョンアップに伴うTimerCameraライブラリの変更内容 - MSR合同会社 (msr-r.net)

・どうもライブラリがリリースが公開されるのは、GitHubの様です。
 GitHub - espressif/arduino-esp32: Arduino core for the ESP32 を開くと、画面右下の方に、Releases (53)と言うところがあり、
 そこに Arduino Release v2.0.15 based o... (Latest)とあり、ボードマネージャーで見た、
 esp32 by Espressif Systemsの2.0.15 と一致しています。
 Photo_20240416195601
 上記赤丸部分を拡大したのが以下。
 Photo_20240416193801
 上記の(Latest)をクリックすると、Arduino Release v2.0.15の説明画面に飛び、こちらにも右端には(Latest)とあります。
  Photo_20240416194001

 + 52 releases をクリックしたら、v3.0.0が出てきました。但し(Latest)ではなく、右端は(Pre-release)になっています。
 Photo_20240416194201
 開発環境ESP-IDFのv5.1に合わせた、ライブラリアップデートの様ですが、まだ先行リリースの段階の様です。
 なので、ライブラリが勝手にアップデートされる事はないのでしょうね。


いろいろと調べると、Espressif社の公式な開発環境は、ESP IDFの方であり、Arduino IDEは有志により開発されているらしい事も分かってきました。どうりでコントリビューターのアイコンが沢山並んでいます。

まだ、v3.0.0は(Pre-release)なので、Arduino IDEで自動ではアップデートされないとしても、今後(Latest)になると、自動アップデートされて、エラーに見舞われアタフタしそうな予感がします。

今後、GitHubのArduino ESP32 ライブラリの情報は、今後もウォッチしておく必要がありそうです。特に下記の右下赤丸部分。
Photo_20240416195601

 

2024-5-5追記 最新ライブラリを覗いてみたら、2日前に、v2.0.16に更新されていました。

説明ではUART関係の更新で、Updateしても問題なさそうなので、更新しました。
Photo_20240505103601

Arduino IDEを起動したら、更新するか聞かれ、ボードマネージャーでUPDATEを押し更新しました。
Photo_20240505103901

 


 

続報あればまた。

 

2024年4月12日 (金)

★★★タイニーBASIC GPIO+AnalogIO拡張 PWM高速化・ADC高精度化

E S P 3 2
豊四季タイニーBASIC WiFi Telnet版
GPIO・PWM・ADC・DAC
操作 拡張関数
プチ改良:
PWM高速化・高精度ADC

先日拡張が成功したGPIO+AnalogIO版ですが、以下の点で気になっていました。
・TinyBasicは扱う数値の最大値が32767のため、単純にはPWM出力周波数を32,768Hz以上に出来ない
・ESP32で用意されているキャリブレーションされた、精度の高いanalogReadMilliVolts()関数を取り込んでいなかった
GPIO16,17はWROOMでは使えるものの、非対応としていた。

今回、時間があったので、以下の通りプチ改良してみました。
・PWM出力最大周波数をESP32限界の40MHzまで出せるようにした。
 参考 PWM制御とは?Arduino(ESP32)コマンドで使い方を詳しく紹介 | ロジカラブログ (logikara.blog)
 TinyBasicでは40MHzは直接指定できないので、数値FRQと係数FMLTの2つの引数を記述し、
 その積を出力周波数としuint32_t型に変換して、ledcSetup()関数へ渡すようにした。
・上記に合わせて、分解能RESをESP32の最大値20bitsまでにし、
 最大40MHz Duty50%まで出せ、分解能も最大限細かく設定できるようにした。
・analogReadMilliVolts()に相当する、高精度ADC関数を用意した。
 参考 ESP32のADCでキャリブレーションされた精度の良い電圧値を取得する方法 | kohacraftのblog
・GPIO・PWM操作の対象GPIOに、WROOMで利用可能な、GPIO16,17を加えた

一応、PWMの指定可能範囲を拡大したので、いろいろと設定値を変えて、動作確認をしました。
その中では、設定変更が効かないケースもあり、その場合シリアルインターフェイスでエラーメッセージと共に、ヒントが送信されてくるので、デバッグに役立つ事も分かりました。これに関しての関連記事等は今現在見つけきれていませんが。
analogReadとanalogReadMilliVoltsの変換結果を比較では、ちょっと予想外の結果も判明しました。
arduino ESP32のライブラリのバージョンで、使用可能なAPI関数名や書式が変わってしまう事にも気づいたので、補足しました。

豊四季TinyBasicの文法は、豊四季タイニーBASICの文法 | 電脳伝説 (wordpress.com) を参照ください。
また、SAVE [BOOT]、LOAD が使えます。 

-------------------------------------------
本記事の目次です。
・改訂した拡張関数の仕様とGPIO選択表
・主に工夫した点
・デモ結果
 ・PWM出力の最高周波数40MHzの例
 ・PWMでの76Hz出力の例
 ・TinyBasicで扱える最小値1HzのPWM出力例
 ・不適切なPWM設定はシリアルからのメッセージでデバッグ
 ・AD変換のデモと結果のグラフ
 ・AD変換のオフセットの考察と追加実験
・ソースコードの公開と注意・使用方法
・Arduino IDE ESP32 APIライブラリの補足
・雑感

以下詳細です。

 


改訂した、拡張関数の仕様と、GPIO選択表は、以下です。

Ttbfunc
 尚、ライブラリのバージョンは Arduino ESP32 version 2.0.15 (現時点のLatest版)を使っています。

Gpiopintable2

今回、主に工夫した点は以下です。

・PWM出力の周波数を指定するledcSetup()への周波数の引数はuint32_t型で与える必要があり、
 FRQとFMLTの積を取りstatic_castでuint32_t型に変換しました。
 ledcSetup(chn, static_cast<uint32_t>(frq * fmlt), res);
 TinyBasicでは数値や変数・配列は全てshort int型なので、static_castで十分なはず。

・キーワードテーブルとenumではANALOG_READ_MILLIVOLTSをANALOG_READよりも先に記述した。
 最初は逆に記述してしまい、ANALOG_READ_MILLIVOLTSを実行したいのに、内部処理的にANALOG_READが実行されてしまい、
 残りの文字列"_MILLIVOLTS"でpin番号を得ようとしエラー、この原因究明に数時間悩んでしまいました。
 先頭からの文字列が同じキーワードは、長い方を先に記述する必要がある点、「タイニーBASICをCで書く」に注意書きありました。
 Photo_20240414085901

・ADCの減衰量設定は、前回確認できたので、以下の1行で済ませました。
 analogSetPinAttenuation(pin, static_cast<adc_attenuation_t>(attn));

 



以下、デモ結果です。


■ PWM出力の最高周波数40MHzの例です。
40MHzだと、GPIO出力の遷移時間・出力インピーダンス、オシロスコープ・プローブの帯域、測定系の配線状態等、種々の影響を受け綺麗な方形波になりませんが、こんなもんでしょう。

100 REM GPIO32 PWM simple test
110 P=32; REM GPIO 32
120 C=0 ; REM PWM channel = 0
130 R=1 ; REM resolution
200 F=4000
210 M=10000
220 D=1
300 LEDC_SETUP C,F,M,R
310 LEDC_ATTACH_PIN P,C
320 LEDC_WRITE C,D

Img_0238

 

■ PWMでの76Hz出力の例です。
RESが20bitsに対し、Dutyが32767なので、オシロ波形のデューティは3%(32767/(2^20=1048567))になっています。
RESを荒くすれば、76Hz出力でもデューティをもっと大きく出来ます。

100 REM GPIO32 PWM simple test
110 P=32; REM GPIO 32
120 C=0 ; REM PWM channel = 0
130 R=20 ; REM resolution
200 F=76
210 M=1
220 D=32767
300 LEDC_SETUP C,F,M,R
310 LEDC_ATTACH_PIN P,C
320 LEDC_WRITE C,D

Img_0239

 

■TinyBasicで扱える最小値1Hzでの出力例です。
PWM 1Hz デューティ50%の波形例です。

100 REM GPIO32 PWM simple test
110 P=32; REM GPIO 32
120 C=0; REM PWM channel = 0
130 R=12
200 F=1
210 M=1
220 D=2048
300 LEDC_SETUP C,F,M,R
310 LEDC_ATTACH_PIN P,C
320 LEDC_WRITE C,D

Img_0241

 

■ 不適切なPWM設定はシリアルからのメッセージでデバッグ
PWM回路に対し不適切な設定を行った場合は、シリアルインターフェイスでメッセージが送信されますので、ヒントになります。
上記に対し、130 R=6に変えてrunしてみると、以下のメッセージが返ってきました。

E (1069533) ledc: requested frequency and duty resolution can not be achieved, try reducing freq_hz or duty_resolution. div_param=320000000

この例では、RES=6bitsのため、Duty指定範囲は1~63ですが、2048を指定したままなので、設定変更されず、周波数かデューティを下げろと言ってきています。

100 REM GPIO32 PWM simple test
110 P=32; REM GPIO 32
120 C=0; REM PWM channel = 0
130 R=6
200 F=1
210 M=1
220 D=2048
300 LEDC_SETUP C,F,M,R
310 LEDC_ATTACH_PIN P,C
320 LEDC_WRITE C,D
シリアルインターフェイスに出力されるエラーメッセージ例Photo_20240413145701

WiFiでのTinyBasicとの接続だけでなく、PCのUSBでSerial (上記では TeraTerm シリアル COM6 115200bps 8bits パリティ無し)に接続しておけば、簡易的ですがデバッグに役立ちそうです。

2024-4-21追記
ESP-IDFのAPIの説明に、以下の記述がありました。注意Arduino ESP32 APIの説明では記述は見当たりません。
Photo_20240421223501
LEDC APIはハードウェアの対応範囲を超えた周波数とデューティ分解能をセットしようとすると、シリアルモニターにエラーをレポートするように設計されているとの事です。
親切なライブラリと言う事か? ユーザーでの設定トラブルが多く、問い合わせやフォーラムでの質問が多いと言う事かな?

2024-4-22追記
Arduino ESP32 APIのライブラリにも、メッセージを出すと思われる記述がありました。以下自分のPC環境での例です。
C:\Users\username\AppData\Local\Arduino15\packages\esp32\hardware\esp32\2.0.15\cores\esp32\esp32-hal-ledc.c 
を見ると、ledcSetup()関数では、LEDCチャンネルかビット幅が最大値を超えた際にメッセージを出し、実行無しでリターンですね。

uint32_t ledcSetup(uint8_t chan, uint32_t freq, uint8_t bit_num)
{
   if(chan >= LEDC_CHANNELS || bit_num > LEDC_MAX_BIT_WIDTH){
       log_e("No more LEDC channels available! (maximum %u) or bit width too big (maximum %u)", LEDC_CHANNELS, LEDC_MAX_BIT_WIDTH);
       return 0;
   }

単純な引数の数値範囲チェックだけは、本簡易拡張でもしていますけどね。

 


 

■AD変換のデモと結果のグラフです。
analogReadMilliVoltsの方は、縦軸をmVとして電圧値が読み取れますし、特に11dbで直線性が改善しているのが分かります。
ただ、全ての減衰量でも低電圧側オフセットが100mV程度ある様です。

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 #5,ANALOG_READ A,",",#5,ANALOG_READ_MILLIVOLTS 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 #5,ANALOG_READ A,",",#5,ANALOG_READ_MILLIVOLTS A
440 NEXT D
450 PRINT;PRINT
460 RETURN
Analodread

Photo_20240415140001


・AD変換結果のオフセットの考察と追加実験
analogReadMilliVoltsの下限側100mV程度のオフセットが気になります。
たぶんDAC出力がオフセットを持っていると考えられますが、測定での確認まではしていません。
データシート類には情報が見当たりませんが、以下のフォーラム記事を見つけました。

Digital To Analogue Converter Characteristics - ESP32 Forum

記事を読むと、上限は電源電圧より少し(120mV?)程度下がり、下限はGND(0V)より少し(50mV?)程度上がっている模様。

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

ならば、単純に、AD入力にGND(0V)を繋いで、AD変換結果がどうなるか調べれば済むので、やってみました。
アッテネーションを変えながら、10ms毎に2回づつ、analogReadとanalogReadMilliVoltsを実行させた結果です。

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
330 DELAY_MS 10
340 PRINT #5,ANALOG_READ A,",",#5,ANALOG_READ_MILLIVOLTS A
360 PRINT
420 DELAY_MS 10
430 PRINT #5,ANALOG_READ A,",",#5,ANALOG_READ_MILLIVOLTS A
450 PRINT
460 RETURN

 

GPIO36(ADC入力)をGNDに接続した場合
減衰量に応じて0ではない、特定の値が得られています。

減衰量 analogRead analogReadMilliVolts
-------+--------------+----------------------
 11db           0                   142
 11db           0                   142
   6db           0                   107
   6db           0                   107
 2.5db          0                     78
 2.5db          0                     78
   0db           0                     75
   0db           0                     75

参考で、GPIO36(ADC入力)に何も繋がない場合です。

ノイズできちんと暴れています。

減衰量 analogRead analogReadMilliVolts
-------+--------------+----------------------
 11db         453                  142
 11db       1488                 1100
   6db       1297                 1368
   6db             0                  252
 2.5db            0                    78
 2.5db            0                    78
   0db        4095                    75
   0db        4095                 1112

何と、予想に反し

analogReadの方は全て0が返ってきたものの、
analogReadMilliVolts側は、キャリブレーション(補正)で付与されたと思われる値が返ってきました

しかも[mV]単位で電圧値を返すはずなのに、減衰量設定によって電圧値が変わっています
減衰量11dbだと142mV、6dbで107mV、2.5dbで78mV、0dbで75mVのオフセットがある様です。

どう解釈するのかは良く分かりませんが、
analogReadMilliVoltsでは、AD変換結果に一定のオフセットが付与されているのが判明しました。

まあ、esp32_datasheet_en.pdf (espressif.com)にある下の表では、実効的な測定範囲が明記されていて、GND(0V)入力はこの範囲未満となり、そもそも精度保証範囲外、気にしてはいけないって事なのでしょう。



ESP32の電気的特性に関する情報はかなり乏しいので、これ以上の調査は厳しそうな予感。

まあ、ESP32では、ADC・DACに精度を求めるべきではなく、心配なら実験で性能をある程度把握し、使えそうな範囲内で使う。
そんな扱いが必要そうです。

 


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

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

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

 


・Arduino IDE ESP32 APIライブラリの補足

尚、Arduino ESP32 の最新APIを参照すると、ledcAttachや、ledcAttachChannelがありますが、実際には使えませんでした。
調べると、ESP-IDF 5.1に対応したArduino ESP32 v3.0.0の説明で、v3.0.0自体はまだ、Pre-Release段階の様です。
私のArduino IDEでは、v2.0.15なので、ledcSetupやledcAttachPinはまだ、使えました。

もし、Arduino ESP32 v3.0.0 がLatestリリースになり、Arduino IDEで自動アップデートがかかってしまうと、コンパイルでエラーが多発する可能性が高く、その場合は、2.0.15に戻せばOKのはずと思います。

別記事で、もう少し詳しく書きました。

GitHubのArduino ESP32 ライブラリの最新情報(以下のURL、赤丸部分)を今後もウォッチしておく必要がありそうです。

GitHub - espressif/arduino-esp32: Arduino core for the ESP32
Photo_20240416195601

 


・まとめと雑感
今回、PWMの高速化、高精度ADC関数の、TinyBasicへの取り込みが実施できました。
拡張には慣れてきましたが、未知の対処方法を考えないといけないケースも出てきました。
例えばstatic_castが必要だったり、short int型2つの積をuint32_t型に型変換してからライブラリ関数の引数として渡すとかです。
TinyBasicの数値範囲を超える必要性が出てきて、どうしようかと少し考え、スマートではないにしても対応できました。
それはそれで良い勉強になりました。

一応、デモ等でも動作確認・設定値の有効範囲の確認など実施したつもりですが、誤りが含まれている可能性があります。
特に、PWMの設定では、不適切な設定の場合シリアルインターフェイスでエラーメッセージが送信されてくるので、いろいろと気付けたし、デバッグに役立つ事も知りました。

Arduno ESP32のAPIをどんどん取り込むのも一つの方向性かも知れませんが、TinyBasicで扱える範囲の簡単で低速で済むアプリ開発を考え、そこそこ頻繁に使いそうなAPIに絞り、便利そうなら拡張する程度が、本来のTinyBasicの守備範囲として適切なんだろうとの思いもあります。
今後ESP32をもっと使ってみて、どうするかは未知数ですけどね。


-------
本ブログは、過還暦脳活を第一の目的としております。なので、ここに記載のTinyBasic改良の実用性やコード記述のスマートさ等は、少し置いといて、「脳活題材でTinyBasicの拡張にチャレンジしているやつもいるんだなー」程度の目で見て頂けると助かります。
しかし、TinyBasicの拡張はなかなか面白く、楽しみながらやっています。

 


続報あればまた。

 

2024年4月 6日 (土)

ESP32 WROOM/WROVER GPIO16,17使用可否実機検証

先日拡張したTinyBasicの開発に使った手持ちのボードではGPIO16,17ピンが出ておらず、GPIO操作対象外としてました。
他のボードを調べていたら、普通のESP32-DevKitC-32EやESP32-DevKitC-VEでは、外部ピンとして出ているのが分かりました。
ボードにより、ピンあるならTinyBasicでの操作対象にしておくべきとの思いが浮かんできました。

今回、秋月電子から開発キットのESP32-DevKitC-32EとESP32-DevKitC-VEを購入したので、TinyBasicでGPIO16,17の操作を試し、使えるか検証してみました。

結論を表にまとめてみました。

開発キット 搭載モジュール PSRAM・FLASH GPIO16,17用途 GPIO16,17使用可否
ESP32-DevKitC-VE WROVER 8M PSRAM有
8M FLASH有
PSRAM制御に使用
 CS#、SRAM_CLK
不可
NC
ESP32-DevKitC-32E WROOM PSRAM無し
4M FLASH有
フリー

使用可

TinyBasic GPIO+AnalogIO版へのフィードバックとしては、GPIO16,17を操作対象としておき、
WROVERモジュールを使っている場合は実際には使えない事に注意」程度にしようと思います。

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

2024-4-21追記
ArduinoIDEでのタイニーBASICの書き込みの際に出力画面に出るメッセージには、chip型番、搭載メモリ情報、CPUクロック、MACアドレスなどの情報が書き出されているのに気づきました。今後のタイニーBASICの拡張・プログラム領域拡大・スタック深さ拡大などで、参考になりそうなので、以下にメッセージ例を添付。

ESP32-DevKitC-32E
(ESP32-WROOM-32E)
最大1310720バイトのフラッシュメモリのうち、スケッチが754525バイト(57%)を使っています。
最大327680バイトのRAMのうち、グローバル変数が78836バイト(24%)を使っていて、ローカル変数で248844バイト使うことができます。
esptool.py v4.5.1
Serial port COM6
Connecting....
Chip is ESP32-D0WD-V3 (revision v3.1)
Features: WiFi, BT, Dual Core, 240MHz, VRef calibration in efuse, Coding Scheme None
Crystal is 40MHz
MAC: 省略
ESP32-DevKitC-VE
(ESP32-WROVER-E)
最大1310720バイトのフラッシュメモリのうち、スケッチが772921バイト(58%)を使っています。
最大327680バイトのRAMのうち、グローバル変数が78924バイト(24%)を使っていて、ローカル変数で248756バイト使うことができます。
esptool.py v4.5.1
Serial port COM5
Connecting....
Chip is ESP32-D0WD-V3 (revision v3.1)
Features: WiFi, BT, Dual Core, 240MHz, VRef calibration in efuse, Coding Scheme None
Crystal is 40MHz
MAC: 省略

ESP32-D0WD-V3(チップ内FLASH/PSRAM無し)を搭載し、内蔵SRAMが327,680バイト等分かります。(データシートでは520KB SRAMとの記載ですが)。
尚、ArduinoIDEのツールメニュー、FlashのPartition Schemeでは、"Default 4MB with spiffs(1.2MB APP/2.5MB SPIFFS)"を指定しているので、アプリには1.2MB(1310720バイト)を割り当てている条件下でのメッセージです。

Photo_20240421093701
余談ですが、タイニーBASICを載せても、内蔵RAMのリソースは余裕たっぷりなので、もっとプログラム領域を広げるとか、配列要素数やスタック数を増やすとかできそうです。

#define SIZE_LIST 1023 //List buffer size
#define SIZE_ARRY 32 //Array area size
#define SIZE_GSTK 6 //GOSUB stack size(2/nest)
#define SIZE_LSTK 15 //FOR stack size(5/nest)


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

以下、今回調査の詳細です。

 


 

各ボード毎のGPIO16,17ピンの有無

Photo_20240408193701 実際、手持ちで実機検証に使っているFreenove社ESP32-WROVER-Eの開発ボード(写真右)は、カメラモジュールがボード上のコネクタに繋げられる仕様で、カメラ用途で8MBのPSRAMを搭載し多用するためか、GPIO4と5に間にはGPIO16,17が無くGND 2つに代わっています(左図赤枠部分)。またボードのピンの数は、片側20ピン、両側で40ピンと多いです。

秋月のESP32-DevKitC-32E(写真左)と、ESP32-DevKitC-VE(写真中央)では、GPIO16,17が端子に出ています(左図青枠部分)。ピン数は片側19、両側38。純正DevKitCも秋月同様GPIO16,17が出ています。

この事から、手持ちの方が特殊で、通常の開発ボードでを配慮すると、TinyBasicでは操作対象にしておくべきと考え、今回実機で検証しています。

 

PSRAMとFLASHの有無に着目しての比較すると、

ESP32-DevKitC-32E(ESP32-WROOM-32Eモジュール搭載)は PSRAM搭載無しFLASH(4MB)搭載有り
ESP32-DevKitC-VE (ESP32-WROVER-Eモジュール搭載)は  PSRAM(8MB)搭載有りFLASH(8MB)搭載有り

です。以下、Espressif社のDevKitCのWebより抜粋
Photo_20230628203701_20240406172801

今回以下の2者で実機でGPIOを操作して、波形で比較してみました。
ESP32-DevKitC-32E ⇒ 波形出力OK
ESP32-DevKitC-VE   ⇒ 波形出ずNG、全く反応なし

以下、GPIO16,17テストプログラムとオシロ波形です。黄色CH1がGPIO16、青色CH2がGPIO17です。


GPIO16,17テストプログラム

ボード:ESP32-DevKitC-32E

(モジュール:ESP32-WROOM-32)
PSRAM無し:波形出力OK

ボード:ESP32-DevKitC-VE

(モジュール:ESP32-WROVER-E)
PSRAM搭載:波形出ず、全く反応なし

100 REM ---- GPIO16,17 TEST ----
110 PIN_MODE 16,3; PIN_MODE 17,3
200 REM
210 DIGITAL_WRITE 16,1
220 DIGITAL_WRITE 17,1
230 DELAY_MS 100
300 DIGITAL_WRITE 16,0
310 DIGITAL_WRITE 17,0
320 DELAY_MS 100
400 GOTO 210
Img_0227 Img_0226

上記実機検証結果より、ESP32-DevKitC-VEでは全く反応しません。記事の後半でNCを確認。

2024-4-7追記 WROVERであっても、モジュール選択やPSRAM利用設定を変えればどうなるか調べてみました。
・ボードマネージャーでESP32 dev module を選択すると、ツールにPSRAMの項目が現れ、disableかenableが選択できます。
 ここでdisableを選択し、コンパイルして書き込んでも、状況は改善せず全く反応しません。(下図左)
・ボードマネージャーでESP32 wrover moduleを選択すると、ツールにPSRAMの項目すら出てきません。(下右図)
DevWrover

雑感:

今回、GPIO16,17だけですが、開発ボードでのピンの有無に気づいて、実際に入手。
TinyBasicで試しで操作してみたら、今度は別の問題に引っ掛かり、調べて検証し、やっと状況が判明。
と言う感じでした。まあボード毎の制約事項の理解は深まりました。

なかなか、一歩づつ ステップバイステップ って感じですかね。
やってみないと分からないし、疑問を持って調べないと必要な情報には辿り着かないし、最初から注意・制限事項を熟知しておくなんて出来ないし、まあ世の中こんなもんなのでしょう。

ただ、TinyBasicインタープリタをESP32に書けば、TeraTermからの操作ですし、コマンドラインからの直接操作やプログラムの実行で、簡単便利で気楽にIOが操作出来るのって、とっても良い検証環境にもなるって事が、自分でも実感できました。

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

WROVERでGPIO16,17がPSRAMを制御している情報です。

・ESP32フォーラム記事の抜粋
(*1)Unable to use gpio 16 and 17 - ESP32 Forum
GPIO16 and 17 may be used for communication with flash or PSRAM, depending on particular chip or module that you have on your development board.
For example see the datasheet of ESP32-WROVER-E module.

Esp32wrovereflashpsram
WROVERのデータシートで最新情報を確認。
下図が15ページ Fig.7がモジュールのリファレンスデザインの回路図で、GPIO16がPSRAMのCS#へ、GPIO17がPSRAMのSRAM_CLKへしっかり繋がっています。
Photo_20240406212001
2024-4-13追記
WROVERのデータシートの周辺回路図 Fig.9を見ると、IO16,17が並んでいるはずの、IO4とIO5の間がNCになっています。
モジュール内でPSRAMと繋がるので、外からは使えない様に、NCにしているのでしょう。
なるほど、今回テスト的にGPIO16,17を強制的に動かしてみたつもりでも、NCなので波形には何の反応も現れない訳ですね。

Photo_20240415072501

2024-4-13追記
WROVERのモジュールは、GPIO16,17がNCとなっているのが本当か、確かめてみました。
単純に、GPIO16,17をOUTPUTに設定し、共に0を出力、GPIO36,39のADC入力へ接続し、ADC変換結果を読み取るものです。
ブレッドボード上で、配線を伸ばしてノイズを拾いやすくしておきました。
以下、テストプログラムと、ブレッドボード配線の写真、100ms毎10回のADC変換結果です。
結果は、予想通り、ADC結果は暴れているので、本当にNCとなっている様な結果が得られました。

100 REM ------ GPIO16,17 ADC INPUT Test ------
110 PIN_MODE 16,3; PIN_MODE 17,3
120 DIGITAL_WRITE 16,0; DIGITAL_WRITE 17,0
130 PIN_MODE 36,192; PIN_MODE 39,192
140 ANALOG_SET_PIN_ATTENUATION 36,3
150 ANALOG_SET_PIN_ATTENUATION 39,3
200 FOR I=0 TO 10
210 PRINT #5,ANALOG_READ 36,#5,ANALOG_READ 39
220 DELAY_MS 100
230 NEXT I

 

Img_0247

1回目の実行結果
Photo_20240415092601

2回目の実行結果
Photo_20240415092701_20240417121601

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

2024-4-10追記
一方、ESP32-WROOM-32Eの内部回路情報 Fig.5を見ると、PSRAMは無いですし、内蔵FLASHへはGPIO16,17は接続していない様です。
Photo_20240410113801

2024-4-13追記
ESP32-WROOM-32Eの周辺回路情報 Fig.7を見ると、IO16に注意書きがありました。
PSRAM内蔵のESP32-D0WDR2-V3等では、IO16を10KΩでPullUp、他の用途では使用不可とあります。

Photo_20240415065201

余り気にするべき所ではないかも知れませんが、以下の図が気になるので、念のため確認として調べました。
R11 0(NC)と言う書き方が、オープンなのかショートなのか自分的には混乱しています。
WROVERの回路なので、GPIO17をSRAM_CLKとして、SCK/CLKをFLASH_CLKとして用い、R11は未実装と言う意味で(NC)としているとは思いますが...
Photo_20240417120401
WROOMには、上記回路は見当たりませんが、FLASHは搭載されているので、FLASHとSRAMのクロックを兼用するための接続の目的が過去にあったのかもと思えてしまいます。
であるならば、WROOMのFLASHアクセスにGPIO17の影響は本当にないのか? が気になってしまう訳です。
WROOMの実機テストでDIGITAL_WRITEではGPIO16,17は普通に波形が出せましたが、それはTinyBasicでユーザープログラムの実行中に確認したものでしかなく、FLASHのアクセスはしてなかったので、ハードウェア的に動かしっ放しにできるはずのPWM出力を、GPIO16,17へ出し続け、[esc]でユーザープログラムの走行を止め、その状態でSAVEやLOADでFLASHのアクセスを行い、問題が発生するかどうか調べました。

WROOMにTinyBasicを載せ、GPIO16,17へPWMを出したまま、SAVE→NEW→LOADを繰り返してみました。書き込んだユーザープログラムが化けるとか、動作がおかしくなるとかの支障はみられませんでした。

関係ないはずと信じてはいたものの、確認するまでは安心できなかったのですが、今回WROOMなら、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さんには、感謝申し上げます。

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

続報あればまた。