先日Twitterのタイムラインに@H0meMadeGarbageさんのムシキングのおもちゃ改造の動画が流れてきました↓
このリアルな動きに一目ぼれしてしまいまして、自分も作ってみたいとなりまして、他人の創作を丸パクリするのはイケないと思いながらも我慢ならず、とりあえず同じものをヤフオクで落としました。
このtweetを上げたところ、@H0meMadeGarbage さんよりコメントを頂きまして、ありがたいことに真似してもいいよとのお言葉を頂きました。心の広いお方だ。。
ということで、今回はムシキングのおもちゃを改造し、無線で操作してみた事をまとめようかと思います。
※ブログにあげるのはどうかと思いましたが、とにかくすばらしい作品ですので、勝手ながらあげさせて頂くことにしました。作り方は一応自分で考えましたが、 @H0meMadeGarbage の作品であることには変わり有りません。問題があれば当記事は即刻削除いたします。m(__)m
ムシキングラジコンバトル
もう10年程前に販売されていた?ものっぽくて、現在は販売されていません。
写真のように、リモコンと有線で繋がっているので、これを無線化に改造します。
ちなみに、現在では新しいバージョンのものが販売されていて、それは無線化されています。
ならばそれを買えばいいんじゃ?となりますが、違うのです。動きが全然違うんです。ほんとに過去バージョンの動きは、本物かと見間違えるほどリアルなのです。
動きについて
動作については4種類。
1、前進
2、右旋回
3、ハサミの掴み、離し
4、あごの上下
となります。
これ、改造次第では後退と左旋回も追加できるかと思いましたが、分解してみたところモーターが2つしか入っておらず、次項のような機構になっていたので、あきらめました。
モーターの動作
2つのモーターは、下記のような仕組みになっていました。
モーター①:正転で前進、後転で右旋回
モーター②:正転でハサミ、後転で顎(逆だったかも。)
後退と左旋回はあきらめて、今の動きを無線化するだけにします。
ムシキングの無線化
ハードウェア
マイコンボードにはESP32を使用し、WIFIのUDP通信で操作出来るようにしました。コントローラーにはM5Stack CORE2を使用。
ハードウェアの構成は下記の通り。
M5Stack CORE2 ⇒ UDP ⇒ ESP32 ⇒ DCモータードライバ ⇒ DCモーター
配線後はこんな感じになりました。バッテリーはリポ1つを共通電源としています。
プログラム(micropython)
M5Stack CORE2
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 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 |
from m5stack_ui import * from socket import socket, AF_INET, SOCK_DGRAM import time import network from m5stack import * #from m5stack import lcd from machine import Pin from uiflow import * screen = M5Screen() screen.clean_screen() screen.set_screen_bg_color(0xFFFFFF) dstip = "ESP32のIP" dstport = ポート番号 wlan = network.WLAN(network.STA_IF) wlan.active(True) if not wlan.isconnected(): print('connecting to network...') wlan.connect('SSID', 'PASS') while not wlan.isconnected(): pass print('network config:', wlan.ifconfig()) print('network config:', wlan.ifconfig()) s = socket(AF_INET, SOCK_DGRAM) #s.bind((dstip, dstport)) touch_button0 = M5Btn(text='Button', x=60, y=36, w=70, h=70, bg_c=0xFFFFFF, text_c=0x000000, font=FONT_MONT_14, parent=None) touch_button1 = M5Btn(text='Button', x=60, y=137, w=70, h=70, bg_c=0xFFFFFF, text_c=0x000000, font=FONT_MONT_14, parent=None) touch_button2 = M5Btn(text='Button', x=177, y=36, w=70, h=70, bg_c=0xFFFFFF, text_c=0x000000, font=FONT_MONT_14, parent=None) touch_button3 = M5Btn(text='Button', x=177, y=137, w=70, h=70, bg_c=0xFFFFFF, text_c=0x000000, font=FONT_MONT_14, parent=None) def touch_button0_pressed(): global data data = "for" def touch_button3_pressed(): global data data = "up" def touch_button1_pressed(): global data data = "hasami" def touch_button2_pressed(): global data data = "side" #touch_button0.pressed(touch_button0_pressed) # ボタン"A" が「離された」時の処理 def touch_button0_released(): global data data = "S" #data = touch_button0.released(touch_button0_released) data = "nane" stamp = 0 while(True): #global data touch_button0.pressed(touch_button0_pressed) touch_button1.pressed(touch_button1_pressed) touch_button2.pressed(touch_button2_pressed) touch_button3.pressed(touch_button3_pressed) #data = "A" touch_button0.released(touch_button0_released) touch_button1.released(touch_button0_released) touch_button2.released(touch_button0_released) touch_button3.released(touch_button0_released) s.sendto(data, (dstip, dstport)) print(data) #print(Slider2.get_value()) time.sleep(0.1) |
ESP32
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 |
from socket import socket, AF_INET, SOCK_DGRAM import time import network from machine import Pin HOST = "ESP32のIP" PORT = ポート番号 wlan = network.WLAN(network.STA_IF) wlan.active(True) if not wlan.isconnected(): print('connecting to network...') wlan.connect('SSID', 'PASS') while not wlan.isconnected(): pass print('network config:', wlan.ifconfig()) s = socket(AF_INET, SOCK_DGRAM) s.bind((HOST, PORT)) p1 = Pin(0, Pin.OUT) p2 = Pin(2, Pin.OUT) p3 = Pin(4, Pin.OUT) p4 = Pin(16, Pin.OUT) while(True): msg, address = s.recvfrom(8192) #print(f"message: {msg}\nfrom: {address}") msg = msg.decode() print(msg) if msg == "for": p1.value(1) p2.value(0) elif msg == "side": p1.value(0) p2.value(1) elif msg == "hasami": p3.value(1) p4.value(0) elif msg == "up": p3.value(0) p4.value(1) else: p1.value(0) p2.value(0) p3.value(0) p4.value(0) time.sleep(0.1) s.close() |
完成
何度見ても動きがいいんですよねえ。(^▽^)/