Raspberry Pi と サーボモータ を使った【旗上げ機】(自由研究にお薦め)

electric

今回は、
ボタンとサーボモータを使って、旗上げ機を作って行きます。

ボタンを押す度に、サーボモータに付けた旗を、
上げたり、下げたりするよ。

使い方としては、
子供の勉強を助けるアイテムとして使えるよ。
旗に、算数、国語などの教科を書き込み、
宿題が終わったら、ボタンを押して、宿題が終わったことの目印にすると、
楽しくて、勉強のモチベーションが上がるよ!

他には、
子供の忘れ物防止として使えるよ。
旗に、ハンカチ・ティッシュ、水筒などの忘れ物が多い内容を書き込み、
準備が出来たら、ボタンを押して、準備が出来たことの目印に出来るよ。

あなたなら、何に使ってみますか?

この記事で学べること。

  • ボタン制御
  • モータ制御
  • マイコン
  • Linux
  • Python

やりたいこと

・ボタンを押すと、サーボモータを90°回転させる
・もう一度ボタンを押すと、サーボモータを元に戻す

システム構成図

やることリスト

上記の「やりたいこと」をみて、
どんな作業が必要か、自分で項目を考えてみてください。
これを考えることで、「プログラミング的思考」が身に付いていきます。

番号作業項目備考
やりたいこと・システム構成図の作成
やることリストの作成処理項目の洗い出し
部品の準備
4ボタンが押されたことを判断する
サーボモータ制御
まとめ以上の機能をまとめて、
やりたいことを実現する!
デコレート自由研究用に、装飾する

部品の準備

今回のシステムに必要な部品です。
不足している部品があれば購入下さい。

購入に必要な部品を、
Raspberry Pi 関連に記載しています。
以下「」内に記載の商品は、上記URL内の項目名とリンクしています。

以下数量は、ボタン2個、サーボモータ2個で作る場合の数量です。

部品名備考
Raspberry Pi別途、電源・SDカード・HDMIケーブルが必要です。
ジャンパー線(※1)オスーメス:6本
オスーオス:6本
ボタン「電子工作キット」内のタクトスイッチでもいいですが、
今回は、工作っぽいのを作る為、
「丸いボタンスイッチ」を購入しました。
ブレッドボード(※1)タクトスイッチを使う場合は必要。
サーボモータ今後も何かとサーボは使うだろうと、
10個入りの「SG90マイクロサーボ」を購入しました。
そんなに必要ないという方は、
amazonで”SG90″で検索して必要数のサーボを購入下さい。

※1)「電子工作キット」内に全て含まれています。

ラズパイは、電源を入れただけでは起動しません。
ラズパイの起動手順の記事を参照ください。

ボタンが押されたことを判断する

以下記事「ボタンが押されたことを判断する」の章で、
回路図・配線図・部品の説明・プログラム の説明をしています。
参照ください。

Raspberry Pi と Python を使って【天気予報】を喋らせる
今回は、ボタンを押したら、地元の天気予報を喋ってもらおうと思います。楽しそうだったら作ってみて♪この記事では以下が学べます。ボタン制御スピーカー出力PythonWebAPI(外部情報取得)音声合成(発話)やりた...

サーボモータ制御

サーボモータとは、
指定した角度に回転し、正確な位置で止めることが出来るモータのことです。

その代り、
ミニ四駆に付いている、回転し続けるモータの様に、
連続回転は出来ません。

この特性から、サーバモータはロボットの関節、ラジコンの方向などに使用されます。

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しますね。

最後に

如何だったでしょうか?

・サーボモータが動いた時、
・ボタンを押して、サーボモータが動いた時、
感動しましたよね♪
この感動を一人でも多くの人に味わってもらいたいな。

自分で作ったものが動くって楽しいですよね♪

以下記事では他にも色んな電子工作を作っています。
あなたが作りたいモノのヒントがあれば嬉しいです。

電子工作(Raspberry Pi でできること)
このサイトは、「モノづくりの楽しさをあなたに伝えたい」との思いで作っています。「難易度:☆☆☆」の章に、Raspberry Pi(マイコン) と Python(プログラミング言語)を使ったおもちゃの作り方を書いています。あ...

記事を更新するとTwitterでつぶやきます。
フォローしてもらうと、記事を書くモチベーションが上がります。
下のTwitterアイコンからフォローお願いします。

不明な点があればページTOPの「お問い合わせ」にてご連絡下さい。

もし一人で作るのが難しかったら、
一緒に作るサービスをしています。
お気軽に ページTOPの「お問い合わせ」にてご連絡下さい。

タイトルとURLをコピーしました