今回は、
ボタンとサーボモータを使って、旗上げ機を作って行きます。
ボタンを押す度に、サーボモータに付けた旗を、
上げたり、下げたりするよ。
使い方としては、
子供の勉強を助けるアイテムとして使えるよ。
旗に、算数、国語などの教科を書き込み、
宿題が終わったら、ボタンを押して、宿題が終わったことの目印にすると、
楽しくて、勉強のモチベーションが上がるよ!
他には、
子供の忘れ物防止として使えるよ。
旗に、ハンカチ・ティッシュ、水筒などの忘れ物が多い内容を書き込み、
準備が出来たら、ボタンを押して、準備が出来たことの目印に出来るよ。
あなたなら、何に使ってみますか?
この記事で学べること。
- ボタン制御
- モータ制御
- マイコン
- Linux
- Python
やりたいこと
・ボタンを押すと、サーボモータを90°回転させる
・もう一度ボタンを押すと、サーボモータを元に戻す
システム構成図
やることリスト
上記の「やりたいこと」をみて、
どんな作業が必要か、自分で項目を考えてみてください。
これを考えることで、「プログラミング的思考」が身に付いていきます。
番号 | 作業項目 | 備考 |
1 | やりたいこと・システム構成図の作成 | |
2 | やることリストの作成 | 処理項目の洗い出し |
3 | 部品の準備 | |
4 | ボタンが押されたことを判断する | |
5 | サーボモータ制御 | |
6 | まとめ | 以上の機能をまとめて、 やりたいことを実現する! |
7 | デコレート | 自由研究用に、装飾する |
部品の準備
今回のシステムに必要な部品です。
不足している部品があれば購入下さい。
購入に必要な部品を、
Raspberry Pi 関連に記載しています。
以下「」内に記載の商品は、上記URL内の項目名とリンクしています。
以下数量は、ボタン2個、サーボモータ2個で作る場合の数量です。
部品名 | 備考 |
Raspberry Pi | 別途、電源・SDカード・HDMIケーブルが必要です。 |
ジャンパー線(※1) | オスーメス:6本 オスーオス:6本 |
ボタン | 「電子工作キット」内のタクトスイッチでもいいですが、 今回は、工作っぽいのを作る為、 「丸いボタンスイッチ」を購入しました。 |
ブレッドボード(※1) | タクトスイッチを使う場合は必要。 |
サーボモータ | 今後も何かとサーボは使うだろうと、 10個入りの「SG90マイクロサーボ」を購入しました。 そんなに必要ないという方は、 amazonで”SG90″で検索して必要数のサーボを購入下さい。 |
※1)「電子工作キット」内に全て含まれています。
ラズパイは、電源を入れただけでは起動しません。
ラズパイの起動手順の記事を参照ください。
ボタンが押されたことを判断する
以下記事「ボタンが押されたことを判断する」の章で、
回路図・配線図・部品の説明・プログラム の説明をしています。
参照ください。
サーボモータ制御
サーボモータとは、
指定した角度に回転し、正確な位置で止めることが出来るモータのことです。
その代り、
ミニ四駆に付いている、回転し続けるモータの様に、
連続回転は出来ません。
この特性から、サーバモータはロボットの関節、ラジコンの方向などに使用されます。
SG90の仕様
今回使用するSG90の仕様を見ると、以下のことが分かります。
PWM周期 | 50Hz(20ms) |
パルス幅 | パルス幅は、0.5 ~ 2.4msの範囲 2.4 ms:+90°(時計回り) 1.45 ms:0° 0.5 ms:-90°(反時計回り) |
動作電圧 | 4.8V(~5V) |
配線 | オレンジ色の線・・・PWM制御ピン 赤色の線・・・5V電源 茶色の線・・・Ground(0V) |
回路
サーボモータは、PWM(Pulse Width Modulation:パルス幅変調)を使って制御します。
PWM制御は 電圧の HIGH と LOW を繰り返すことで、
出力される電力を制御します。
ラズパイには、ハードウェアPWMを出力する為のピンが以下4本あります。
・PWM Channel 0 : GPIO12、GPIO18
・PWM Channel 1 : GPIO13、GPIO19
しかし、独立して使用出来るのは、
Channel 0 と、Channel 1 のそれぞれ一つづつの組み合わせでです。
例えば、GPIO12とGPIO13 となります。
今回の記事でも、PWM制御に GPIO12とGPIO13 を使って行きます。
配線図
上記、SG90の仕様の章で記載の、
配線の仕様を見ながら、接続します。
# 勿論、ブレッドボードを使わず、
# ラズパイとサーボモータを直接接続してもらっても大丈夫です。
プログラム
「ボタンが押されたことを判断する」の章で、
ピンを制御する為のライブラリ、RPi.GPIOパッケージをインストールしていない人は、
以下コマンドでインストール下さい。
sudo pip3 install rpi.gpio
以下の通り、ディレクトリとファイルを作成する。
この章では、以下赤字のファイルを修正する。
/home/pi/work/servo/
└servo.py
クラスを使ったプログラム
# -*- coding: utf-8 -*-
import RPi.GPIO as GPIO
import time
# PWM channel0 のGPIO12をセット
PWM0_GPIO = 12
# PWM channel1 のGPIO13をセット
PWM1_GPIO = 13
class Servo():
def __init__(self, gpio_num):
# GPIO.BCMを設定することで、GPIO番号で制御出来るようになります。
GPIO.setmode(GPIO.BCM)
GPIO.setup(gpio_num, GPIO.OUT)
# PWM0_GPIOピンを使って、PWMのインスタンスを作成します。
# 第2引数に、サーボモータ仕様のPWM周期である、50(Hz)を設定します。
self.servo = GPIO.PWM(gpio_num, 50)
# PWM出力を開始します。引数にはデューティー比(%表記)を設定します。
self.servo.start(0)
def set_degree(self, degree):
duty_cycle = 2.5 + (12.0 - 2.5) / 180 * (degree + 90)
duty_cycle = round(duty_cycle, 2)
self.servo.ChangeDutyCycle(duty_cycle)
time.sleep(0.2)
self.servo.ChangeDutyCycle(0)
if __name__ == '__main__':
servo_1 = Servo(PWM1_GPIO)
for i in range(-90, 90, 10):
servo_1.set_degree(i)
time.sleep(1)
GPIO.cleanup()
関数を使ったプログラム
# -*- coding: utf-8 -*-
import RPi.GPIO as GPIO
import time
# PWM channel0 のGPIO12をセット
PWM0_GPIO = 12
# PWM channel1 のGPIO13をセット
PWM1_GPIO = 13
servo = None
def start_servo():
# GPIO.BCMを設定することで、GPIO番号で制御出来るようになります。
GPIO.setmode(GPIO.BCM)
GPIO.setup(PWM0_GPIO, GPIO.OUT)
# PWM0_GPIOピンを使って、PWMのインスタンスを作成します。
# 第2引数に、サーボモータ仕様のPWM周期である、50(Hz)を設定します。
global servo
servo = GPIO.PWM(PWM0_GPIO, 50)
# PWM出力を開始します。引数にはデューティー比(%表記)を設定します。
servo.start(0)
def set_degree(degree):
duty_cycle = 2.5 + (12.0 - 2.5) / 180 * (degree + 90)
duty_cycle = round(duty_cycle, 2)
servo.ChangeDutyCycle(duty_cycle)
time.sleep(0.2)
servo.ChangeDutyCycle(0)
def stop_servo():
GPIO.cleanup()
if __name__ == '__main__':
start_servo()
for i in range(-90, 90, 10):
set_degree(i)
time.sleep(1)
stop_servo()
デューティー比の計算の説明をします。
デューティー比(%)は、「パルス幅 ÷ 周期 x 100」 で求めます。
-90°の時は、0.5 ÷ 20 x 100 = 2.5%
0°の時は、(2.4 – 0.5) ÷ 2 ÷ 20 x 100 = 7.25%
90°の時は、2.4 ÷ 20 x 100 = 12%
となります。
上記のset_degree()関数では、引数に角度をセットするようにしています。
その方が、人が使い易いからです。
2.5 + (12.0 – 2.5) / 180 * (degree + 90)
は、角度をデューティー比に変換する式となります。
実行
コマンドラインから、先程作成した servo.py のディレクトリに移動し、
以下コマンドでプログラムを実行する。
python3 servo.py
実行結果は、
1秒周期に10°づつ回転し、
180°回転したら成功です。
まとめ
ボタン2つ、サーボ2つを使った回路図とプログラムを書きますね。
配線図
プログラム
以下の通り、ディレクトリとファイルを作成します。
この章では、以下赤字のファイルを修正します。
/home/pi/work/servo/
├app.py
└servo.py
app.py
# -*- coding: utf-8 -*-
import RPi.GPIO as GPIO
import time
import servo
DEGREE_ON = 0
DEGREE_OFF = -90
# GPIO の番号をセット
SW0_GPIO = 14
SW1_GPIO = 15
# GPIO.BCMを設定することで、GPIO番号で制御出来るようになります。
GPIO.setmode(GPIO.BCM)
# GPIO.INを設定することで、入力モードになります。
# pull_up_down=GPIO.PUD_DOWNにすることで、内部プルダウンになります。
GPIO.setup(SW0_GPIO, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)
GPIO.setup(SW1_GPIO, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)
# 初期設定
servo0 = servo.Servo(servo.PWM0_GPIO)
servo1 = servo.Servo(servo.PWM1_GPIO)
servo0.set_degree(DEGREE_OFF)
sw0_degree = DEGREE_OFF
servo1.set_degree(DEGREE_OFF)
sw1_degree = DEGREE_OFF
# ボタン押し / 離し 動作確認用コード
while True:
try:
# GPIO24の値を読み込み、その値を出力します。
# ボタンを押すと"1"(High)、離すと"0"(Low)が表示されます。
print(f'button: {GPIO.input(SW0_GPIO)}')
if GPIO.input(SW0_GPIO):
if sw0_degree == DEGREE_OFF:
servo0.set_degree(DEGREE_ON)
sw0_degree = DEGREE_ON
else:
servo0.set_degree(DEGREE_OFF)
sw0_degree = DEGREE_OFF
print(f'button: {GPIO.input(SW1_GPIO)}')
if GPIO.input(SW1_GPIO):
if sw1_degree == DEGREE_OFF:
servo1.set_degree(DEGREE_ON)
sw1_degree = DEGREE_ON
else:
servo1.set_degree(DEGREE_OFF)
sw1_degree = DEGREE_OFF
time.sleep(0.5)
# Ctrl+Cキーを押すと処理を停止
except KeyboardInterrupt:
# ピンの設定を初期化
# この処理をしないと、次回 プログラムを実行した時に「ピンが使用中」のエラーになります。
GPIO.cleanup()
実行
コマンドラインから、先程作成した app.py のディレクトリに移動し、
以下コマンドでプログラムを実行する。
python3 app.py
ボタンを押す度に、サーボの角度を、-90° ⇔ 0° と交互に繰り返します。
プログラムを終了する場合は、
Ctrl+Cキー を押すと終了します。
デコレート
作成中・・・
この作業は私の子供に任せます。
夏休みの自由研究として作てもらうので、完成まで少し時間が掛かります。
完成したらUPしますね。
最後に
如何だったでしょうか?
・サーボモータが動いた時、
・ボタンを押して、サーボモータが動いた時、
感動しましたよね♪
この感動を一人でも多くの人に味わってもらいたいな。
自分で作ったものが動くって楽しいですよね♪
以下記事では他にも色んな電子工作を作っています。
あなたが作りたいモノのヒントがあれば嬉しいです。
記事を更新するとTwitterでつぶやきます。
フォローしてもらうと、記事を書くモチベーションが上がります。
下のTwitterアイコンからフォローお願いします。
不明な点があればページTOPの「お問い合わせ」にてご連絡下さい。
もし一人で作るのが難しかったら、
一緒に作るサービスをしています。
お気軽に ページTOPの「お問い合わせ」にてご連絡下さい。