PyCharmを使ってRaspberry Pi2上で快適リモートGPIOプログラミング

概要

せっかくRaspberry pi2も出て、モノノインターネットだとかフィジカルコンピューティングだとかユビキタス(これは死語?)も流行っているので、GPIO経由でセンサやサーボを使うプログラムを書きたいな、と思いました。
その際にPythonを使い、開発環境としてJetBrains社のPython IDEであるPyCharmを使って、普段使っているPCからリモート開発環境を作ってみました。
CUIモードのRaspberry pi2上で素のviで書くのもカッコイイとは思うのですが、入力補完等が親切な方が個人的には嬉しいです。
このエントリはその備忘録です。

多少覚えることはありますが、初心者がいきなりPythonをRaspberry pi上で書き始める、と言うのであればPyCharmは親切な環境であると思います。
他にもCPUが非力なLinuxが載る組み込み系ボード(BBB,Odroid)でも、同様に使えてIDEの恩恵を受けられるので、リモートは便利です!

開発環境

  • Raspberry pi 2
  • Rasbian CUI (2/16付最新版)
  • Python2.7
  • PyCharm 4.0.4 Professional(Community Editionではリモート開発が出来ません。有償ですがPro版必須です)
  • RPi.GPIO 5.11(2/17最新版、 5.10以下ではpi2でランタイムエラーが起きます)

また、rasbianのユーザとパスは初期設定の通り(user:pi pass:raspberry)とします。 (web公開サービスとかではダメですが、今回は組み込み的に使うのと、説明の簡略化の為です)

PyCharmは有料ですが、学生の方はJetbrain社の学生ライセンスがあるので、教育目的であれば無償で利用できます。

Free for students: Professional developer tools from JetBrains

Rasberry piの設定

  1. apt-getを最新版にアップデートし、最低限のライブラリを入れる
  2. 固定IPを振る
  3. SSH接続を受け入れる

1.最新版にアップデートする

sudo apt-get update
sudo apt-get upgrade 
sudo apt-get install python-rpi.gpio
sudo apt-get install python-pip

2.固定IPを振る

sudo vi /etc/network/interfaces

で開いて

iface eth0 inet dhcp

の行を(今回は192.168.0.25にすると仮定)

#iface eth0 inet dhcp
iface eth0 inet static

address 192.168.0.25
netmask 255.255.255.0
gateway 192.168.0.1

と書き換えます。

sudo shutdown -r now

で再起動したら、

ifconfig

でinetアドレスが192.168.0.25になっているかを確認します。

参考サイト: Raspberry Piに固定IPアドレスを割り振る方法 http://blog.nambo.jp/2013/07/28/raspberrypi-set-ipaddress/

3.SSH接続を受け入れる

rasbian上のターミナルで

sudo raspi-config

のraspi-configを起動して
8 Advanced Options Configure advanced settings
より、A4 SSH→Enable でFinish

手持ちの他のPCのSSHクライアントから

sudo ssh pi@192.168.0.25

で接続できるかを確認します。

PyCharm

Ubuntu14.04上でのPyCharmインストール

sudo add-apt-repository ppa:webupd8team/java
sudo apt-get update
sudo apt-get install oracle-java8-installer

PyCharmをダウンロードしたフォルダに移動して

sudo tar -xvzof pycharm-professional-4.0.4.tar.gz -C /opt

で/optに解凍

/opt/pycharm-4.0.4/bin/pycharm.sh

で起動

MacOS Windowsでのインストール

Javaを入れて
ダウンロードして普通にインストールすれば大丈夫。

PyCharm上での操作

リモート実行環境の整備

新規プロジェクトの作成 f:id:izm_11:20150219011136j:plain PurePython f:id:izm_11:20150219011153j:plain Pythonランタイムをリモート(RasberryPi上に) f:id:izm_11:20150219011208j:plain プロジェクト名やIP、ユーザとパスワードの設定 f:id:izm_11:20150219011233j:plain 新規pythonfileを追加 (main.py) f:id:izm_11:20150219011920j:plain f:id:izm_11:20150219011948j:plain

print 'hello'

を追加して f:id:izm_11:20150219011953j:plain ctrl+shit+F10(デバッグ実行)

[Errno 2] No such file or directory

と、エラーが出る事を確認する。 これは、手元のPCの自分のユーザ名と、Rasbian上のパスが異なるために、そんなパスが無いと言うエラーが起るためです。

エラーを解消するために、パスの読み替え設定をします。

Tools→Development→Configuration f:id:izm_11:20150219014318j:plain add f:id:izm_11:20150219014430j:plain 適当なサーバ名を決めて、SFTPを選択 f:id:izm_11:20150219014439j:plain ConnectionタブでSFTP用の設定を行う f:id:izm_11:20150219014528j:plain 中央のMappingタブでパスの読み替えを設定する。
今回は今のプロジェクトディレクトリを /home/pi/Desktopに置き換えました。 f:id:izm_11:20150219014546j:plain Tools→Deployment→Upload to rasberry piを選んでアップロード f:id:izm_11:20150219014819j:plain また、Automatic Uploadにチェックを入れます。

改めてctrl+shift+F10で実行すると

hello

Process finished with exit code 0

f:id:izm_11:20150219015033j:plain と、無事実行されることが確認できます。 Automatic Uploadの効果を確認するために print文の中身を書き換えてctrl+shift+F10を押して、出力される文が変わっている事を確認します。

RPi.GPIOライブラリの動作確認

import RPi.GPIO as GPIO
print GPIO.VERSION
print 'hello'

と書き換えて実行すると、0.5.xxxのような結果が見えます。 これでRaspberry上のGPIOライブラリが動かせている事が確認出来ます。

もし、GPIO. とピリオドを打った後に f:id:izm_11:20150219015616j:plain こういった補完候補が出てこない場合は、以下の設定を行います。

この補完候補が出るおかげで、はじめて触るライブラリでも、なんとなく書けて素晴らしいです!

ライブラリの入力補完

File→Settings→Project→Project Interpreter

f:id:izm_11:20150219020028j:plain 現在Rasberry pi上のPythonにインストールされていて、PyCharmの入力補完が効くライブラリ(パッケージ)一覧を見ることが出来ます。右上の「」を押して RPi.GPIOを検索してInstall Packageを押すことでリモートのRaspberry pi上にRPi.GPIOが(入っていなければ)入り、PyCharm上での入力補完も正しく働きます。 f:id:izm_11:20150219020206j:plain また、何はともあれpython-pipは最新にアップデートしましょう。 f:id:izm_11:20150219020612j:plain

オマジナイ

gpioを叩く場合は、gpioのある /dev/memにアクセスする必要があり、これは必然的にroot権限が無くてはいけないです。
普通に実行するならsudoを付けたら良いのですが、PyCharm上のリモート実行でsudo付きで実行する設定が見当たらなかった為、以下のおまじないをスクリプト内に書きます。
rootで実行されていなかった場合、sudo をつけて再実行するコードです。(piユーザがパスワードなしでsudo出来るから取れる手段ですね…)

# -*- coding: utf-8 -*-
#!/usr/bin/python

#ここから
import os
import sys

if os.geteuid() != 0:
    print "not root"
    os.execvp("sudo", ["sudo"] +["python"]+ sys.argv)
    print "nevert reach here!"
#ここまで

#以降普通のコード
import RPi.GPIO as GPIO

実際の動作

後はお好みで書いていきましょう。
RPi.GPIOはpi2発売に合わせて、現在かなりアグレッシブに開発が進んでいます。

不審な挙動があったら開発サイトを確認して同様の症状が起きていないか確認するのも大事だと思います。

例えばLEDを点滅させる場合は、 #22にLEDの正極と抵抗、GNDにLEDのGNDを繋いで

# -*- coding: utf-8 -*-
#__author__ = 'izm'
#!/usr/bin/python

import os
import sys

if os.geteuid() != 0:
    print "not root"
    os.execvp("sudo", ["sudo"] +["python"]+ sys.argv)
    print "never reach here"
import RPi.GPIO as GPIO
import time

print GPIO.VERSION
GPIO.setwarnings(False)
GPIO.setmode(GPIO.BCM)
led = 22

GPIO.setup(led, GPIO.OUT)
count = 0
while count < 5:
    GPIO.output(led, 1)
    time.sleep(1)
    GPIO.output(led, 0)
    time.sleep(1)
    count += 1

print "end script"

こんな感じで確認できます。