先日M5Stack社から新製品のATOM-S3が発売されました。
24×24の超小型サイズでESP32-S3ベースのマイコンボードを搭載していて、なんと液晶も付いています。
今回、これを使って超小型の2足歩行ロボットを作成しましたので、ここでまとめておこうかと思います。
M5Stackを使ったスタックチャンのさらに小型版、「アトムちゃん」と命名します。(超安易。。)
目次
初めに
コンセプト
2足歩行させようと思えば、最低でもサーボモーターが4つ必要(前進後退、左右旋回する場合)ですので、ATOM-S3の内部には2つ入れなければなりません。
さらにバッテリーも入れる必要があります。
サーボモータは基板に直結させるとしても、これをATOM-S3の24×24の内部に収めるにはかなり無理があります。
一回り大きい筐体を用意すればなんとか楽する事ができますが、それは今回NGとしました。
あくまでも24×24をベースに、奥行きだけを伸ばして、ATOM-S3の小ささをそのまま維持することをコンセプトとしました。
使用部品の小型化
部品調達
・超小型サーボモータ(Pingzheng1.7マイクロデジタルサーボ)
・超小型Lipoバッテリ(19×21,130mAh 1C )
とにかく24×24に収まる大きさの部品を調達しました。
基板加工
使用部品を小型化で、縦、横の24×24には収まりましたが、これだけでは奥行がどうしても長くなりすぎてしまったので、その長さを縮める為に基板を加工しました。
1,PINソケットの取り外し
2,GROVEコネクタの取り外し
3,無線アンテナの取り外し
1,2はまあ使わないので良しと出来ますが、3はかなりの暴挙に出ております。汗
受信感度など無線の機能が低下するでしょうが、とりあえずアンテナを外した状態でもUDPのリモコン操作が可能でしたので、外すことにしました。
これで奥行は28mm程度に抑えることができました。
動作検証
今回使用するバッテリの容量が130mAhの1Cなので、これ1つでサーボモータ4つと基板の電源をまかなえるのか、検証を行いました。
ギリギリだと思いますが、なんとか動作してくれました。サーボモータも4つを基板直結でも問題無さそうです。
リアカバー作成
スケッチ、プリントアウト
専用のリアカバーをスケッチ、3Dプリンターで印刷しました。
部品収納
なんとか部品が納まりました。
つづいて地獄の配線作業。。
足と配線
足
なんせ小さいから難しい(-_-;)
試行錯誤でなんとかそれっぽく出来ました。
配線
配線がカオスですが、なんとか筐体に収まりました。
しかしこの後の動作テストでサーボモータが3回ほど故障しました。。
原因は「サーボホーンのネジの締め付け」がきつかったようです。強く締め付けた意識は無かったのですが、どうもこのミニサーボは規定のトルクを一瞬でも超えてしまうとお逝きになるっぽいです。。
さて、いよいよ完成間近です。
プログラム
ATOM-S3側(micropyton)
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 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 |
from socket import socket, AF_INET, SOCK_DGRAM import time import network from machine import PWM, Pin import _thread HOST = "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()) print('network config:', wlan.ifconfig()) s = socket(AF_INET, SOCK_DGRAM) s.bind((HOST, PORT)) frequency = 50 servo1 = PWM(Pin(5), frequency)#freq = 50)#p2.duty_u16(0) servo2 = PWM(Pin(6), frequency) servo3 = PWM(Pin(7), frequency) servo4 = PWM(Pin(8), frequency) servo1.duty(45) servo2.duty(62) servo3.duty(45) servo4.duty(65) a = 45 b = 62 c = 45 d = 65 msg = "nane" def recieve(): while(True): global msg msg = s.recv(64) msg = msg.decode() print(msg) time.sleep(0.01) _thread.start_new_thread(recieve, ()) while True: if msg == 'F': while(b <= 77): servo2.duty(b) b = b + 1 if d <= 80: servo4.duty(d) d = d + 1 time.sleep(0.01) while(c <= 60): servo3.duty(c) c = c + 1 time.sleep(0.01) while(b >= 62): servo2.duty(b) b = b - 1 if d >= 65: servo4.duty(d) d = d - 1 time.sleep(0.01) while(c >= 45): servo3.duty(c) c = c - 1 time.sleep(0.01) while(d >= 50): servo4.duty(d) d = d - 1 time.sleep(0.01) if b >= 50: servo2.duty(b) b = b - 1 time.sleep(0.01) while(a >= 30): servo1.duty(a) a = a - 1 time.sleep(0.01) while(d <= 65): servo4.duty(d) d = d + 1 if b <= 62: servo2.duty(b) b = b + 1 time.sleep(0.01) while(a <= 45): servo1.duty(a) a = a + 1 time.sleep(0.01) elif msg == "B": while(b <= 77): servo2.duty(b) b = b + 1 if d <= 80: servo4.duty(d) d = d + 1 time.sleep(0.01) while(c >= 30): servo3.duty(c) c = c - 1 time.sleep(0.01) while(b >= 62): servo2.duty(b) b = b - 1 if d >= 65: servo4.duty(d) d = d - 1 time.sleep(0.01) while(c <= 45): servo3.duty(c) c = c + 1 time.sleep(0.01) while(d >= 50): servo4.duty(d) d = d - 1 time.sleep(0.01) if b >= 50: servo2.duty(b) b = b - 1 time.sleep(0.01) while(a <= 60): servo1.duty(a) a = a + 1 time.sleep(0.01) while(d <= 65): servo4.duty(d) d = d + 1 if b <= 62: servo2.duty(b) b = b + 1 time.sleep(0.01) while(a >= 45): servo1.duty(a) a = a - 1 time.sleep(0.01) elif msg == "R": while(b <= 80): servo2.duty(b) b = b + 1 if d <= 77: servo4.duty(d) d = d + 1 time.sleep(0.01) while(c >= 30): servo3.duty(c) c = c - 1 time.sleep(0.01) while(b >= 62): servo2.duty(b) b = b - 1 if d >= 65: servo4.duty(d) d = d - 1 time.sleep(0.01) while(c <= 45): servo3.duty(c) c = c + 1 time.sleep(0.01) elif msg == "L": while(d >= 50): servo4.duty(d) d = d - 1 time.sleep(0.01) if b >= 50: servo2.duty(b) b = b - 1 time.sleep(0.01) while(a <= 60 ): servo1.duty(a) a = a + 1 time.sleep(0.01) while(d <= 65): servo4.duty(d) d = d + 1 if b <= 62: servo2.duty(b) b = b + 1 time.sleep(0.01) while(a >= 45): servo1.duty(a) a = a - 1 time.sleep(0.01) time.sleep(0.01) |
リモコンのM5Stack CORE2から操作信号をUDPで受信しています。
CORE2側のプログラムは割愛します。
完成(仮)
いやあここまで苦労して結果これかい(;^ω^)という感じもしますが、一応歩いています!(という事にしておいてください。。)
後は微調整すればまだましにはなるかと思います。
あと表情をつけたいですね。今のところUiFlowではまだ出来そうにないので、実装されるのを期待しています。