RaspberryPi ZERO2Wで多関節2足歩行ロボット
過去にいくつか2足歩行ロボットを作ってきたのですが、見た目にあまりこだわってこなかったので、自分なりに見た目がイケてるやつを作ってみようかとなりました。
しかし見た目だけ変えるのは少し物足りないので、間接も増やして頭、肘、腰、なども動かせる「多関節2足歩行ロボット」にする事にしました。(これで多関節なのかはわかんないけど。。)
となるとサーボモーターも多く使う事になるので、そこそこの大きさになりました。
ロボットは先日完成(仮)しましたので、今回はこの「多関節2足歩行ロボット」について、概要や作成過程等をまとめようと思います。
これからロボットを作る方の参考になれば幸いです。
多関節2足歩行ロボット の概要
外観
とりあえず手書きで外観をスケッチしてみました。
これを元に、サーボモーターやマイコン等の大きさを加味したサイズにしていきます。
ハードウェアの構成
外観のサイズが大方わかりましたので、内部に入れるマイコン等を決めます。
今回はカメラを付けて、ブラウザやbluetooth,bleで無線操作したいと思ったのと、ゆくゆくはROSなんかも入れてみたいなと思ったのでRaspberryPi ZERO2Wを使う事にしました。
構成は下記の通りです。
RaspberryPi ZERO2W ⇒ i2c ⇒ PCA9685 ⇒ サーボ11個
カメラはラズパイカメラを使いました。
バッテリーはLipoで2000mAh,放電Cレート2の物を使いました。瞬間最大で4Aまで出せるのでこれ1個でマイコンとサーボドライバの電源をまかないます。
制御について
1,WEBサーバーにhtmlで操作画面を作りブラウザから操作可能にする。(カメラ画像あり)
2,bleでアナログコントローラーから操作可能にする。(カメラ画像なし)
各部位ごとの操作も可能にする。
なお、1,2,共に電源投入後に自動でプログラムが立ち上がるようにする。
動作
前進、後退(腰の捻りを追加)
左右旋回
目の発光(LED)PWM制御も入れる
ポーズ(中山きんに君のパワー)
ブラウザ時はカメラ映像あり
アナログコントローラー時は各部位を単体で動かせる
物理ボタンで電源ON,OFF
電源ON時、目を発光、その後ポーズ(パワー)
WEBサーバー、およびアナログコントローラーの接続プログラムは電源ON後に自動で起動
プログラム
ブラウザはHTML,css,js,pythonCGI
アナログコントローラーはpython
外観の作成
CADスケッチ
fusion360でボディのスケッチを作成。
3Dプリント、部品格納
3Dプリンターで印刷、内部に部品を格納。
配線と歩行テスト
配線
歩行テスト
なんとか動いてくれました。
全体の姿はこんな感じになりました。↓
プログラム
ブラウザ(html/css,js,python)
※WEBサーバーはApacheを使用しています。カメラはmjpgstreamerを使用しています。またCGIを使う場合は各種設定変更が必要です。その辺の説明は長くなりますのでここでは割愛します。
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8">
<title>テスト</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="style.css">
</head>
<body>
<div class="cam">
<img src="http://ローカルIP:8080/?action=stream">
</div>
<main>
<ul>
<div class="tp">
<div class="b">
<li id="topl" class="ledoff">left</li>
</div>
<div class="a">
<li id="tops" class="ledoff">center</li>
</div>
<div class="c">
<li id="topr" class="ledoff">right</li>
</div>
</div>
<div class="bc">
<div class="b">
<li id="leftforward" class="ledoff">1</li>
</div>
<div class="a">
<li id="forward" class="ledoff">↑</li>
</div>
<div class="c">
<li id="rightforward" class="ledoff">2</li>
</div>
</div>
<div class="bc">
<div class="b">
<li id="left" class="ledoff">←</li>
</div>
<div class="a">
<div class="z">
<div class="y">
<li id="l" class="ledoff">ON</li>
</div>
<div class="x">
<li id="r" class="ledoff">OFF</li>
</div>
</div>
</div>
<div class="c">
<li id="right" class="ledoff">→</li>
</div>
</div>
<div class="bc">
<div class="b">
<li id="leftbackward" class="ledoff">3</li>
</div>
<div class="a">
<li id="backward" class="ledoff">↓</li>
</div>
<div class="c">
<li id="rightbackward" class="ledoff">4</li>
</div>
</div>
</ul>
</main>
<script src="jquery-3.6.1.min.js"></script>
<script src="main.js"></script>
</body>
</html>
* {
margin: 0px;
padding: 0px;
}
body {
max-width: 600px;
font-size: 18px;
width: 100%;
-webkit-touch-callout: none;
-webkit-user-select: none;
}
img {
width: 100%;
}
main {
height: 50vh;
background: skyblue;
}
ul {
display: block;
height: 40vh;
list-style: none;
padding-top: 10px;
}
.tp {
display: flex;
}
.bc {
display: flex;
}
.z {
display: flex;
}
.a ,.bc, .d .y, .x, .tp {
height: 12vh;
}
li {
width: 90px;
height: 70% ;
margin-left: 5px;
background: yellow;
line-height: 60px;
}
#l, #r {
width: 45px;
margin-left: 5px;
}
.b {
margin-left: auto;
}
.c {
margin-right: auto;
}
ul li {
text-align: center;
}
.a li, .b li, .c li, .d li {
border: solid 1px;
}
.ledon {
background: #f88888;
}
.n li {
background: skyblue;
}
a:active { color: #ff2020;
}
$(function(){
let motor = "STOP";
function change_motor2() {
motor = 'STOP';
}
// 関数:モーターを動かすマクロ呼び出し
function change_motor(typee) {
motor = typee;
if(typee == "FOWARD") { // 前進
//w().callMacro('FW');
console.log(typee);
$.ajax({
url: 'cgi-bin/recieve.py',
type: 'post',
data: {name:
'hhhh'
}
}).done(function(data){
change_motor2();
console.log(data);
}).fail(function(){
console.log('failed');
});
} else if(typee == "BACKWARD") {
//w().callMacro('BK');
console.log(typee);
$.ajax({
url: 'cgi-bin/recieve.py',
type: 'post',
data: {name:
'iiii'
}
}).done(function(data){
change_motor2();
console.log(data);
}).fail(function(){
console.log('failed');
});
} else if(typee == "RIGHT") {
//w().callMacro('RT');
console.log(typee);
$.ajax({
url: 'cgi-bin/recieve.py',
type: 'post',
data: {name:
'jjjj'
}
}).done(function(data){
change_motor2();
console.log(data);
}).fail(function(){
console.log('failed');
});
} else if(typee == "LEFT") {
//w().callMacro('LT');
console.log(typee);
$.ajax({
url: 'cgi-bin/recieve.py',
type: 'post',
data: {name:
'kkkk'
}
}).done(function(data){
change_motor2();
console.log(data);
}).fail(function(){
console.log('failed');
});
} else if(typee == "STOP") {
//w().callMacro('ST');
console.log(typee);
$.ajax({
url: 'cgi-bin/recieve.py',
type: 'post',
data: {name:
'ssss'
}
});
} else if(typee == "topl") {
//w().callMacro('LT');
console.log(typee);
$.ajax({
url: 'cgi-bin/recieve.py',
type: 'post',
data: {name:
'topl'
}
}).done(function(data){
change_motor2();
console.log(data);
}).fail(function(){
console.log('failed');
});
} else if(typee == "tops") {
//w().callMacro('LT');
console.log(typee);
$.ajax({
url: 'cgi-bin/recieve.py',
type: 'post',
data: {name:
'tops'
}
}).done(function(data){
change_motor2();
console.log(data);
}).fail(function(){
console.log('failed');
});
} else if(typee == "topr") {
//w().callMacro('LT');
console.log(typee);
$.ajax({
url: 'cgi-bin/recieve.py',
type: 'post',
data: {name:
'topr'
}
}).done(function(data){
change_motor2();
console.log(data);
}).fail(function(){
console.log('failed');
});
} else if(typee == "LEFTFORWARD") {
//w().callMacro('ST');
console.log(typee);
$.ajax({
url: 'cgi-bin/recieve.py',
type: 'post',
data: {name:
'qqqq'
}
}).done(function(data){
change_motor2();
console.log(data);
}).fail(function(){
console.log('failed');
});
} else if(typee == "RIGHTFORWARD") {
//w().callMacro('ST');
console.log(typee);
$.ajax({
url: 'cgi-bin/recieve.py',
type: 'post',
data: {name:
'mmmm'
}
}).done(function(data){
change_motor2();
console.log(data);
}).fail(function(){
console.log('failed');
});
} else if(typee == "L") {
//w().callMacro('ST');
console.log(typee);
$.ajax({
url: 'cgi-bin/recieve.py',
type: 'post',
data: {name:
'gggg'
}
});
} else if(typee == "R") {
//w().callMacro('ST');
console.log(typee);
$.ajax({
url: 'cgi-bin/recieve.py',
type: 'post',
data: {name:
'dddd'
}
});
} else if(typee == "LEFTBACKWARD") {
//w().callMacro('ST');
console.log(typee);
$.ajax({
url: 'cgi-bin/recieve.py',
type: 'post',
data: {name:
'oooo'
}
}).done(function(data){
change_motor2();
console.log(data);
}).fail(function(){
console.log('failed');
});
} else if(typee == "RIGHTBACKWARD") {
//w().callMacro('ST');
console.log(typee);
$.ajax({
url: 'cgi-bin/recieve.py',
type: 'post',
data: {name:
'zzzz'
}
}).done(function(data){
change_motor2();
console.log(data);
}).fail(function(){
console.log('failed');
});
}
}
// 「前進」ボタンが押されたときのイベント処理
$('#forward').bind('touchstart', function() {
// 押されたとき
if(motor == 'STOP') {
$(this).addClass('ledon');
change_motor('FOWARD');
ff1 = setInterval(function(){
change_motor('FOWARD');
}, 2700);
}
}).bind('touchend', function() {
// 離したとき
$(this).removeClass('ledon');
//change_motor('STOP');
clearInterval(ff1);
});
// 「後退」ボタンが押されたときのイベント処理
$('#backward').bind('touchstart', function() {
if(motor == "STOP") {
$(this).addClass('ledon');
change_motor('BACKWARD');
ff1 = setInterval(function(){
change_motor('BACKWARD');
}, 2700);
}
}).bind('touchend', function() {
$(this).removeClass('ledon');
//change_motor('STOP');
clearInterval(ff1);
});
// 「右」ボタンが押されたときのイベント処理
$('#right').bind('touchstart', function() {
if(motor == "STOP") {
$(this).addClass('ledon');
change_motor('RIGHT');
ff1 = setInterval(function(){
change_motor('RIGHT');
}, 1300);
}
}).bind('touchend', function() {
$(this).removeClass('ledon');
//change_motor('STOP');
clearInterval(ff1);
});
// 「左」ボタンが押されたときのイベント処理
$('#left').bind('touchstart', function() {
if(motor == "STOP") {
$(this).addClass('ledon');
change_motor('LEFT');
ff1 = setInterval(function(){
change_motor('LEFT');
}, 1300);
}
}).bind('touchend', function() {
$(this).removeClass('ledon');
//change_motor('STOP');
clearInterval(ff1);
});
$('#leftforward').bind('touchstart', function() {
// 押されたとき
if(motor == 'STOP') {
$(this).addClass('ledon');
change_motor('LEFTFORWARD');
//ff1 = setInterval(function(){
//change_motor('LEFTFORWARD');
//}, 4500);
}
}).bind('touchend', function() {
// 離したとき
$(this).removeClass('ledon');
//change_motor('STOP');
//clearInterval(ff1);
});
$('#rightforward').bind('touchstart', function() {
// 押されたとき
if(motor == 'STOP') {
$(this).addClass('ledon');
change_motor('RIGHTFORWARD');
//ff1 = setInterval(function(){
//change_motor('RIGHTFORWARD');
//}, 3000);
}
}).bind('touchend', function() {
// 離したとき
$(this).removeClass('ledon');
//change_motor('STOP');
//clearInterval(ff1);
});
$('#leftbackward').bind('touchstart', function() {
// 押されたとき
if(motor == 'STOP') {
$(this).addClass('ledon');
change_motor('LEFTBACKWARD');
//ff1 = setInterval(function(){
//change_motor('LEFTBACKWARD');
//}, 5500);
}
}).bind('touchend', function() {
// 離したとき
$(this).removeClass('ledon');
//change_motor('STOP');
//clearInterval(ff1);
});
$('#rightbackward').bind('touchstart', function() {
// 押されたとき
if(motor == 'STOP') {
$(this).addClass('ledon');
change_motor('RIGHTBACKWARD');
//ff1 = setInterval(function(){
//change_motor('RIGHTBACKWARD');
//}, 3000);
}
}).bind('touchend', function() {
// 離したとき
$(this).removeClass('ledon');
//change_motor('STOP');
//clearInterval(ff1);
});
$('#topl').bind('touchstart', function() {
// 押されたとき
if(motor == 'STOP') {
$(this).addClass('ledon');
change_motor('topl');
//ff1 = setInterval(function(){
//change_motor('RIGHTBACKWARD');
//}, 3000);
}
}).bind('touchend', function() {
// 離したとき
$(this).removeClass('ledon');
//change_motor('STOP');
//clearInterval(ff1);
});
$('#tops').bind('touchstart', function() {
// 押されたとき
if(motor == 'STOP') {
$(this).addClass('ledon');
change_motor('tops');
//ff1 = setInterval(function(){
//change_motor('RIGHTBACKWARD');
//}, 3000);
}
}).bind('touchend', function() {
// 離したとき
$(this).removeClass('ledon');
//change_motor('STOP');
//clearInterval(ff1);
});
$('#topr').bind('touchstart', function() {
// 押されたとき
if(motor == 'STOP') {
$(this).addClass('ledon');
change_motor('topr');
//ff1 = setInterval(function(){
//change_motor('RIGHTBACKWARD');
//}, 3000);
}
}).bind('touchend', function() {
// 離したとき
$(this).removeClass('ledon');
//change_motor('STOP');
//clearInterval(ff1);
});
$('#l').bind('touchstart', function() {
// 押されたとき
if(motor == 'STOP') {
$(this).addClass('ledon');
change_motor('L');
}
}).bind('touchend', function() {
// 離したとき
$(this).removeClass('ledon');
//change_motor('STOP');
change_motor2();
});
$('#r').bind('touchstart', function() {
// 押されたとき
if(motor == 'STOP') {
$(this).addClass('ledon');
change_motor('R');
}
}).bind('touchend', function() {
// 離したとき
$(this).removeClass('ledon');
//change_motor('STOP');
change_motor2();
});
});
#!/usr/bin/python3
#! -*- coding: utf-8 -*-
import time
import cgi
import Adafruit_PCA9685
import RPi.GPIO as GPIO
import sys
GPIO.setmode(GPIO.BCM)
LED_1 = 18
LED_2 = 23
GPIO.setup(LED_1, GPIO.OUT)
GPIO.setup(LED_2, GPIO.OUT)
#led = GPIO.PWM(LED_1,50)
#led2 = GPIO.PWM(LED_2,50)
#light = 0
form = cgi.FieldStorage()
recieve = form.getvalue('name')
pwm = Adafruit_PCA9685.PCA9685()
pwm.set_pwm_freq(60)
a = 370
b = 360
c = 380
d = 350
e = 380
f = 370
g = 370
h = 390
i = 300
j = 400
k = 300
l = 420
if recieve == 'hhhh':
while(d >= 300):
pwm.set_pwm(1, 0, b)
pwm.set_pwm(3, 0, d)
d = d - 2
b = b - 2
time.sleep(0.005)
#time.sleep(3)
while(c <= 450):
#sev.position(2, c)
#sev.position(4, e)
#sev.position(5, f)
#sev.position(6, g)
pwm.set_pwm(2, 0, c)
pwm.set_pwm(4, 0, e)
pwm.set_pwm(5, 0, f)
pwm.set_pwm(6, 0, g)
c = c + 2
f = f - 2
g = g - 2
e = e - 2
time.sleep(0.005)
#time.sleep(3)
while(b <= 360):
#sev.position(3, d)
#sev.position(1, b)
pwm.set_pwm(1, 0, b)
pwm.set_pwm(3, 0, d)
d = d + 2
b = b + 2
time.sleep(0.005)
#time.sleep(3)
while(c >= 380):
#sev.position(2, c)
#sev.position(4, e)
#sev.position(5, f)
#sev.position(6, g)
pwm.set_pwm(2, 0, c)
pwm.set_pwm(4, 0, e)
pwm.set_pwm(5, 0, f)
pwm.set_pwm(6, 0, g)
c = c - 2
f = f + 2
g = g + 2
e = e + 2
time.sleep(0.005)
#time.sleep(3)
while(b <= 410):
#sev.position(3, d)
#sev.position(1, b)
pwm.set_pwm(1, 0, b)
pwm.set_pwm(3, 0, d)
b = b + 2
d = d + 2
time.sleep(0.005)
#time.sleep(3)
while(a >= 300):
#sev.position(0, a)
#sev.position(4, e)
#sev.position(5, f)
#sev.position(6, g)
pwm.set_pwm(0, 0, a)
pwm.set_pwm(4, 0, e)
pwm.set_pwm(5, 0, f)
pwm.set_pwm(6, 0, g)
a = a - 2
f = f + 2
g = g + 2
e = e + 2
time.sleep(0.005)
#time.sleep(3)
while(b >= 360):
#sev.position(3, d)
#sev.position(1, b)
pwm.set_pwm(1, 0, b)
pwm.set_pwm(3, 0, d)
d = d - 2
b = b - 2
time.sleep(0.005)
#time.sleep(3)
while(a <= 370):
#sev.position(0, a)
#sev.position(4, e)
#sev.position(5, f)
#sev.position(6, g)
pwm.set_pwm(0, 0, a)
pwm.set_pwm(4, 0, e)
pwm.set_pwm(5, 0, f)
pwm.set_pwm(6, 0, g)
a = a + 2
f = f - 2
g = g - 2
e = e - 2
time.sleep(0.005)
print('Content-type: text/html\n')
print(recieve)
print('ff')
elif recieve == 'jjjj':
while(d >= 300):
pwm.set_pwm(1, 0, b)
pwm.set_pwm(3, 0, d)
d = d - 2
b = b - 2
time.sleep(0.005)
#time.sleep(3)
while(c >= 310):
#sev.position(2, c)
#sev.position(4, e)
#sev.position(5, f)
#sev.position(6, g)
pwm.set_pwm(2, 0, c)
#pwm.set_pwm(4, 0, e)
pwm.set_pwm(5, 0, f)
pwm.set_pwm(6, 0, g)
c = c - 2
f = f + 2
g = g + 2
#e = e + 2
time.sleep(0.005)
#time.sleep(3)
while(b <= 360):
#sev.position(3, d)
#sev.position(1, b)
pwm.set_pwm(1, 0, b)
pwm.set_pwm(3, 0, d)
d = d + 2
b = b + 2
time.sleep(0.005)
while(c <= 380):
#sev.position(2, c)
#sev.position(4, e)
#sev.position(5, f)
#sev.position(6, g)
pwm.set_pwm(2, 0, c)
#pwm.set_pwm(4, 0, e)
pwm.set_pwm(5, 0, f)
pwm.set_pwm(6, 0, g)
c = c + 2
f = f - 2
g = g - 2
#e = e - 2
time.sleep(0.005)
print('Content-type: text/html\n')
print(recieve)
print("r")
elif recieve == 'kkkk':
while(b <= 410):
#sev.position(3, d)
#sev.position(1, b)
pwm.set_pwm(1, 0, b)
pwm.set_pwm(3, 0, d)
b = b + 2
d = d + 2
time.sleep(0.005)
#time.sleep(3)
while(a <= 440):
#sev.position(0, a)
#sev.position(4, e)
#sev.position(5, f)
#sev.position(6, g)
pwm.set_pwm(0, 0, a)
#pwm.set_pwm(4, 0, e)
pwm.set_pwm(5, 0, f)
pwm.set_pwm(6, 0, g)
a = a + 2
f = f - 2
g = g - 2
#e = e - 2
time.sleep(0.005)
#time.sleep(3)
while(b >= 360):
#sev.position(3, d)
#sev.position(1, b)
pwm.set_pwm(1, 0, b)
pwm.set_pwm(3, 0, d)
d = d - 2
b = b - 2
time.sleep(0.005)
#time.sleep(3)
while(a >= 370):
#sev.position(0, a)
#sev.position(4, e)
#sev.position(5, f)
#sev.position(6, g)
pwm.set_pwm(0, 0, a)
#pwm.set_pwm(4, 0, e)
pwm.set_pwm(5, 0, f)
pwm.set_pwm(6, 0, g)
a = a - 2
f = f + 2
g = g + 2
#e = e + 2
time.sleep(0.005)
print('Content-type: text/html\n')
print(recieve)
print('l')
elif recieve == 'iiii':
while(d >= 300):
pwm.set_pwm(1, 0, b)
pwm.set_pwm(3, 0, d)
d = d - 2
b = b - 2
time.sleep(0.005)
#time.sleep(3)
while(c >= 310):
#sev.position(2, c)
#sev.position(4, e)
#sev.position(5, f)
#sev.position(6, g)
pwm.set_pwm(2, 0, c)
pwm.set_pwm(4, 0, e)
pwm.set_pwm(5, 0, f)
pwm.set_pwm(6, 0, g)
c = c - 2
f = f + 2
g = g + 2
e = e + 2
time.sleep(0.005)
#time.sleep(3)
while(b <= 360):
#sev.position(3, d)
#sev.position(1, b)
pwm.set_pwm(1, 0, b)
pwm.set_pwm(3, 0, d)
d = d + 2
b = b + 2
time.sleep(0.005)
#time.sleep(3)
while(c <= 380):
#sev.position(2, c)
#sev.position(4, e)
#sev.position(5, f)
#sev.position(6, g)
pwm.set_pwm(2, 0, c)
pwm.set_pwm(4, 0, e)
pwm.set_pwm(5, 0, f)
pwm.set_pwm(6, 0, g)
c = c + 2
f = f - 2
g = g - 2
e = e - 2
time.sleep(0.005)
#time.sleep(3)
while(b <= 410):
#sev.position(3, d)
#sev.position(1, b)
pwm.set_pwm(1, 0, b)
pwm.set_pwm(3, 0, d)
b = b + 2
d = d + 2
time.sleep(0.005)
#time.sleep(3)
while(a <= 440):
#sev.position(0, a)
#sev.position(4, e)
#sev.position(5, f)
#sev.position(6, g)
pwm.set_pwm(0, 0, a)
pwm.set_pwm(4, 0, e)
pwm.set_pwm(5, 0, f)
pwm.set_pwm(6, 0, g)
a = a + 2
f = f - 2
g = g - 2
e = e - 2
time.sleep(0.005)
#time.sleep(3)
while(b >= 360):
#sev.position(3, d)
#sev.position(1, b)
pwm.set_pwm(1, 0, b)
pwm.set_pwm(3, 0, d)
d = d - 2
b = b - 2
time.sleep(0.005)
#time.sleep(3)
while(a >= 370):
#sev.position(0, a)
#sev.position(4, e)
#sev.position(5, f)
#sev.position(6, g)
pwm.set_pwm(0, 0, a)
pwm.set_pwm(4, 0, e)
pwm.set_pwm(5, 0, f)
pwm.set_pwm(6, 0, g)
a = a - 2
f = f + 2
g = g + 2
e = e + 2
time.sleep(0.005)
print('Content-type: text/html\n')
print(recieve)
print('bk')
elif recieve == "topl":
pwm.set_pwm(11, 0, 300)
print('Content-type: text/html\n')
print(recieve)
print('l')
elif recieve == "tops":
pwm.set_pwm(11, 0, 420)
print('Content-type: text/html\n')
print(recieve)
print('s')
elif recieve == "topr":
pwm.set_pwm(11, 0, 540)
print('Content-type: text/html\n')
print(recieve)
print('r')
elif recieve == 'qqqq':
GPIO.output(LED_1,GPIO.LOW)
GPIO.output(LED_2,GPIO.LOW)
pwm.set_pwm(11, 0, 370)
while(e <= 480):
#sev.position(2, c)
#sev.position(4, e)
#sev.position(5, f)
#sev.position(6, g)
pwm.set_pwm(4, 0, e)
e = e + 2
time.sleep(0.005)
time.sleep(1)
while(f <= 600):
#sev.position(2, c)
#sev.position(4, e)
#sev.position(5, f)
#sev.position(6, g)
pwm.set_pwm(5, 0, f)
#pwm.set_pwm(4, 0, e)
#pwm.set_pwm(5, 0, f)
#pwm.set_pwm(6, 0, g)
f = f + 2
#g = g - 2
#e = e - 2
time.sleep(0.005)
time.sleep(0.5)
while(j <= 500):
pwm.set_pwm(9, 0, j)
j = j + 2
time.sleep(0.005)
time.sleep(3)
#while(l >= 320):
#sev.position(2, c)
#sev.position(4, e)
#sev.position(5, f)
#sev.position(6, g)
pwm.set_pwm(11, 0, 300)
GPIO.output(LED_1,GPIO.HIGH)
GPIO.output(LED_2,GPIO.HIGH)
time.sleep(5)
GPIO.output(LED_1,GPIO.LOW)
GPIO.output(LED_2,GPIO.LOW)
pwm.set_pwm(0, 0, a)
pwm.set_pwm(1, 0, b)
pwm.set_pwm(2, 0, c)
pwm.set_pwm(3, 0, d)
pwm.set_pwm(4, 0, 380)
pwm.set_pwm(5, 0, 370)
pwm.set_pwm(6, 0, g)
pwm.set_pwm(7, 0, 390)
pwm.set_pwm(8, 0, i)
pwm.set_pwm(9, 0, 400)
pwm.set_pwm(10, 0, k)
pwm.set_pwm(11, 0, l)
print('Content-type: text/html\n')
print(recieve)
print('1')
elif recieve == 'mmmm': #2
pwm.set_pwm(11, 0, l)
GPIO.output(LED_1,GPIO.LOW)
GPIO.output(LED_2,GPIO.LOW)
while(e >= 280):
#sev.position(2, c)
#sev.position(4, e)
#sev.position(5, f)
#sev.position(6, g)
pwm.set_pwm(4, 0, e)
e = e - 2
time.sleep(0.005)
time.sleep(1)
while(g >= 140):
#sev.position(2, c)
#sev.position(4, e)
#sev.position(5, f)
#sev.position(6, g)
pwm.set_pwm(6, 0, g)
#pwm.set_pwm(4, 0, e)
#pwm.set_pwm(5, 0, f)
#pwm.set_pwm(6, 0, g)
g = g - 2
#g = g - 2
#e = e - 2
time.sleep(0.005)
time.sleep(0.5)
while(k >= 150):
pwm.set_pwm(10, 0, k)
k = k - 2
time.sleep(0.005)
time.sleep(3)
#while(l >= 320):
#sev.position(2, c)
#sev.position(4, e)
#sev.position(5, f)
#sev.position(6, g)
pwm.set_pwm(11, 0, 540)
GPIO.output(LED_1,GPIO.HIGH)
GPIO.output(LED_2,GPIO.HIGH)
time.sleep(5)
GPIO.output(LED_1,GPIO.LOW)
GPIO.output(LED_2,GPIO.LOW)
pwm.set_pwm(0, 0, a)
pwm.set_pwm(1, 0, b)
pwm.set_pwm(2, 0, c)
pwm.set_pwm(3, 0, d)
pwm.set_pwm(4, 0, 380)
pwm.set_pwm(5, 0, 370)
pwm.set_pwm(6, 0, 370)
pwm.set_pwm(7, 0, 390)
pwm.set_pwm(8, 0, 300)
pwm.set_pwm(9, 0, 400)
pwm.set_pwm(10, 0, 300)
pwm.set_pwm(11, 0, l)
print('Content-type: text/html\n')
print(recieve)
print('2')
elif recieve == 'oooo': #3
num = 0
while(n >= 340):
pwm.set_pwm(1, 0, n)
pwm.set_pwm(3, 0, t)
time.sleep(0.0001)
n = n - 1
t = t - 1
while(num <= 3):
num = num + 1
while(c >= 130):
pwm.set_pwm(6, 0, c)
pwm.set_pwm(7, 0, d)
time.sleep(0.0001)
c = c - 1
d = d + 1
while(c <= 230):
pwm.set_pwm(6, 0, c)
pwm.set_pwm(7, 0, d)
time.sleep(0.0001)
c = c + 1
d = d - 1
while(n <= 440 ):
pwm.set_pwm(1, 0, n)
pwm.set_pwm(3, 0, t)
time.sleep(0.0001)
n = n + 1
t = t + 1
print('Content-type: text/html\n')
print(recieve)
print('3')
elif recieve == 'zzzz': #4
num = 0
while(n <= 540):
pwm.set_pwm(1, 0, n)
pwm.set_pwm(3, 0, t)
time.sleep(0.0001)
n = n + 1
t = t + 1
while(num <= 3):
num = num + 1
while(c >= 130):
pwm.set_pwm(6, 0, c)
pwm.set_pwm(7, 0, d)
time.sleep(0.0001)
c = c - 1
d = d + 1
while(c <= 230):
pwm.set_pwm(6, 0, c)
pwm.set_pwm(7, 0, d)
time.sleep(0.0001)
c = c + 1
d = d - 1
while(n >= 440 ):
pwm.set_pwm(1, 0, n)
pwm.set_pwm(3, 0, t)
time.sleep(0.0001)
n = n - 1
t = t - 1
print('Content-type: text/html\n')
print(recieve)
print('4')
elif recieve == 'gggg':
GPIO.output(LED_1,GPIO.HIGH)
GPIO.output(LED_2,GPIO.HIGH)
#while(light <= 100):
#led.ChangeDutyCycle(right)
#led2.ChangeDutyCycle(right)
#light = light + 1
#time.sleep(0.05)
elif recieve == 'dddd':
GPIO.output(LED_1,GPIO.LOW)
GPIO.output(LED_2,GPIO.LOW)
#while(light >= 0):
#led.ChangeDutyCycle(right)
#led2.ChangeDutyCycle(right)
#light = light - 1
#time.sleep(0.05)
elif recieve == 'ssss':
#GPIO.output(MOTOR_A1,GPIO.LOW)
#GPIO.output(MOTOR_A2,GPIO.LOW)
#GPIO.output(MOTOR_A3,GPIO.LOW)
#GPIO.output(MOTOR_A4,GPIO.LOW)
#pwm.set_pwm(0, 0, 375)
#pwm.set_pwm(1, 0, 375)
#pwm.set_pwm(2, 0, 375)
#pwm.set_pwm(3, 0, 375)
pass
print('st')
スマホでテスト。
アナログコントローラー(micropython)
アナログコントローラーにはM5stickCのJoyCを使いました。
当初はbleで接続する予定でしたが、micropythonのbleのライブラリであるubluetoothがm5stickcのmicropythonファームウェアでは利用出来ず、断念してUDPで接続させています。(ESP32のmicropythonファームウェアを入れたらubluetoothライブラリが使用できましたが、代わりにJoyC等m5stack関連のライブラリが使用できない。)
※あやまってmain.pyプログラムをdeleteしてしまいました(;^ω^)後日改めて掲載します。
RaspberryPi側(python)
from socket import socket, AF_INET, SOCK_DGRAM
import time
import Adafruit_PCA9685
import RPi.GPIO as GPIO
import sys
import threading
GPIO.setmode(GPIO.BCM)
LED_1 = 18
LED_2 = 23
GPIO.setup(LED_1, GPIO.OUT)
GPIO.setup(LED_2, GPIO.OUT)
#led = GPIO.PWM(LED_1,50)
#led2 = GPIO.PWM(LED_2,50)
led = 0
led2 = 0
#led.start(0)
#led2.start(0)
right = 0
pwm = Adafruit_PCA9685.PCA9685()
pwm.set_pwm_freq(60)
a = 370
b = 360
c = 380
d = 350
e = 380
f = 370
g = 370
h = 390
i = 300
j = 400
k = 300
l = 420
HOST = "ローカルIP"
PORT = 5000
s = socket(AF_INET, SOCK_DGRAM)
s.bind((HOST, PORT))
msg = "none"
def recieve():
global msg
while True:
msg, address = s.recvfrom(8192)
#print(f"message: {msg}\nfrom: {address}")
msg = msg.decode()
print(msg)
time.sleep(0.1)
th = threading.Thread(target=recieve)
th.start()
while True:
try:
if msg == 'f':
while(d >= 300):
pwm.set_pwm(1, 0, b)
pwm.set_pwm(3, 0, d)
d = d - 2
b = b - 2
time.sleep(0.005)
#time.sleep(3)
while(c <= 450):
#sev.position(2, c)
#sev.position(4, e)
#sev.position(5, f)
#sev.position(6, g)
pwm.set_pwm(2, 0, c)
pwm.set_pwm(4, 0, e)
pwm.set_pwm(5, 0, f)
pwm.set_pwm(6, 0, g)
c = c + 2
f = f - 2
g = g - 2
e = e - 2
time.sleep(0.005)
#time.sleep(3)
while(b <= 360):
#sev.position(3, d)
#sev.position(1, b)
pwm.set_pwm(1, 0, b)
pwm.set_pwm(3, 0, d)
d = d + 2
b = b + 2
time.sleep(0.005)
#time.sleep(3)
while(c >= 380):
#sev.position(2, c)
#sev.position(4, e)
#sev.position(5, f)
#sev.position(6, g)
pwm.set_pwm(2, 0, c)
pwm.set_pwm(4, 0, e)
pwm.set_pwm(5, 0, f)
pwm.set_pwm(6, 0, g)
c = c - 2
f = f + 2
g = g + 2
e = e + 2
time.sleep(0.005)
#time.sleep(3)
while(b <= 410):
#sev.position(3, d)
#sev.position(1, b)
pwm.set_pwm(1, 0, b)
pwm.set_pwm(3, 0, d)
b = b + 2
d = d + 2
time.sleep(0.005)
#time.sleep(3)
while(a >= 300):
#sev.position(0, a)
#sev.position(4, e)
#sev.position(5, f)
#sev.position(6, g)
pwm.set_pwm(0, 0, a)
pwm.set_pwm(4, 0, e)
pwm.set_pwm(5, 0, f)
pwm.set_pwm(6, 0, g)
a = a - 2
f = f + 2
g = g + 2
e = e + 2
time.sleep(0.005)
#time.sleep(3)
while(b >= 360):
#sev.position(3, d)
#sev.position(1, b)
pwm.set_pwm(1, 0, b)
pwm.set_pwm(3, 0, d)
d = d - 2
b = b - 2
time.sleep(0.005)
#time.sleep(3)
while(a <= 370):
#sev.position(0, a)
#sev.position(4, e)
#sev.position(5, f)
#sev.position(6, g)
pwm.set_pwm(0, 0, a)
pwm.set_pwm(4, 0, e)
pwm.set_pwm(5, 0, f)
pwm.set_pwm(6, 0, g)
a = a + 2
f = f - 2
g = g - 2
e = e - 2
time.sleep(0.005)
elif msg == 'r':
while(d >= 300):
pwm.set_pwm(1, 0, b)
pwm.set_pwm(3, 0, d)
d = d - 2
b = b - 2
time.sleep(0.005)
#time.sleep(3)
while(c >= 310):
#sev.position(2, c)
#sev.position(4, e)
#sev.position(5, f)
#sev.position(6, g)
pwm.set_pwm(2, 0, c)
#pwm.set_pwm(4, 0, e)
pwm.set_pwm(5, 0, f)
pwm.set_pwm(6, 0, g)
c = c - 2
f = f + 2
g = g + 2
#e = e + 2
time.sleep(0.005)
#time.sleep(3)
while(b <= 360):
#sev.position(3, d)
#sev.position(1, b)
pwm.set_pwm(1, 0, b)
pwm.set_pwm(3, 0, d)
d = d + 2
b = b + 2
time.sleep(0.005)
while(c <= 380):
#sev.position(2, c)
#sev.position(4, e)
#sev.position(5, f)
#sev.position(6, g)
pwm.set_pwm(2, 0, c)
#pwm.set_pwm(4, 0, e)
pwm.set_pwm(5, 0, f)
pwm.set_pwm(6, 0, g)
c = c + 2
f = f - 2
g = g - 2
#e = e - 2
time.sleep(0.005)
elif msg == 'l':
while(b <= 410):
#sev.position(3, d)
#sev.position(1, b)
pwm.set_pwm(1, 0, b)
pwm.set_pwm(3, 0, d)
b = b + 2
d = d + 2
time.sleep(0.005)
#time.sleep(3)
while(a <= 440):
#sev.position(0, a)
#sev.position(4, e)
#sev.position(5, f)
#sev.position(6, g)
pwm.set_pwm(0, 0, a)
#pwm.set_pwm(4, 0, e)
pwm.set_pwm(5, 0, f)
pwm.set_pwm(6, 0, g)
a = a + 2
f = f - 2
g = g - 2
#e = e - 2
time.sleep(0.005)
#time.sleep(3)
while(b >= 360):
#sev.position(3, d)
#sev.position(1, b)
pwm.set_pwm(1, 0, b)
pwm.set_pwm(3, 0, d)
d = d - 2
b = b - 2
time.sleep(0.005)
#time.sleep(3)
while(a >= 370):
#sev.position(0, a)
#sev.position(4, e)
#sev.position(5, f)
#sev.position(6, g)
pwm.set_pwm(0, 0, a)
#pwm.set_pwm(4, 0, e)
pwm.set_pwm(5, 0, f)
pwm.set_pwm(6, 0, g)
a = a - 2
f = f + 2
g = g + 2
#e = e + 2
time.sleep(0.005)
elif msg == 'b':
while(d >= 300):
pwm.set_pwm(1, 0, b)
pwm.set_pwm(3, 0, d)
d = d - 2
b = b - 2
time.sleep(0.005)
#time.sleep(3)
while(c >= 310):
#sev.position(2, c)
#sev.position(4, e)
#sev.position(5, f)
#sev.position(6, g)
pwm.set_pwm(2, 0, c)
pwm.set_pwm(4, 0, e)
pwm.set_pwm(5, 0, f)
pwm.set_pwm(6, 0, g)
c = c - 2
f = f + 2
g = g + 2
e = e + 2
time.sleep(0.005)
#time.sleep(3)
while(b <= 360):
#sev.position(3, d)
#sev.position(1, b)
pwm.set_pwm(1, 0, b)
pwm.set_pwm(3, 0, d)
d = d + 2
b = b + 2
time.sleep(0.005)
#time.sleep(3)
while(c <= 380):
#sev.position(2, c)
#sev.position(4, e)
#sev.position(5, f)
#sev.position(6, g)
pwm.set_pwm(2, 0, c)
pwm.set_pwm(4, 0, e)
pwm.set_pwm(5, 0, f)
pwm.set_pwm(6, 0, g)
c = c + 2
f = f - 2
g = g - 2
e = e - 2
time.sleep(0.005)
#time.sleep(3)
while(b <= 410):
#sev.position(3, d)
#sev.position(1, b)
pwm.set_pwm(1, 0, b)
pwm.set_pwm(3, 0, d)
b = b + 2
d = d + 2
time.sleep(0.005)
#time.sleep(3)
while(a <= 440):
#sev.position(0, a)
#sev.position(4, e)
#sev.position(5, f)
#sev.position(6, g)
pwm.set_pwm(0, 0, a)
pwm.set_pwm(4, 0, e)
pwm.set_pwm(5, 0, f)
pwm.set_pwm(6, 0, g)
a = a + 2
f = f - 2
g = g - 2
e = e - 2
time.sleep(0.005)
#time.sleep(3)
while(b >= 360):
#sev.position(3, d)
#sev.position(1, b)
pwm.set_pwm(1, 0, b)
pwm.set_pwm(3, 0, d)
d = d - 2
b = b - 2
time.sleep(0.005)
#time.sleep(3)
while(a >= 370):
#sev.position(0, a)
#sev.position(4, e)
#sev.position(5, f)
#sev.position(6, g)
pwm.set_pwm(0, 0, a)
pwm.set_pwm(4, 0, e)
pwm.set_pwm(5, 0, f)
pwm.set_pwm(6, 0, g)
a = a - 2
f = f + 2
g = g + 2
e = e + 2
time.sleep(0.005)
elif msg == "hl":
if l >= 300:
l = l - 2
pwm.set_pwm(11, 0, l)
time.sleep(0.005)
elif msg == "hr":
if l <= 540:
l = l + 2
pwm.set_pwm(11, 0, l)
time.sleep(0.005)
elif msg == "hlf":
if f >= 140:
f = f - 2
pwm.set_pwm(5, 0, f)
time.sleep(0.005)
elif msg == "hlb":
if f <= 600:
f = f + 2
pwm.set_pwm(5, 0, f)
time.sleep(0.005)
elif msg == "hrf":
if g <= 600:
g = g + 2
pwm.set_pwm(6, 0, g)
time.sleep(0.005)
elif msg == "hrb":
if g >= 140:
g = g - 2
pwm.set_pwm(6, 0, g)
time.sleep(0.005)
elif msg == "hlup":
if h <= 600:
h = h + 2
pwm.set_pwm(7, 0, h)
time.sleep(0.005)
elif msg == "hldown":
if h >= 390:
h = h - 2
pwm.set_pwm(7, 0, h)
time.sleep(0.005)
elif msg == "hrup":
if i >= 90:
i = i - 2
pwm.set_pwm(8, 0, i)
time.sleep(0.005)
elif msg == "hrdown":
if i <= 300:
i = i + 2
pwm.set_pwm(8, 0, i)
time.sleep(0.005)
elif msg == "el":
if e <= 480:
e = e + 1
pwm.set_pwm(4, 0, e)
time.sleep(0.005)
elif msg == "er":
if e >= 280:
e = e - 1
pwm.set_pwm(4, 0, e)
time.sleep(0.005)
elif msg == "on":
led = GPIO.PWM(LED_1,50)
led2 = GPIO.PWM(LED_2,50)
led.start(0)
led2.start(0)
while(right <= 100):
led.ChangeDutyCycle(right)
led2.ChangeDutyCycle(right)
right = right + 1
time.sleep(0.05)
right = right - 1
elif msg == "set":
pwm.set_pwm(0, 0, 370)
pwm.set_pwm(1, 0, 360)
pwm.set_pwm(2, 0, 380)
pwm.set_pwm(3, 0, 350)
pwm.set_pwm(4, 0, 380)
pwm.set_pwm(5, 0, 370)
pwm.set_pwm(6, 0, 370)
pwm.set_pwm(7, 0, 390)
pwm.set_pwm(8, 0, 300)
pwm.set_pwm(9, 0, 400)
pwm.set_pwm(10, 0, 300)
pwm.set_pwm(11, 0, 420)
time.sleep(1)
elif msg == "off":
while(right >= 0):
led.ChangeDutyCycle(right)
led2.ChangeDutyCycle(right)
right = right - 1
time.sleep(0.05)
right = right + 1
led.stop()
led2.stop()
time.sleep(0.001)
except:
s.close()
ジョイコンでテスト。
電源ボタンの追加
完成
とりあえず仮で完成としますが、また機能追加すればここでまとめたいと思います。
投稿者の人気記事
-
Ketunorobio
さんが
2022/12/14
に
編集
をしました。
(メッセージ: 初版)
ログインしてコメントを投稿する