ESP32 を使って LC共振回路の理解を深め、電波時計をガッツリ合わせてみる実験

ESP32 ( ESP-WROOM-32 )

保護ダイオードで、共振回路から ESP32 の故障を防ぐ

さて、では、恐らく、ESP32 開発ボード自体にも保護回路は入っているだろうとは思いますが、ここでは他のマイコンでの利用も考えて、上記のマイナス電圧から保護してみます。
定電流ダイオード CRD と、ショットキーバリアダイオード SBD を使ってみます。

ショットキーバリアダイオードの長所は、

●高周波特性が良い。
●順方向電圧降下 ( Vf )が小さい。

などがあります。
ただし、欠点として、

●通常のダイオードよりも逆電圧の漏れ電流が大きい

というものがあります。
ですが、今回の共振回路による負電圧はそれほど大きくないので、いろいろ試した結果、特に問題無かったのでこれを使いました。
定電流ダイオード CRD は、ESP32 の GPIO に流せる最大電流が約12mA程度だったと思うので、10mA の CRD を使いました。

結果、先に紹介した回路を以下のように修正してみました。

これで、ESP32 の GPIO にかかるマイナス電圧および過電流から保護できます。

ただし、この2つのダイオードを使うことにより、かなり電圧降下してしまい、最終的な回路では 3.3V の電圧が 1.0Vくらいまで下がってしまいます。
正直、もったいないですね。
CRD は電流値を計算して抵抗を選ぶ手間が省けるので、便利で重宝していますが、抵抗に替えても良いかも知れません。

とりあえず、私が独学で得た知識で知っている保護回路はこのくらいです。

共振回路ってそういうことだったのかー! と突然、理解できるようになった

さて、ここからは、私のド素人的考察が入ります。
熟練者の方が読むとアホらしいかも知れませんので、読み飛ばしてください。

では、ESP32 をダイオードで保護して、安全に共振回路を扱えるようになったので、実際にGPIOから矩形波パルスを共振回路に入れて、オシロスコープで波形を観測していきます。

先でもちょっと触れましたが、コンデンサの値をいろいろ変えたりして、しばらく実験をつづけていると、有る時、ふとサイン波形っぽい挙動を示すことがあります。
これがどうも謎でした。

特に疑問だったのは、GPIOがHIGHレベルのままにもかかわらず、電圧がサイン波状に勝手に下がってしまう挙動が現れるんです。

ですが、そこで、ふと、ひらめきました!!!

GPIOを1ms毎にHIGH→LOWを切り替えて負荷電圧を測定した図が以下になります。
青色の波形がGPIO直近の電圧波形。
赤色が10kΩ負荷の電圧波形です。

1msのパルスの長さだと、この回路では殆ど直流状態と同じなので、流れる電流が微々たるものです。
先ほど述べたようにインダクターによって殆ど短絡状態になっています。
ですが、切り替える瞬間の赤色の負荷電圧に注目してみると、微小な波形が出ています。
そこを拡大してみるとこんな感じになります。

微小電圧ですが、何やら振動していますね。

ここが重要です!!!

先ほどのやってはいけない危険な回路でも紹介したように、GPIOで3.3V掛けているにもかかわらず、しかもコンデンサがあるにもかかわらず振動しています

普通に考えると、コンデンサがあれば電圧が安定するはず。
ですが、インダクターを並列に加えると自然と振動してしまうんです。
まるで、GPIOからの電圧供給を無視しているかのように勝手に振動してしまうんです。
そこがミソのミソです。

では、もっと拡大してみましょう。

ズームしてみると、減衰してはいますが、波形だけ見ると綺麗なサイン波形を示していて、1波長が約 25us の 40kHz になっています。
つまり、インダクターとコンデンサで閉じた回路を組んで、スイッチして急激に電圧を与えてやれば、その共振周波数で自然と綺麗なサイン波で振動してくれるんです。

その間、一定電圧をかけているにもかかわらず、勝手に電圧が上がったり下がったりして、サイン波振動してしまうのです。

ならば、それを利用して、その波形を出来るだけ一定に維持して、電圧を大きくすることができれば、綺麗な一定のサイン波が生成できそうです。

要は、サイン波はインダクターとコンデンサだけで自然と生成されるんです!!!

こんなこと、学生でも当然のように理解しているかもしれません。
回路技術者や無線熟練者なら当たり前なことかもしれません。
でも、私には新鮮な驚きでした。

共振って、回路を組んでいると異常なノイズ発信とかで名前を聞くことも多いと思います。
そのため、手に負えない振動で、延々と拡大しつづける怪物的な神秘的なエネルギーで、理解がちょっと難しいもののように思っていました。

でも、このように、共振は放って置いたら減衰してしまう振動なわけで、それを減衰させないようにエネルギーを意図的に与えてやらないと、電波を発信する共振回路にはならないわけです。
つまり、サイン波の1つ目の山が下がる時にパルスをLOWにしてやれば山が反対に振れるので、それを繰り返してやれば一定のサイン波ができるわけです。
それも、半波長ごとに切り替えてやらねばなりません
このことに気付いた時は、自分の脳内で革命が起こった感じです。

つまり、こんな感じです。

これから考えると、共振回路の周波数と GPIO からの矩形波パルスの周波数がピッタリ合わないと、綺麗な40kHz のサイン波を作ることができません。

それって、かなり難しいような気がします。
ですが、安心して下さい
マイコンの GPIO からのパルスが 40kHz ピッタリであれば、LC 共振回路の周波数が多少ズレていても、後段にフィルタ回路を追加して、サイン波に近づけることができるんです。

そして、これからわかるように、LC共振回路に与えるパルスは、電圧が急激に変化する矩形波(方形波)が最も都合が良いことが理解できるのではないでしょうか。
これで、私個人としては、電波の発振回路に共振回路を使う理由がやっとわかりました!!!

「あーー! そういうことだったのか!!!」

となりましたね。
実際に手を動かしてパーツを選定して、そして測定し続けることによって、これが体感できたわけです。
私的には共振回路が怖くなくなりましたね。
そして、インダクターが大好きなパーツになりましたね。
いゃぁ~・・・、今回は大収穫でした!!!

このことは、机上や頭の中だけの計算式では分からなかったと思います。
電子回路や電子工作はやっぱり自分の手を動かして体感するに限るですね。

では、その考えに基づいて、保護ダイオードを入れたLC共振回路に、 40kHz の矩形波パルスを入れてみましょう。

プログラム(スケッチ)は以下のようになります。
これは、以前のこちらの記事のコメント欄で、Kat-Kaiさんに教えて頂いたものを使わせて頂きました。
ESP32 の CPU クロックカウントを取り出し、パルス長を微調整できるスケッチです。
以下のスケッチ出私の環境では 40kHz でした。

※この記事を書いたその後、PWM ( LEDC )ライブラリ関数を使えば、このソースコードよりも格段に安定した 40kHz パルスを出力できることが解りました。
以下の記事も合わせて参照してください。
(2019/04/04)

https://www.mgo-tec.com/blog-entry-ledc-pwm-arduino-esp32.html

 

【ソースコード】 (※無保証 ※PCの場合、ダブルクリックすればコード全体を選択できます)

const uint8_t gpio = 17;

//*****************セットアップ******************************
void setup() {
  pinMode(gpio, OUTPUT);
  
  TaskHandle_t th; //マルチタスクハンドル定義
  //マルチタスク実行
  xTaskCreatePinnedToCore(Task1, "Task1", 4096, NULL, 5, &th, 0);
}
//************* メインループ ****************************************
void loop() {

}
//************* マルチタスク ****************************************
void Task1(void *pvParameters){
  for(;;){
    oscillator(gpio, 1000);
    delay(1); //WDTが動作するように、必ずdelay(1)以上休止を入れること。
  }
}
//*********** 40kHz High レベル発信******************
void oscillator(const uint8_t pin, uint16_t time_osc){
  uint32_t last_time = millis();
  for(;;){
    long startCount;

    startCount = getCpuCcount();
    digitalWrite(pin, HIGH);
    while(getCpuCcount() - startCount < 2850) NOP();

    startCount = getCpuCcount();
    digitalWrite(pin, LOW);
    while (getCpuCcount() - startCount < 2850) NOP();

    if(millis() - last_time == time_osc) break;
  }
}
//*****************************************
static inline unsigned getCpuCcount(void){
  unsigned r;
  asm volatile ("rsr %0, ccount" : "=r"(r));
  return r;
}

30行目や34行目の数値を微調整することで、マイクロ秒レベルでパルス幅を調整できます。
これはArduino – ESP32 のバージョンや、ESP32 の個体差で変わるかも知れませんので、ご自分でいろいろと調整してみてください。

ESP32 のGPIO #17 の電圧をオシロスコープで見てみるとこんな感じでほぼピッタリで波長 25μs で 40kHz 出ています。

では、10kΩ負荷側の電圧波形を見てみましょう。
こんな感じです。

どうでしょうか?
かなり綺麗なサイン波だと思いませんか?
ピーク値の電位差は、1.24V とまずまずです。
GPIOの HIGH と LOW が切り替わる時点では、スパイクノイズが出ていますね。
これは、俗に言うスイッチングノイズというやつです。
オーディオマニアの方々の天敵ですね。
このスイッチングノイズは、トランジスタや FET、オペアンプ等で増幅させる時に大問題になりますが、今回はそれを使いませんので無視します。
(この対策は今後の課題とします。)
このスイッチングノイズは、ESP32 の GPIO のアップダウンとほぼピッタリ合っていますね。
ほぼ理想的と言っても良いのではないでしょうか。
ここまで綺麗な波形が出れば、申し分ありません。

因みに、オシロスコープのFFT解析で周波数スペクトルを見てみます。

かなり優秀な40kHzサイン波ですね。
自分で考えてパーツの定数を決めて、ここまで綺麗なサイン波ができると、結構感動しちゃいますね。

では、次ではこのサイン波を使って電波飛ばすことを考えてみたいと思います。

コメント

  1. てる より:

    mgo-tecさま始めまして。
    あなたさまのHP楽しく拝見させていただいております。
    此処に有る電波時計のサーバーを作ってみました、動作はするのですがシリアルモニタのTotal 時間が 60000 msの所が上 60008 ms 下が 59994 ms と一寸バラツキが大きいように思っております。
    後は、特に問題なく時間もピッタリと会っております、ここだけの問題ですが気にしなければ特に問題はないのですが製作上何か何かまずいところがあったのでしょうか、ちょっと気になっております。
    Amazonの1,250円の安いwaves ESP32を使ってせいでしょうか?。

    • mgo-tec mgo-tec より:

      てるさん

      はじめまして。
      記事をご覧いただき、そして実際に作って頂きありがとうございます。
      別の記事で同じようなコメント投稿があったのですが、こちらで回答させていただきます。

      かなり昔に作った記事ですので、うろ覚えの記憶をたどってお答えしますが、トータル60000msのバラつきは必ず出ますので、ハードの不良ではありません。
      そもそも、この記事のプログラムでは、パルスの精度が悪く、CPUクロックカウントも誤差があり、しかもESP32のシステム関連の割り込みなどがあって、60000msピッタリとはいきません。
      ですから、しばらく動かしていていて、時刻と大幅にズレて来た場合、現行時刻の00秒に合わせるために1分少々動作がストップするようにプログラミングしています。
      なお、この記事内でも案内していますが、LEDCライブラリを使って出力パルスの精度を大幅に上げることができます。
      それは、この記事を作ってしばらく後でわかったことです。
      以下の記事を参照してみてください。

      ●https://www.mgo-tec.com/blog-entry-ledc-pwm-arduino-esp32.html

      ●https://www.mgo-tec.com/blog-entry-m5stack-jjy-watch-yhaoo-news.html

  2. てる より:

    mgo-tecさま、ご返答ありがとうございました。
    コメントをする時に、コメント送信ボタンを押すと、パ!と全て消えてしまうので送れていないと勘違いて何度か同じコメントを送ってしまったらしいです、お詫び申し上げます。
    LEDCライブラリを使って出力パルスの精度を上げてみたいと思っております、ありがとうございました。

    • mgo-tec mgo-tec より:

      そうなんですよね~。
      WordPressのブログでは、コメント投稿送信はそうなってしまうんです。

      LEDCライブラリはお勧めですよ~。
      (^^)

  3. てる より:

    それと
    3番目のセラミックコンデンサの乗数が1μFのが0.01μになっておりました。
    先に連絡すればよかったのですが、遅れて申し訳ありません。

    • mgo-tec mgo-tec より:

      おー!
      この記事は3年半以上前の記事ですが、気付きませんでした。
      早速修正しました~。
      ご連絡、ありがとうございました。
      m(_ _)m

  4. てる より:

    お忙しい中大変申し訳ありませんが又質問させていただきたくお願いいたします。
    時計サーバーですが、良くしようと色々といじくりまわしておりましたが、
    「task_wdt: Task watchdog got triggered. The following tasks did not reset the watchdog in time:」と出て途切れ途切れになってしましました、サーバーの役目をしなく成ってしまいました、何が原因なのかわかりません、このような症状出たことありませんでしょうか。
    暇なときにでも、わかる範囲で宜しいのでお教えいただければと思っております。
    本当に暇な時で宜しいです。

    • mgo-tec mgo-tec より:

      私もウォッチドックタイマに関しては詳しくないのですが、当ブログで何回か扱ったので検索して参照してみてください。
      例えば、以下の記事を参照してみてください。
      https://www.mgo-tec.com/blog-entry-trouble-shooting-esp32-wroom.html/4
      ウォッチドッグタイマの自動リセット?が機能しなかったかもです。

      • てる より:

        ご回答ありがとうございます。

        >WiFiClientSecure ライブラリを使って

        とありましたので、プログラムには全く駄目な僕ですが、スケッチを下記のようにしてみました

        1://#include
        2:#include //安定化させる、てるが追加
        3:#include
        4:#include //Arduino time library ver1.5-

        今のところ非常に安定しています。

        もうこれ以上は、いじらない様にしたいと思います。

        ありがとうございました。

        http://monsirochou.blog.fc2.com/

  5. てる より:

    おはようございます。

    includenoの中身が記入されていないみたいですが、この様に送らておりましたか?。

    • mgo-tec mgo-tec より:

      実は、コメント投稿欄では半角の括弧<>以降は削除されてしまうんです。
      一般的なブログの場合、多くがそうだと思われます。
      私の場合、WordPressでブログを作成しているので、仕方のないところです。
      括弧だけ全角で投稿してみてください。
      例えばこんな感じです。
      #include<ESP32_lib.h>

タイトルとURLをコピーしました