ESP32-WROOM-32EでMicroPythonを使い開発(色々編)

〔ESP-WROOM-02〕 〔マイコンのトップに戻る〕
[準備編] [module編] [GPIO編] [通信編] [I2S編] [WiFi編] [BLE編1] [BLE編2] [BLE編3]  


[ファイル編][OLED編][メール編][並行処理編]と、
タイマーjsonファイル読書きデータベースFIFOバッファ]関連はESP8266を参照しましょう。

《upysh》

 マイクロパイシェルでファイル操作ができる様です。[ファイル編]参照ください。
"upysh"モジュールはESP8266では最初からmicropythonに構築されていますが、
ESP32は構築されていないです。
なので、ここの「Download files」をクリックし、"micropython-upysh-0.6.tar.gz "をダウンロードします
それから解凍後、[micropython-upysh-0.6]->"upysh.py"をESP32に書き込みましょう。
(ファイルの移動も出来るので、ファイル操作にはこれをお勧めします)

《OLED》

 OLED SSD1306を動作させる"ssd1306 "モジュールが、ESP8266では最初からmicropythonに
構築されていますが、ESP32は構築されていないです。
なので、ここの "ssd1306.py"をダウンロードして、ESP32に書き込みましょう。
尚、"framebuf"モジュールは構築されている様です。
後はESP8266の[OLED編]と同じ操作が出来ます。
ESP32-SSD1306実態配線図
 左は、参考配線図です。

 電源はUSB接続で、回路電源はボード出力3.3Vです。
 I2CはGPIO18(SDA)/GPIO18(SCL)を使っています。
 ピンのプルアップ抵抗はチップ内蔵を使います。
 あぁ、OLEDの[GND]と[VCC]逆に配線しています
 ご注意を。

《ライトスリープ》

ライトスリープモードが目覚めた場合は、その実行した次の行から再開始します。

タッチ入力でスリープから起こす

30カウント(30秒)でスリープモードに入り13番ピンに接続されたタッチパッドが押されたら目覚めます。
後は、ずっとカウント表示を続けるだけのサンプルです。

@ 14番ピンにタッチパッドを接続します。
A ESP32-WROOM-32EボードをUSBでPCに繋ぎます。
B "PyCharm"を起動させ、こちらのCを操作する必要が有ります。(起動時最初のみ設定)
C "main.py"を新規登録して下記スクリプトを"main.py"に貼り付けましょう。
  (登録済みなら上書き貼り付けでも行いましょう)
D ESP32-WROOM-32Eに書き込みます
  左側プロジェクトウインドウから"main.py"の文字を右クリックをして、[実行(U)'Flash main.py']を
  クリックします。
--------------------------------------------------------------------------------
import time
import machine
from machine import TouchPad, Pin
import esp32

t = TouchPad(Pin(14))       # 14番ピンにタッチパッドを接続
t.config(200)               # ピンが接触したと見なす敷居値を設定
esp32.wake_on_touch(True)   # タッチ入力で起こすを有効にする

x = 0
while True:
    print(x)
    if x == 30:
        # 30カウントしたらスリープ
        print('I sleep a little.')
        time.sleep_ms(100)  # 上の文字が表示されず寝てしまうので少し待たせる
        machine.lightsleep()
        print('I woke up now')
    x = x + 1
    time.sleep_ms(1000)
--------------------------------------------------------------------------------
外部ピン入力でスリープから起こす

使用できるピンは、RTC_GPIOxxのピンのみです、なのでぇ、GPIO1/GPIO3/GPIO5/GPIO16-19/
GPIO21-23のピンは使用不可です。
動作は上と同じです。

@ 14番ピンにスイッチを接続します。(プルアップはチップ内蔵を利用しています)
A ESP32-WROOM-32EボードをUSBでPCに繋ぎます。
B "PyCharm"を起動させ、こちらのCを操作する必要が有ります。(起動時最初のみ設定)
C "main.py"を新規登録して下記スクリプトを"main.py"に貼り付けましょう。
  (登録済みなら上書き貼り付けでも行いましょう)
D ESP32-WROOM-32Eに書き込みます
  左側プロジェクトウインドウから"main.py"の文字を右クリックをして、[実行(U)'Flash main.py']を
  クリックします。
--------------------------------------------------------------------------------
import time
import esp32
import machine

sw1 = machine.Pin(14, machine.Pin.IN, machine.Pin.PULL_UP)  # ピン14番(GPIO14)をスイッチ入力で割り付ける
# スイッチのLOWでスリープから起こす
esp32.wake_on_ext0(sw1, esp32.WAKEUP_ALL_LOW)

x = 0
while True:
    print(x)
    if x == 30:
        # 30カウントしたらスリープ
        print('I sleep a little.')
        time.sleep_ms(100)
        machine.lightsleep()
        print('I woke up now')
    x = x + 1
    time.sleep_ms(1000)
--------------------------------------------------------------------------------

《ディープスリープ》

ディープスリープモードから目覚めた場合は、ボードはリセットされ最初から起動します。
動作は30秒後にディープスリープに入り、10秒後に起きます、で再起動です。

@ 4番ピンにLEDを接続します。
A ESP32-WROOM-32EボードをUSBでPCに繋ぎます。
B "PyCharm"を起動させ、こちらのCを操作する必要が有ります。(起動時最初のみ設定)
C "main.py"を新規登録して下記スクリプトを"main.py"に貼り付けましょう。
  (登録済みなら上書き貼り付けでも行いましょう)
D ESP32-WROOM-32Eに書き込みます
  左側プロジェクトウインドウから"main.py"の文字を右クリックをして、[実行(U)'Flash main.py']を
  クリックします。
--------------------------------------------------------------------------------
import time
import machine

led = machine.Pin(4, machine.Pin.OUT)  # ピン4番(GPIO4)をLED出力で割り付ける
led.on()

# ディープスリープから起こされたかをチェック
if machine.reset_cause() == machine.DEEPSLEEP_RESET:
    print('woke from a deep sleep')

# 30秒してからスリープに入る
x = 0
while True:
    print(x)
    if x >= 30: break
    x = x + 1
    time.sleep(1)

# 10秒間のディープスリープに入る
print('I sleep deeply')
machine.deepsleep(10000)
print('pass')
--------------------------------------------------------------------------------
RTCモジュールを除くチップ全体の電源が遮断されます。
ディープスリープ中はLEDも消えていますね。

ライトスリープのスクリプトを"machine.lightsleep()"から"machine.deepsleep()"へ
書き換えても動作はします。
その際のピン指定は"RTC_GPIOx"にしないとダメでしょう。

《RTCとntptime》

REPLでhelp(RTC)操作  どうやら2000年1月1日 00:00:00 UTC のエポックを
 使っている様です。
 datetime()は、
 [年][月][日][曜日(土)][時][分][秒][マイクロ秒]
 曜日は、"0"が月曜から"6"の日曜までのかんじぃ
 因みにtime.localtime()は、
 [年][月][日][時][分][秒][曜日(土)][経過日数]です。

memory()は、
"RTC.memory('Hello')"とかメモリにb'Hello'と保存されます、
電源がON中はリセットされても残っている(リセットの内容によってはクリアされる場合が有る)
電源切れても残っていないとぉ意味ねぇ〜
クラス RTC -- リアルタイムクロックを見ましょう。

ntptime

REPLでhelp(ntptime)操作

NTPサーバーに接続して現在時刻を得る事が出来る様ですねチョットぉやってみます。
サーバーの接続先は"pool.ntp.org"です、接続先は変更できます。
NTPサーバーは1900年1月1日00:00:00(UTC)からの経過秒数で送ってきます、
ESP32は、2000年1月1日00:00:00ですね、だからESPに合わせる為の経過秒数がNTP_DELTAの値です。

@ ESP32-WROOM-32EボードをUSBでPCに繋ぎます。
A "PyCharm"を起動させ、こちらのCを操作する必要が有ります。(起動時最初のみ設定)
B "main.py"を新規登録して下記スクリプトを"main.py"に貼り付けましょう。
  (登録済みなら上書き貼り付けでも行いましょう)
C コード内に記述している"ESSID"/"Password"は自分ちのルータ等のアクセスポイントに変更します
D ESP32-WROOM-32Eに書き込みます
  左側プロジェクトウインドウから"main.py"の文字を右クリックをして、[実行(U)'Flash main.py']を
  クリックします。
--------------------------------------------------------------------------------
import time
from machine import RTC
import network
import ntptime

time.sleep(30)  # 30秒後に開始するこの間にREPLを起動しましょう。

ESSID = "BBUser"
Password = ""
# Wi-Fi 接続を設定する為にクライアントオブジェクトのインターフェースを作成する
sta_if = network.WLAN(network.STA_IF)
if not sta_if.isconnected():
    sta_if.active(True)
    sta_if.connect(ESSID, Password)  # ステーションインターフェイスを有効にする
    while not sta_if.isconnected():  # WiFiネットワークに接続する
        pass
print('\r\n[network config]\r\n', sta_if.ifconfig())

rtc = RTC()                     # RTCのオブジェクト作成
# (date(2000, 1, 1) - date(1900, 1, 1)).days * 24*60*60
ntptime.NTP_DELTA = 3155641200  # 更にタイムゾーンを引いた値
# "pool.ntp.org"サーバーに接続している
# 他のサーバーに接続したいなら(例:host = "ntp.nict.jp")とする
ntptime.settime()               # サーバからの日時を rtc に設定
print('Finished setting to RTC')
sta_if.active(False)            # Wi-Fi 接続を切る

while True:
    print(rtc.datetime())       # 日時を UTC で取得
    time.sleep((1))
--------------------------------------------------------------------------------
動作は30秒後に起動します、この間にREPLを動かしましょう。
こんなに簡単すぎて良いのだろうか?...あぁ、PICが遠くに感じられる。(´-`).。oO(..pic..C...)

※ RTCの既知の問題としてこんな問題があるそうです、ぜひ読みましょう。

≪おまけ≫

"ntptimeGET.zip"をダウンロードし解凍後、ESP32-WROOM-32Eの"/"か"lib/"の下に書き込んで
置きましょう。あ、"ESSID"/"Password"は書き換えますよ!
>>> import ntptimeGET
とREPLで操作するだけでRTCに現在時刻が設定されて便利ですよ、とっても! v( ̄∇ ̄)v

《CPU 周波数の変更》

REPLで周波数の変更操作  ESP32-WROOM-32Eは、クロック周波数が160Mhzと
 240MHz
で切り替えができるらしい、
 デフォルトは160MHzです。

 240MHzに切り替えても起動時は160MHzに戻ります

《RMT》

ESP32に固有のRMT(リモートコントロール)モジュールは、元々赤外線リモートコントロール信号を
送受信する為に設計された物らしいです。
ですがぁ、これでパルスが生成できます、チョットぉ行ってみます。

ヘルプ(esp32.RMT)
詳しい説明は、ここ又は、ここを参照しましょう。

esp32.RMT
 ・esp32.RMT(channel, *, pin=None, clock_div=8, carrier_freq=0, carrier_duty_percent=50)
  このクラスは、8つのRMTチャネルの1つへのアクセスを提供します。
  RMTモジュールへの入力クロック周波数は80MHz固定です、将来的には設定できるかもしれない。
  クロックの分解能は、"1 / (source_freq / clock_div)"で計算します。

  channel  = 0-7のチャンネルを指定します、この引数は必須です。
  pin    = パルスを出力するピンを指定します、この引数は必須です。
         入力専用以外のピンは使えそうです。
  clock_div = クロック周波数の分周器の設定(8ビット 0-255)です。
  carrier_freq     = キャリア周波数の設定(38000等)です。
  carrier_duty_percent = キャリア周波数のデュティ比を%で指定します。
  例)
    from esp32 import RMT
    pls = RMT(0, pin=Pin(18), clock_div=8, carrier_freq=38000)
 ・RMT.write_pulses(pulses, start)
  パルスの送信を開始します。
  出力は"pulses"でセットするパルスパターンのリスト又はタプルを指定します。
  例えば""010111"のパターンで出力するなら(100,30,30,30,50,50)と各パルスの長さを指定します。
  各パルスの長さは100なら"(1/(source_freq /clock_div)) = 100/(80/8)"で計算します。
  又、パルスの長さ指定は、15ビット(0-32,768)の数値まで設定可能です。
  パルスの始まりが"start=0"ならビット0で始まります。

 ・RMT.loop(enable_loop)
  パターンのループを設定します。 enable_loopは bool型で、 True/Falseです。
  ループ中のパルス出力中に"False"で呼出された場合、パターン転送が完了する前に途中で中断します

 ・RMT.deinit()
  パルスの出力を停止します。

100KHzのパルスを作ってみる
--------------------------------------------------------------------------------
import time
import esp32
from machine import Pin

# 基本クロックは80MHz 分周器は8ビット(0-255)
pulse = esp32.RMT(0, pin=Pin(25), clock_div=8)
# パターンをループさせる
pulse.loop(True)

# 100KHzのパルスで出力
# 100KHz=10us(1周期) の半分 5us は(80MHz/8div)*5us = 50(49は調整しています)
# パルスはLOWの0から開始で、パターンは"01"だから分解能は"50,50"で出力
pulse.write_pulses((49, 50), start=0)

while True:
    time.sleep(1)
--------------------------------------------------------------------------------

分周は[clock_div=8]
出力した波形図1(clock_div=8)
ワンダフォな波形ですがぁ"(50,50)"ではチョットぉあれだった物でぇ"(49,50)"にした図です。
1周期が(50,50)でデュティ比50%なら、(25,75)とすれば25%って事ですね。

分周は[clock_div=1]
出力した波形図2(clock_div=1)
(80MHz/1div)*5us = 400
(399,400)にした図です、んん、まぁいっかぁ。

出力した波形図3(1MHz)
最高で1MHz辺りまでは行けそうですね。





[BLE編3へ] [ページ上へ]


【きむ茶工房ガレージハウス】
Copyright (C) 2006-2021 Shigehiro Kimura All Rights Reserved.