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)