UMEHOSHI ITA TOP PAGE COMPUTER SHIEN LAB
esp32側をpythonでTCPサーバーにし、それを付けたUMEHOSHI ITA基板側のモータ制御ROM関数を呼び出してロボットを動かす構成の
サーバー側はこちらのページで紹介しています。
対してこのページは、上記ロボット側ESP32のサーバーにWifiを介して接続し、制御するPC側のクライアントソフトの紹介です。

こちらのページで紹介しているロボットの設定で、次のように起動できるようになっています。
まず、USBを介して電源を供給して、SW1とSW2を押し、SW1(赤)のリセットを離してからSW2(白)を遅れて離します。
これで、パターン[・・・・]の音を出した後、音が停止すればESP32のPythonyが正しく動作できたと予想できます。
(異なるパターンの音を出した場合や、音が長く出る場合は、起動にに失敗していると予想できます。
その場合は、再びSW1とSW2のスイッチ操作をしてください。)
esp32のboot.pyのプログラムが起動すれば、PC側からWifiで'ESP-AP'のアクセスポイントに接続できるはずです。
'ESP-AP'のアクセスポイントに接続できれば、"192.168.222.0"のネットワークに属したことになります。
この時、ESP32は192.168.222.1のIPアドレスになっています。
そして、ESP32のserver.pyが実行されて、それにより59154のポート番号のTCPサーバーが動作します。
このサーバーに接続して制御するためのpythonで作成したクライアントプログラムの使い方と、
このソースコード(client_ume_esp32.py)を下記で紹介しています。
D:\_D\_Hardware\esp32ロボット1>python client_ume_esp32.py IP (defualt:192.168.222.1)Address> Connect! 入力:M/F/'quit'/w/a/s/d/b/?>b Send:R009D020D00003B START:9D020D00:Response 入力:M/F/'quit'/w/a/s/d/b/?>w Send:R009D020200004D START:9D020200:Response 入力:M/F/'quit'/w/a/s/d/b/?>上記では、最初にIP Addressの入力で、単にEnterを押しています。
入力:M/F/'quit'/w/a/s/d/b/?>wwww aaaaaa ss Send:R009D020200004D Send:R009D020200004D START:9D020200:Response Send:R009D020200004D ・・・省略・・・上記は、前進を4回、左回転を6回、後進を2回実行させる入力です。
入力:M/F/'quit'/w/a/s/d/b/?>F ['boot.py', 'client_ume_esp32.py', 'flow_off.umh', 'log.txt', 'server.py', 'setap.py', 'uEsp32Init.umh', '_df.py'] 送信したいファイル名入力>uEsp32Init.umh Server:'uEsp32Init.umh' 28bytes received. R009D021000004E:Command START:9D021000:Response 入力:M/F/'quit'/w/a/s/d/b/?>F ['boot.py', 'client_ume_esp32.py', 'flow_off.umh', 'log.txt', 'server.py', 'setap.py', 'uEsp32Init.umh', '_df.py'] 送信したいファイル名入力>_df.py Server:'_df.py' 607bytes received. 入力:M/F/'quit'/w/a/s/d/b/?>Fの操作でESP32に送信できるファイルは任意で、ファイルをネットを介してESP32のルートコピーされます。
入力:M/F/'quit'/w/a/s/d/b/?>M UME HEX Command /exc /ls -l/cat /get /del /import >R009D020D00003B Send:R009D020D00003B START:9D020D00:Response 入力:M/F/'quit'/w/a/s/d/b/?>
入力:M/F/'quit'/w/a/s/d/b/?>M UME HEX Command /exc /ls -l/cat /get /del /import >exc uEsp32Init.umh Send:exc uEsp32Init.umh R009D021000004E:Command START:9D021000:Response 入力:M/F/'quit'/w/a/s/d/b/?>
入力:M/F/'quit'/w/a/s/d/b/?>M
UME HEX Command /exc /ls -l/cat /get /del /import >ls -l
Send:ls -l
ls_filelist:
16 Run.umh
607 _df.py
98 boot.py
17 log.txt
入力:M/F/'quit'/w/a/s/d/b/?> 11149 server.py
454 setap.py
?
入力:M/F/'quit'/w/a/s/d/b/?>
表示データの受信は、別スレッドで行われるため、『入力:M/F/'quit'/w/a/s/d/b/?>』が上記のように途中で表示されてしまう場合があります。
そのような場合、上記のように「?」Enterと入力して、プロンプトを出して操作するとよいでしょう。
入力:M/F/'quit'/w/a/s/d/b/?>M
UME HEX Command /exc /ls -l/cat /get /del /import >cat _df.py
Send:cat _df.py
cat_filepath:_df.py
import server
print = server.send
import os
stat = os.statvfs('/')
block_size = stat[0] # 1ブロックのサイズ(バイト単位)
total_blocks = stat[2] # f_blocks(総ブロック数)
free_blocks = stat[3] # 空きブロック数
print(f"block_size: {block_size} bytes, free_blocks: {free_blocks}")
free_space=block_size * free_blocks # 空き容量(バイト単位)
print(f"Free space: {free_space} bytes")
total_size = block_size * total_blocks # 総容量(バイト)
print(f"Total Storage: {total_size} bytes")
入力:M/F/'quit'/w/a/s/d/b/?>
上記の背景色が薄い部分がファイルの内容です。入力:M/F/'quit'/w/a/s/d/b/?>M UME HEX Command /exc /ls -l/cat /get /del /import >get log.txt Send:get log.txt log.txt:size=17 server:send_file:log.txt 入力:M/F/'quit'/w/a/s/d/b/?>
入力:M/F/'quit'/w/a/s/d/b/?>M UME HEX Command /exc /ls -l/cat /get /del /import >get log.txt Send:get log.txt log.txt:size=17 server:send_file:log.txt 入力:M/F/'quit'/w/a/s/d/b/?>
UME HEX Command /exc /ls -l/cat /get /del /import >import _df Send:import _df import_name:_df block_size: 4096 bytes, free_blocks: 460 Free space: 1884160 bytes Total Storage: 2097152 bytes 入力:M/F/'quit'/w/a/s/d/b/?>この実行結果は、上述のcat _df.pyで示したファイルの実行結果を表示しています。その先頭に次のコードがあり、重要な意味があります。
import server
print("R009D020D00003B") # ビープ関数起動のUME専用Hexコマンド文字列をUART1へ送ってビープを鳴らす。
server.send("Beep command was sent.") # TCPでこのクライアントに送り、表示させる
このファイルをFで転送して import test.py で実行すれば、音を鳴らして「Beep command was sent.」のメッセージを表示させることになります。
import os # client_ume_esp32.py
import socket
import sys
import time
import threading
path_datas="./"
# ----- 受信関連 ---------------------------------
def recieve_file(sock):
buf=b""
while True:
bin = sock.recv(1)
if len(bin) != 1: break
buf += bin
if buf[-2:] == b"\r\n":
s = buf[0:-2].decode('utf-8')
a=s.split(' ')
filename, filesize = a[0], int(a[1])
bin=b""
while len(bin) < filesize:
bin += sock.recv(filesize-len(bin))
with open( path_datas + filename, "wb") as f:
f.write(bin)
#tcp_send_message(sock,filename + ":size=" + str(len(bin)))
break
print(filename + ":size=" + str(filesize)) # debug ---------------
def recieve_message(sock): # TCP文字列メッセージ受信
buf=b""
while True:
bin = sock.recv(1)#1byte受信
if len(bin) != 1: break
buf += bin
if buf[-2:] == b"\r\n":# 1行の文字列受信終了?
s = buf[0:-2].decode('utf-8')#バイナリから
print(s)
break
def receiveData(sock): # 全てのTCP受信のスレッド用関数
#print( "start receiveData" )
while True:
bin = sock.recv(1)#1byte受信
if len(bin) != 1: break
if bin == b"f" : recieve_file(sock)
elif bin == b"M" : recieve_message(sock)
else: print(bin , end="")
#
print( "receiveData ended." )
# ----- 送信関連 ---------------------------------
def send_file(sock, filepath):
try:
filesize = os.path.getsize(filepath)
filename = os.path.basename(filepath)
s = "f{} {}".format(filename, filesize)
bin=(s+"\r\n").encode("utf-8")#binaryへ変換
# print(bin, end=" ")
sock.sendall(bin) #filename filesize 送信
with open(filepath, "rb") as f:
bin = f.read(filesize)
# print("送信data:" , bin )
sock.sendall(bin) # ファイル内容一括送信
print("送信byte:" , len(bin) )
except Exception as e:
print( "send_file error:" + str(e))
def send_file_Max(sock, filepath):
try:
filesize = os.path.getsize(filepath)
filename = os.path.basename(filepath)
s = "F{} {}".format(filename, filesize)
bin=(s+"\r\n").encode("utf-8")#binaryへ変換
# print(bin, end=" ")
sock.sendall(bin) #filename filesize 送信
with open(filepath, "rb") as f:
bin = f.read(filesize)
# print("送信data:" , bin )
sock.sendall(bin) # ファイル内容一括送信
#print("送信byte:" , len(bin) )
except Exception as e:
print( "send_file_Max error:" + str(e))
def send_message(sock,msg):
bin=('M'+msg+"\r\n").encode("utf-8")#binaryへ変換
sock.sendall(bin)#一括送信
print(f"Send:{msg}")
# ----- メイン ---------------------------------
portnumber=59154
ip="192.168.222.1"
s = input(f"IP (defualt:{ip})Address>")
if s != "": ip = s
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect((ip, portnumber))
#print("接続成功")
t_id = threading.Thread(target=receiveData, args=(sock,) )
t_id.start()
time.sleep(1.0)
loopFlag = True
cmd=""
while loopFlag:
s = input("入力:M/F/'quit'/w/a/s/d/b/?>")
if s != "": cmd = s
if cmd == 'M':
msg = input("UME HEX Command /exc /ls -l/cat /get /del /import >")
send_message(sock,msg)
cmd=' '
elif cmd == 'f' or cmd == 'F':
s='F'
print(os.listdir(path_datas))
filename = input("送信したいファイル名入力>")
if not os.path.isfile(path_datas + "/" + filename):
print( filename, "no exist")
continue
if cmd == 'f' : send_file(sock, path_datas + "/" + filename)
if cmd == 'F' : send_file_Max(sock, path_datas + "/" + filename)
cmd=' '
elif cmd == 'quit':
send_message(sock,'end_listen_loop')
loopFlag=False
else:
for c in cmd:
if c == 'b' :
send_message(sock,"R009D020D00003B") # Beep UME Hex コマンド
#send_file_Max(sock, path_datas + "/" + "uBeep.umh")
time.sleep(2.0)# 短い間隔のBeepの連続を禁止
elif c == 'w':
send_message(sock,"R009D020200004D") # Forward UME Hex コマンド
#send_file_Max(sock, path_datas + "/" + "uForward.umh")
elif c == 's':
send_message(sock,"R009D020300004C") # Back UME Hex コマンド
#send_file_Max(sock, path_datas + "/" + "uBack.umh")
elif c == 'a':
send_message(sock,"R009D020500004A") # Left UME Hex コマンド
#send_file_Max(sock, path_datas + "/" + "uLeft.umh")
elif c == 'd':
send_message(sock,"R009D020400004B") # Right UME Hex コマンド
#send_file_Max(sock, path_datas + "/" + "uRight.umh")
time.sleep(0.05)
#
time.sleep(1.0)
sock.close()
sys.exit(0)