Raspberry Pi×Blynkでサーボモーター(SG-90)を遠隔制御+温湿度を遠隔監視する

畑監視システムではカメラの向きを変えれるようにしたい.そのために,サーボモーターSG-90を使うが,これをBlynkで遠隔制御するための手順メモ.

これまでの開発経緯

前記事までの段階で,Raspberry PiとBlynkというIoTサービスアプリを使って,温湿度情報を遠隔監視する,スマホからRaspberry Piに数値情報を送るというところまで完了していた.本記事では,これにサーボモーターを追加する.
www.eletech.work

使用機器

使用する機器は以下の通り.

  • Raspberry Pi 2 model B
  • 温湿度センサモジュール AE-SHT3X(秋月電子で購入)
  • サーボモーター(SG-90)←安いしトルクもなかなか強いしオススメ!


Raspberry Pi 2 Model B (1)


KKHMF マイクロサーボ SG90 9gネジ付きマイクロサーボモータロボットアーム用サーボアーム小型ロボット航空機RCヘリコプターボート

SG-90について

SG-90のデータシートを見ると,50HzのPWM信号のDutyを変えれば角度を自由に変えれるという超簡単なものであることがわかる.制御方法を絵でまとめると以下のような感じ.

f:id:EleTECH:20190219224549p:plain
SG-90の制御概要

Blynk側の準備

以前既に作成していたSliderを使用する.Sliderの設定を図のようにしておく.SG-90が-90~90°の範囲で動かせるが,畑のような広い土地を監視するシステムなのでそこまで細かい制御はいらない.一旦は,-90~90°の範囲を5つに分割しておく.1が-90°,3が0°,5が+90°という感じである.

f:id:EleTECH:20190219232453p:plain
Sliderの設定

サーボモーターSG-90とRaspbeery Piの接続

以下のとおりとする.

  • 端子橙(PWM)→ Raspberry Pi Pin07(GPIO4)
  • 端子赤(5V)→ Raspberry Pi Pin02(5V)
  • 端子茶(GND)→ Raspberry Pi Pin09(GND)

f:id:EleTECH:20190219223011p:plain
サーボモーター+(前回までの)温湿度モジュールの接続

Python3でプログラム作成

Raspberry PiでPWM制御するなら,pigpioというライブラリを使用するのが便利.pigpioにはservo_pulsewidthという関数が良いされていて,この関数では周波数が50Hzとなっていてちょうど良い.まずはpigpioのインストール.

pi@raspberrypi:~ $ sudo apt-get install pigpio

そのあと,pigpioを以下のコマンドで有効にしておく必要がある.

pi@raspberrypi:~ $ sudo pigpiod

これでpigpioを使用するための準備はOK.前記事で作成していたプログラムに色々追記し,以下のようなプログラムを作成.

import BlynkLib
import smbus
import time
import pigpio
i2c = smbus.SMBus(1)
addr=0x45
pi = pigpio.pi()

def sign16(x):
    return ( -(x & 0b1000000000000000) |
                  (x & 0b0111111111111111) )

# Initialize Blynk
blynk = BlynkLib.Blynk('b8******************************05a')

@blynk.VIRTUAL_WRITE(1)
def my_write_handler(rawServo):
    print('Value for servomotor: {}'.format(rawServo))
    if rawServo == ['1']:
        pi.set_servo_pulsewidth(4, 500)
        time.sleep(3)
    elif rawServo == ['2']:
        pi.set_servo_pulsewidth(4, 975)
        time.sleep(3)
    elif rawServo == ['3']:
        pi.set_servo_pulsewidth(4, 1450)
        time.sleep(3)
    elif rawServo == ['4']:
        pi.set_servo_pulsewidth(4, 1925)
        time.sleep(3)
    elif rawServo == ['5']:
        pi.set_servo_pulsewidth(4, 2400)
        time.sleep(3)

@blynk.VIRTUAL_READ(2)
def my_read_handler():
    blynk.virtual_write(2, (Temparature))

@blynk.VIRTUAL_READ(3)
def my_read_handler():
    blynk.virtual_write(3, (RelativeHumi))

while True:
    #Execute Blynk
    blynk.run()

    #send  address
    i2c.write_byte_data(addr,0xe0,0x0)

    #read data
    data = i2c.read_i2c_block_data(addr,0x0,6)

    #calculate temparature data
    raw_data_T = ((data[0]) << 8) | (data[1]) 
    calc_T = sign16(int(hex(raw_data_T),16))
    Temparature = round(-45 + 175 * calc_T / (2**16 - 1), 1)

    #calculate humidity data
    raw_data_RH = ((data[3]) << 8) | (data[4])
    RelativeHumi = round(100 * raw_data_RH / (2**16 - 1), 1)

    #print data
    print (str(Temparature) +"degC") 
    print (str(RelativeHumi) +"%RH")

    #wait for data conversion
    time.sleep(1)

そして,以下のようにして実行する.

pi@raspberrypi:~ $ sudo python3 blynk_test.py blynk_test

    ___  __          __
   / _ )/ /_ _____  / /__
  / _  / / // / _ \/  '_/
 /____/_/\_, /_//_/_/\_\
        /___/ for Python v0.2.0 (Linux)

21.3degC
52.1%RH
21.3degC
52.2%RH

実行すると,温湿度情報がプリントされ始め,もちろんBlynk側でもGaugeでこれを確認できる.そしてSliderを1から順番に5まで動かしていくと…

f:id:EleTECH:20190219234158p:plain
実行結果
という感じで遠隔制御できた!!感動!今回までで,Raspberry Piとは異なるネットワークにつながるスマホから,Raspberry Piに接続されている温湿度モジュールの情報を読むことができ,さらにRaspberry Piに接続されているサーボモーターSG-90を制御するところまでできた.