ラズパイ WebIOPi


WebIOPi は、ラズパイの GPIO をWEBブラウザから制御できるフレームワークです。
本来は、RaspberryPi 1 です。
RaspberryPi 2 に対応するためのパッチが公開されています。

インストール

$ cd /tmp
$ wget http://sourceforge.net/projects/webiopi/files/WebIOPi-0.7.1.tar.gz
$ tar xvzf WebIOPi-0.7.1.tar.gz
$ cd WebIOPi-0.7.1

RaspberryPi 2 用に変更する

$ wget https://raw.githubusercontent.com/doublebind/raspi/master/webiopi-pi2bplus.patch
$ patch -p1 -i webiopi-pi2bplus.patch

ビルドする

$ sudo ./setup.sh
 ...
Do you want to access WebIOPi over Internet ? [y/n] <== y
 ...
WebIOPi successfully installed
 ...

起動スクリプトを設定する

$ cd /tmp
$ wget https://raw.githubusercontent.com/neuralassembly/raspi/master/webiopi.service
$ sudo mv webiopi.service /etc/systemd/system/

起動

$ sudo systemctl start webiopi

確認
WEBブラウザで下記にアクセスする

http://raspberrypi.local:8000/ 

認証画面が表示されるので、
ユーザー名は「webiopi」パスワードは「raspberry」を入力する。
20160606_webiopi_auth

WebIOPi Main Menu が表示されれば、OKです。
20160606_webiopi_main

前回の方法 では、26ピンしか表示されないが、今回は、40ピンが表示されます。
20160608_webiopi_40pin

GPIOにLEDをつけて、オンオフしてみる。

参考
「Raspberry Piで学ぶ電子工作」補足情報
p.227:WebIOPiのバージョンとインストール


ラズパイ WebIOPi (非推奨)


WebIOPi は、ラズパイの GPIO をWEBブラウザから制御できるフレームワークです。
本来は、RaspberryPi 1 です。
RaspberryPi 2 に対応するためには、若干の変更が必要です。

この方法はなく パッチを使う方法 をお勧めします。

ダウンロード
公式サイトからダウンロードする
6月時点の最新版は 0.7.1 です。

インストール

$ tar xvzf WebIOPi-0.7.1.tar.gz
$ cd WebIOPi-0.7.1

RaspberryPi 2 用に変更する

$ nano python/native/cpuinfo.c
if (strcmp(hardware, "BCM2708") == 0)
⬇︎
if (strcmp(hardware, "BCM2709") == 0)

RaspberryPi 2 用に変更する

$ nano python/native/gpio.c
#define BCM2708_PERI_BASE 0x20000000
⬇︎
#define BCM2708_PERI_BASE 0x3f000000

ビルドする

$ sudo ./setup.sh
...
Do you want to access WebIOPi over Internet ? [y/n] <== y
...
WebIOPi successfully installed
...

サービスデーモンをリロードする

$ sudo systemctl daemon-reload

起動

$ sudo /etc/init.d/webiopi start

確認
WEBブラウザで下記にアクセスする

http://raspberrypi.local:8000/ 

認証画面が表示されるので、
ユーザー名は「webiopi」パスワードは「raspberry」を入力する。
20160606_webiopi_auth

WebIOPi Main Menu が表示されれば、OKです。
20160606_webiopi_main

GPIO Header をクリックすると、ピン配置が表示される。
RaspberryPi 2 では 40ピンあるが、RaspberryPi 1 の 26ピンしか表示されない。
20160606_webiopi_gpio_header

GPIOにLEDをつけて、オンオフしてみる。

参考
第30回「WebIOPiでIoT!(1)導入&Lチカ編〜ブラウザからGPIOを操作しよう」


ラズパイ WiringPi 連続回転サーボ


20160505_raspi_servo

LED明暗 に続いて、ラズパイで WiringPi を使って、連続回転サーボを制御します。
LED明暗と同様に、ハードウェア PWM を使います。

設定
設定には、5つの関数を使用します。
それぞれ、ラズパイの BCM2835 / BCM2836 のレジスタと関連しています。

pinMode
pin のモードとして、PWM_OUTPUT を設定します。
これを最初に設定しないと、以降の関数が効かなかったです。

pwmSetMode
PWMのモードを設定します。
PWM には、2つのモードがあります。
バランスド (balanced) と マーク・スペース (mark:space) です。
スペースは周期で、マークはパルス幅です。
バランスドは、デューティ比 50% です。
20160530_wiringpi_pwm_mode

サーボに必要なのは、下記のような信号なので、マーク・スペースに設定します。
20160425_servo_control_2

pwmSetClock
クロックの分周比を設定します。
PWMのクロックは、19.2 MHz です。
サーボでは、パルス幅 ±0.5ms で制御します。
制御の刻みを 100 とすると、分周比は 96 です。
0.5ms / 100 = 5μs (200 KHz)
19.2 MHz / 200 KHz = 96

pwmSetRange
PWMの周期となるクロック数を設定します。
サーボのパルス周期は、20ms なので、クロック数は 400 です。
20ms / 5μs = 4000

pwmWrite
パルス幅となるクロック数を設定します。
1.5ms のときは、300 です。
1.5ms / 5μs = 300

動作確認
サーボには3本の線があります。
赤を Pin4 (+5v)、黒を Pin6 (GND)、白を Pin12 (GPIO18) に接続します。

wiringpi_servo_pulse.py (github)
パルス幅のクロック数 を 200、290、300、310、400 と変化させて、
時計周り(高速)、時計周り(低速)、停止、反時計周り(低速)、 反時計周り(高速) となることを確認します。

wiringpi_servo_speed.py (github)
パルス幅で指定するのは使い難いので、速度で指定するようにしました。
速度の範囲は、−100 から 100 です。

オシロでの測定
周期 20ms、パルス幅 1.5ms となっています。
RPi.GPIO では、ジッタ が見られましたが、今回は綺麗です。

周期 20ms
20160530_wiringpi_pwm_20ms

パルス幅 1.5ms
20160530_wiringpi_pwm_1_5ms

参考
Raspberry Pi Specifics – Wiring Pi
・void pinMode (int pin, int mode)
pin に対して、mode として、INPUT、 OUTPUT、 PWM_OUTPUT、または GPIO_CLOCK のいずれかを設定します。

・pwmSetMode (int mode)
PWMジェネレータは、 2つのモードで実行することができます。
バランスド (balanced) と マーク・スペース (mark:space) です。
マーク・スペースが伝統的な方式ですが、ラズパイのデフォルトのモードはバランスドです。
mode にパラメータを設定することで、モードを切り替えることができます。
PWM_MODE_BAL か PWM_MODE_MS です。

・pwmSetRange (unsigned int range)
PWMジェネレータ内のレンジ・レジスタを設定します。
デフォルトは1024です。

・pwmSetClock (int divisor)
PWMクロックの分周比を設定します。

・void pwmWrite (int pin, int value)
指定されたピンのPWMレジスタに値を書き込みます。

Control Hardware PWM frequency – Raspberry Pi
PWMクロックは19.2 MHz です。
pwmSetClock の値で分周されます。
分周された周波数で、PWMカウンタが増加します。


ラズパイ WiringPi LED明暗


20160510_raspi_led

LED点滅 に続いて、ラズパイで WiringPi を使ってLEDを徐々に明くしたり暗くしたりします。

WiringPi では、ハードウェア PWM が使えます。
ラズパイ2では、2チャネルあり、1つは P32 (GPIO12) か P12 (GPIO18)、もう1つは P33 (GPIO13) か P35 (GPIO19) です。

P12(GPIO18) と P6(GND) の間に、LEDと1KΩの抵抗を直列に入れます。
20160510_raspi_led_gpio17

wiringpi_led_fade.py

import wiringpi
import time
PIN = 18 
INTERVAL = 0.05
MIN_BRIGHTNESS = 0
MAX_BRIGHTNESS = 1023
bright = 0
amount = 16
wiringpi.wiringPiSetupGpio()
wiringpi.pinMode(PIN, wiringpi.PWM_OUTPUT)
try:
	# endless loop
	while True:
		print bright
		wiringpi.pwmWrite(PIN, bright)
		bright = bright + amount;
		if bright <= MIN_BRIGHTNESS:
			bright = MIN_BRIGHTNESS
			amount = -amount
		elif bright >= MAX_BRIGHTNESS:
			bright = MAX_BRIGHTNESS
			amount = -amount
		time.sleep(INTERVAL)
except KeyboardInterrupt:
	# exit the loop, if key interrupt
	pass

参考
Core Functions – Wiring Pi
・void pinMode (int pin, int mode)
pin に対して、mode として、INPUT、 OUTPUT、 PWM_OUTPUT、または GPIO_CLOCK のいずれかを設定します。
PWM_OUTPUT は、WiringPi 1ピン (BCM_GPIO 18) のみサポートされています。
GPIO_CLOCK は、WiringPi 7ピン (BCM_GPIO 4) のみサポートされています。

・void pwmWrite (int pin, int value) ;
指定されたピンのPWMレジスタに値を書き込みます。
ラズパイ1はオンボードPWMピンを1つ持っています。
Wiring Pi 1ピン (BMC_GPIO 18、物理ピン12) です。
value の範囲は0〜1024です。
他のPWMデバイスは、他のPWM範囲を有することができます。

Raspberry Piで学ぶ電子工作
wiringPiを用いたハードウェアPWM信号によるサーボモーターの制御
Raspberry Pi Model B ではハードウェアPWM信号はGPIO 18からの1つのみしか出力できなかったのですが、Raspberry Pi Model B+以降(Raspberry Pi 2 Model B含む)では、ハードウェアPWM信号を2つ出力できます。
1つ目のPWM0はGPIO 18かGPIO 12のどちらかから、2つ目のPWM1はGPIO 13かGPIO 19のどちらかから出力できます。


ラズパイ WiringPi LED点滅


20160510_raspi_led

ラズパイで WiringPi を使ってLEDを点滅する。
ラズパイの GPIO 制御は RPI.GPIO が定番ですが。
今回は WiringPi を使います。

WiringPi はラズパイ1の BCM2835 のために、C言語で書かれた GPIO のライブラリです。
適切なラッパーにより Python などの言語に対応しています。
Arduino のライブラリに似せて設計されています。
ラズパイ2の BCM2836 にも対応しています。

インストール

(Python 開発ライブラリ)
$ sudo apt-get install python-dev
(WiringPi 本体)
$ sudo apt-get install wiringpi
(Python ラッパー)
$ sudo pip install wiringpi2

確認
バージョンの確認

$ gpio -v

gpio version: 2.32

WiringPi のピン番号には、(1) 物理ピン (2) BCM GPIO ピン (3) wiringPi ピンの3種類があり、ちと面倒です。
デフォルトは wiringPi ピンです。
このへんの対応は、下記のコマンドで表示できます。

$ gpio readall

20160525_wiringpi_readall

gpio コマンドでLED点滅
11番ピン(GPIO 17、wPi 0)と6番ピン(GND)の間に、LEDと1KΩの抵抗を直列に入れます。
20160510_raspi_led_gpio17

$ gpio mode 0 out
(点灯)
$ gpio write 0 1
(消灯)
$ gpio write 0 0

Python でLED点滅 (1)

$ sudo python
>> import wiringpi
>> wiringpi.wiringPiSetup()
>> wiringpi.pinMode(0, wiringpi.OUTPUT)
(点灯)
>> wiringpi.digitalWrite(0, wiringpi.HIGH)
(消灯)
>> wiringpi.digitalWrite(0, wiringpi.LOW)
>>> exit()

Python LED点滅 (2)
1秒間隔で点滅する
wiringpi_led_blink.py

import wiringpi
import time
wiringpi.wiringPiSetupGpio()
wiringpi.pinMode(17, wiringpi.OUTPUT)
while True:
	wiringpi.digitalWrite(17, wiringpi.HIGH)                 
	time.sleep(1)
	wiringpi.digitalWrite(17, wiringpi.LOW)            
	time.sleep(1)

参考
Setup – Wiring Pi
・wiringPiSetup (void)
WiringPi 方式のピン番号を使用して、WiringPi を初期化します。
これは、Broadcom の GPIO のピン番号 16 に対して、仮想のピン番号 0 をマッピングする方式です。
この関数は、 root権限で呼び出す必要があります。

・wiringPiSetupGpio (void)
Broadcom の GPIO のピン番号を使用して、WiringPi を初期化します。
この関数は、 root権限で呼び出す必要があります。

Core Functions – Wiring Pi
・void pinMode (int pin, int mode)
pin に対して、mode として、INPUT、 OUTPUT、 PWM_OUTPUT、または GPIO_CLOCK のいずれかを設定します。
PWM_OUTPUT は、WiringPi 1ピン (BCM_GPIO 18) のみサポートされています。
GPIO_CLOCK は、WiringPi 7ピン (BCM_GPIO 4) のみサポートされています。

・void digitalWrite (int pin, int value)
pin は OUTPUT として設定されている必要があります
pin に value として、HIGH (1) または LOW (0) の値を書き込みます。
WiringPi では、0(ゼロ) は LOW となり、0(ゼロ) 以外の数値は HIGH として扱います。


ラズパイ PythonでLED点滅


20160510_raspi_led

ラズパイで Python プログラムで LEDを点滅します。
Python の GPIO 制御として、RPI.GPIO を使用します。

P11(GPIO17) と P6(GND) の間に、LEDと1kΩの抵抗を直列に入れます。
20160510_raspi_led_gpio17

rpi_led_blink.py

import RPi.GPIO as GPIO
import time
PIN = 11
INTERVAL = 1
GPIO.setmode(GPIO.BOARD)
GPIO.setup(PIN, GPIO.OUT)
try:
	while True:
		GPIO.output(PIN, GPIO.LOW)
		time.sleep(INTERVAL)
		GPIO.output(PIN, GPIO.HIGH)
		time.sleep(INTERVAL)	
except KeyboardInterrupt:
	pass
GPIO.cleanup()

GPIO.setwarnings
すでにGPIOを使っている場合に、下記のようなワーニングが出力されます。

RuntimeWarning: This channel is already in use, continuing anyway.

TESTING A CONNECTED LED IN PYTHON にある GPIO.setwarnings(False) は、これを出力しないように抑止する設定です。
なくても、ワーニングが出るだけなので、気にしない。

参考
CONNECTING AN LED WITHOUT A BREADBOARD
TESTING A CONNECTED LED IN PYTHON
RPi.GPIO basics 3 – How to Exit GPIO programs cleanly, avoid warnings and protect your Pi


ラズパイ シェルでLED点灯


P11(GPIO17)とP6(GND)の間に、LEDと1kΩの抵抗を直列に入れます。
20160510_raspi_led

$ sudo su -
# echo "17" > /sys/class/gpio/export
# echo "out" > /sys/class/gpio/gpio17/direction
# echo "1" > /sys/class/gpio/gpio17/value
# echo "0" > /sys/class/gpio/gpio17/value
...
# exit

参考
CONNECTING AN LED WITHOUT A BREADBOARD


ラズパイ sumobot turn


sumobot turn は、Sumobot が左回転と右回転を繰り返すプログラムです。
sumobot_turn.py と sumobot_turn_check.py の2つがあります。
後者は、前者に、ピンの状態をチェックする処理を追加したものです。

インストール
Github から持ってきて、ラズパイの好きな場所 (例えば /home/pi/sumobot/ ) に置きます。

起動

$ sudo python /home/pi/sumobot/sumobot_turn.py

Sumobot が左回転と右回転を繰り返します。

注意
無線LANでログインして起動してください。
有線LANだと、LANケーブルが絡まります。

自動起動
電源を投入したときに、自動的に起動するようにします。
しかし、常に Sumobot が動き出すと、扱いにくいのです。
sumobot_turn_check.py を使用します。
これは、特定のピン (P13) の状態をチェックして、Sumobot を動かさずに、プログラムを終了する処理を追加したものです。

自動起動するには、/etc/rc.local を変更します。
exit 0 の前に、1行追加します。

$ sudo nano /etc/rc.local
...
# add
python /home/pi/sumobot/sumobot_turn_check.py
exit 0 

ハードの設定
P13(GPIO27) と P17(3.3V) の間に10KΩの抵抗を入れます。
プログラムが自動起動して、Sumobot は動き続けます。
P17(3.3V) に代わりに P14(GND) につなぐと、プログラムは終了して、Sumobot Jr は停止したままです。
20160505_raspi_circuit_p13


ラズパイ Sumobot Jr


20160505_raspi_completion

Arduino に続いて、ラズパイで Sumobot Jr を制御します。

部品
Raspberry Pi 2 B
モバイルバッテリ
・連続回転サーボ SM-S4303R x 2個
16mm ボール
・ネジとナット M2.6x10mm x 12本、M2.6x15mm x 2本
・結索バンド 20cm x 2本
・ゴムバンド #25 3mm幅 x 2本
・線材 少々

加工品
レーザー加工機
・車体 (設計データ) Arduino版と同じです
20160501_sumobot_laser_body

3Dプリンタ
・ボールキャスタ (設計データ) Arduino版と同じです
20160501_sumobot_3d_printer_ball_caster

サーボの動作確認
サーボが所望の動作をするか確認します。
特に、停止を指定したときに、ちゃんと停止しているか。

参考
ラズパイ WiringPi 連続回転サーボ
ラズパイ 連続回転サーボ

車体の組み立て
車体の作り方は、Arduino版 と同じです。
違うのは、上板に Arduino ではなくラズパイを固定すること。
20160505_raspi_upper

配線
20160505_raspi_curuit

(1) オスとメスのジャンパー線を半田付けして、オス2口とメス1口のジャンパー線にします。
20160505_raspi_wiring

(2) モバイルバッテリーを車体に入れます。
モバイルバッテリーの上下に厚紙を入れると、ほどよい感じで固定されます。
20160505_raspi_battery_back

(3) ラズパイと2個のサーボを結線します。ラズパイとモバイルバッテリーを結線します。
20160505_raspi_battery_wire

プログラム
ラズパイにプログラム sumobot_turn を設定します。
電源を入れます。
Sumobot Jr が左回転と右回転を繰り返せば、OKです。

課題
スペーサが3mm厚では足りなかった。
10mmくらい必要です。

(1) 上板にラズパイを固定すると、コネクタの足があたり、基板がしなります。
どうやら、木材のスペーサだと、締め付けると、潰れるようです。
20160505_raspi_problem_1

(2) ラズパイに電源ケーブルを挿す時に、横板が邪魔になり、ケーブルが挿さりません。
応急処置として、横板を切断しました。
20160505_raspi_problem_2_2

YouTube Preview Image

ラズパイ 連続回転サーボ (speed)


20160505_raspi_servo

ラズパイ 連続回転サーボ (duty) に続いて、ラズパイで連続回転サーボを制御します。

ServoSpeed クラス
RPi.GPIO の PWM モードでは、PWMのパルス幅を、デューティ比 で指定します。
デューティ比の範囲は、5.0 から 10.0 です。

これでは使い難いので、速度で指定するクラスを作成しました。
速度の範囲は、−100 から 100 です。
duty のときの確認でわかったように、停止の指定が、計算値よりも少しずれています。
そこで、オフセットを設定して、速度 0 を指定した時に、停止するようにしました。

ソースは、github で公開しています。
rpi_servo_speed.py

確認
試してみたことろ、オフセット=0、速度=0 のときは、微速で回転して、停止しませんでした。
速度 -10 から -26 で、停止しました

オフセットを−18に設定して、速度を -100、-10、0、10、100 と変化させます。
時計周り(高速)、時計周り(低速)、停止、反時計周り(低速)、 反時計周り(高速) となることを確認しました。

課題
停止を指定しても、クリッと音がして、サーボが微動することがあります。
これは、パルスがジッタを持ってるためと思われます。
今回の用途では、割り切って、このままで使用します。