前回、M5Stack core2のスライダーからESP32のLEDをPWM制御してみました。↓
今回はLEDをDCモーターに変えて、一本のスライダーで正転、後転する仕組みをPWMを使って作成します。
前回作成したスライダーの左側、縦の方を使います。中央が停止、上にスライドで正転、下にスライドで後転するようにします。
※右側のスライダーはステアリングに使用するので、とりあえず今回はなにもせず保留。
目次
初めに
概要
前回同様、M5StackをクライアントとしてUDPでESP32に接続させます。スライダーの値をESP32が受け取って、値に応じた動作をさせます。
M5Stack core2(クライアント側、コントローラー) ⇒ UDP ⇒ ESP32(サーバー側)、DCモーター駆動
構成
・M5Stack core2
・ESP32
・DCモーター、DCモータードライバ
・ブレッドボード、ジャンパーピン
余談
ESP32でDCモーターを駆動するにあたり、モーター駆動時のみピンポイントで下記エラーが頻繁に発生いたしました。
”Guru Meditation Error: Core 1 panic’ed (LoadProhibited). Exception was unhandled.”
メモリ不足とか電力不足等で発生するみたいですが、どちらも思い当たる節がなく。。
丸1日悩みましたが、結果、ESP32のファームウェアを違うものにインストールし直した所改善しました。↓
変更前 esp32-20220117-v1.18 .bin
変更後 esp32-ota-20220320-unstable-v1.18-221-g94a9b5066.bin
ESP-WROOM-32D DevKitC-32Dという基板を使用していますが、ESP32のファームウェアが無数にあり、はっきりいってどれが正解か分かりません。。↑のも正解かはわかりません。。
とりあえず上記エラーが発生した場合は、一度ファームウェアの変更を考えてみるのもいいと思います。
プログラム
クライアント側、M5Stack core2(micropython)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 |
from m5stack_ui import * from socket import socket, AF_INET, SOCK_DGRAM import time import network from m5stack import * from machine import Pin from uiflow import * screen = M5Screen() screen.clean_screen() screen.set_screen_bg_color(0xFFFFFF) dstip = "サーバーIP" dstport = ポート番号 wlan = network.WLAN(network.STA_IF) wlan.active(True) if not wlan.isconnected(): print('connecting to network...') wlan.connect('Buffalo-G-29CE', 'AKANE0918') while not wlan.isconnected(): pass print('network config:', wlan.ifconfig()) s = socket(AF_INET, SOCK_DGRAM) Slider = M5Slider(50,50,12,150,0,100,0x888888,0x000fff) Slider2 = M5Slider(150,111,150,12,0,100,0x888888,0x000fff) Slider.set_bg_color(0x888888) Slider2.set_bg_color(0x888888) Slider.set_color(0x000fff) Slider2.set_color(0x000fff) Slider.set_range(-1023,1023) Slider2.set_range(0,100) Slider.set_value(0) Slider2.set_value(50) while(True): #global data data = str(Slider.get_value()) data = "A" + data print(data) s.sendto(data, (dstip, dstport)) #print(Slider2.get_value()) data2 = str(Slider2.get_value()) data2 = "B" + data2 print(data2) s.sendto(data2, (dstip, dstport)) time.sleep(0.01) |
先頭のWIFI接続は割愛します。
スライダーのレンジに-1023~1023を指定していますが、これはPWMのデューティサイクルの値になります。
デューティサイクルは 0 (全オフ)と 1023 (全オン)の間であり、512 は 50% のデューティとなります。この最小値/最大値を超える値は切り捨てられます。
マイナスを付けているのは、ESP32側で正転か後転かの判別を付けるためです。
サーバー側、M5Stack core2(micropython)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 |
from socket import socket, AF_INET, SOCK_DGRAM import time import network from machine import PWM, Pin HOST = "IP" PORT = ポート番号 wlan = network.WLAN(network.STA_IF) wlan.active(True) if not wlan.isconnected(): print('connecting to network...') wlan.connect('Buffalo-G-29CE', 'AKANE0918') while not wlan.isconnected(): pass print('network config:', wlan.ifconfig()) s = socket(AF_INET, SOCK_DGRAM) s.bind((HOST, PORT)) print("bind") frequency = 5000 p1 = PWM(Pin(32), frequency) p2 = PWM(Pin(33), frequency) while(True): msg = s.recv(64) msg = msg.decode() if "A" in msg: msgA = msg[1:] msgA = int(msgA) if msgA > 100: p2.duty(0) p1.duty(msgA) print(msgA) elif msgA < -100: msgA = str(msgA) msgA = msgA[1:] msgA = int(msgA) p1.duty(0) p2.duty(msgA) print(msgA) else: p1.duty(0) p2.duty(0) print(msgA) time.sleep(0.01) s.close() |
PWMの周波数は5Khzとし、2つの出力ピンでPWMのインスタンスを作成します。
ループ処理ではスライダーの値を随時受け取り、デューティー比に応じてP1,P2の出力電圧が変動します。
左右のスライダーを識別するためにA,Bの文字列を数値に先頭に付けていますので、if文の初めで一度先頭文字を削除していますが、マイナス符号(後転)の場合はもう一度先頭文字を削除する必要があります。
プラス=正転、マイナス=後転、数値100~-100は停止、としています。
完成
こんな感じで制御できます。↓
次回は右側のスライダーでサーボモーターを制御させてみたいと思います。