VNC環境とRaspberry Piで簡単電子工作(4)

2017年6月28日(水)
青柳 良介福田 紘也

はじめに

前回は、Raspberry Piを使ったPWM出力を解説しました。LEDとブザーとサーボを使って、段階的な制御を行いました。

今回は、回路を1つ(回路3)作成し、アナログデジタル変換(A/D変換)を使ったアナログ入力をテーマに解説します。Raspberry PiにはA/D変換の仕組みがないため、アナログ値を取得するセンサーを接続しただけではアナログ値を読み取れません。

そこで、A/Dコンバータを使ってA/D変換を行います。今回はSPI通信ができる「MCP3008」というA/Dコンバータを使います(図1)。参考までに、SPI通信は「Serial Peripheral Interface」の頭文字をとっており、少ないピンでデータをやり取りする低速インタフェースのことを指します。

MCP3008では1~8までのピンを各センサー(入力デバイス)のチャンネル(CH)として使い、9~16までのピンをRaspberry Piへの接続として使います。Raspberry Pi側には、以下のように接続します。

Vdd→pin1
Vref→(pin1)
AGND→(pin25)
CLK→pin23(GPIO11/SCLK)
Dout→pin21(GPIO9/MISO)
Din→pin19(GPIO10/MOSI)
CS/SHDN→pin24(GPIO8/CE0#)
DGND→pin25

各CHに接続されたセンサーからのアナログ値がMCP3008でデジタル値に変換されるという仕組みです。今回はLEDとMCP3008と各センサーを用いてアナログ入力を制御します。

LEDについては前回作成した回路1を用い、MCP3008と各センサーについては新たに作成する回路3を用います。

用意するもの

回路3を作るために、下記のパーツを準備します。

  • Raspberry Pi 3B
  • microSDカード(OSインストール済みのもの。第1回を参照)
  • PC
  • A/Dコンバータ MCP3008
  • 半抵抗ボリューム 10kΩ[103]
  • 温度センサー IC LM35DZ
  • 照度センサー NJL7502L
  • 焦電人感センサー SB612A
  • ジャンパーワイヤ オス-メス
  • ブレッドボード

また、第2回で作成した回路1は、下記のパーツを使用しました(詳細は第2回を参照)。

  • LED
  • 押しスイッチ
  • ブレッドボード
  • ジャンパーワイヤ オス-メス
  • 抵抗抵抗(330Ω×2:LED側/10kΩ:スイッチ側)

アナログ入力を制御しよう

シミュレーションしてみよう

まずは、シミュレーションをしてみましょう。fritzingを起動して、以下のような配線図を作成します(fritzingのダウンロードとインストール、使い方については第1回を参照)

電子工作をしてみよう

配線図で正しくシミュレーションができたら、電子工作を行います。前回の内容に付け加える形で今回の内容を組み立てていきます。

プログラミングをしてみよう①~VNC環境の立ち上げ~

まず、以下の手順でVNC環境を立ち上げましょう(詳細は第1回を参照してください)。

  1. Raspberry PiにmicroSDカードを挿入し、LANをつないで電源を入れる
  2. PC上でTera Termを起動させ、ホスト名にIPアドレスを入力する
    (※この時、上手く接続できない場合はIPアドレスが変わっている可能性があるため、IPアドレスを確認してください)
  3. 認証画面が表示されたらユーザー名:Pi、パスワード:raspberryを入力する
  4. ターミナルが表示されたら、以下のコマンドでVNCサーバを立ち上げる
    $ tightvncserver
  5. UltraVNC Viewerを起動し、IPアドレスとポート番号を入力する。「connect」ボタンを押して第1回で設定した8文字以下のパスワードを入力する

プログラミングをしてみよう②~半抵抗ボリュームを使った制御~

VNS環境が立ち上がったら、プログラミングを進めて行きます。はじめに、半抵抗ボリュームを使った制御を行います。半抵抗ボリュームはつまみを回すことで抵抗を変化させることができます。

今回は、10kΩの最大抵抗値を持つ半抵抗ボリュームを使うため、0Ω~10kΩまで変化させることができます。半抵抗ボリュームをMCP3008のCH0に接続しているので、3.3VでRaspberry Piから供給された電圧に対して任意の抵抗値をとることができ、MCP3008にかかる電圧が変化します。

まずは、電圧の変化を見ていきましょう。nanoエディタを立ち上げます。

$ nano adc.py

nanoエディタ上で以下のプログラムを入力し、[Ctrl]+[X]で保存します。

from gpiozero import MCP3008

adc = MCP3008(channel=0)

while True:
	print(adc.value)

ターミナル画面に戻った後、以下のコマンドを入力すると画面上に数値が表示され、つまみを回すと数値が変化します。

$ sudo python adc.py

プログラムを終了するときは、[Ctrl]+[C]を入力してください。

このプログラムではMCP3008のモジュールを使って、MCP3008のCH0から変数adcとして数値を読み取っています。そして、読み取った数値はプリント関数により画面に表示されます。

つまみを回すと数値が変化しますが、これはつまみというアナログ入力がMCP3008によりデジタル処理されていることを示します。

次に、この仕組みを使ってLEDをPWM制御します。nanoエディタ上で以下のプログラムを入力します。

from gpiozero import MCP3008, PWMLED
from signal import pause

adc = MCP3008(channel=0)
led = PWMLED(17)

led.source = adc.values

pause()

ここでは、source/valuesで出力側(LED)のソースを入力側(MCP3008)の数値に設定しています。これにより、入力側でアナログ変化する数値をPWMLEDでデジタル出力できるようになります。

プログラムを実行した後、つまみを回すとLEDの強度を調整できます。半抵抗ボリュームにより変化した電圧がRaspberry Piにデジタル値として入力され、そのデジタル値に相当する強度でLEDが光るという仕組みです。

実機をお持ちでない方のために、実際の動作を確認できる動画を用意しました。ぜひこちらを参考にイメージしていただければと思います。

プログラミングをしてみよう③~温度センサーを使った制御~

今回は温度センサーとしてLM35DZを使います。LM35DZは1℃あたり10mVを出力する温度センサーです。ダイオードの原理を用いて電位差が起きると一定方向に電気を流す性質があり、ある特定の条件(環境と電源)では温度と電位差が比例関係になります。

まずは、温度センサーから室内の温度を読み取ってみましょう。nanoエディタ上で以下のプログラムを入力します。

from gpiozero import MCP3008
from time import sleep

def convert_temp(gen):
    for value in gen:
        yield (value * 3.3 - 0.5) * 10

adc = MCP3008(channel=2)

for temp in convert_temp(adc.values):
    print('The temperature is', temp, 'C')
    sleep(1)

プログラムを実行すると画面上に温度が表示されるようになります。ここではMCP3008にかかる電位差を温度に変換するための計算式をプログラムに入れており、これにより温度が表示されます。

次に、特定の温度以上になるとLEDが光るプログラミングを行います。nanoエディタ上で以下のプログラムを入力します。

from gpiozero import MCP3008, LED
from time import sleep

tmp = MCP3008(channel=2)
led = LED(17)
 
while True:
    temperature = (tmp.value * 3.3 - 0.5)*10
    if temperature >24:
        led.on()
    else:
        led.off()
    print('{:.1f}'.format(temperature), 'C')
    sleep(0.1)

ここでは、温度センサーが24℃以上を返したときにLEDを光らせるようにしています。プログラムのLED部分については第2回をご参照ください。

このように、簡単に温度と紐づけた制御ができるため、サーボやブザー等の出力も組み合わせることで適用の幅がさらに広がります。

プログラミングをしてみよう④~照度センサーを使った制御~

照度センサー NJL7502Lは分光感度が人間の視覚に近いフォトトランジスタです。暗い状態では電流を流さず、明るい状態で電流を流す電気特性を持つ素子です。

まずは、照度センサーを使って照度をデジタル変換します。nanoエディタ上で以下のプログラムを入力します。

from gpiozero import MCP3008

light = MCP3008(channel=1)

while True:
	print(light.value)
	sleep(1)

プログラムを実行すると1秒ごとに数値が表示されます。照度をデジタルに変換した数値なので、明るくなると大きな値に変化します。

次に、明るさを判定できる仕組みを作りましょう。nanoエディタ上で以下のプログラムを入力します。

from gpiozero import MCP3008
from time import sleep

light = MCP3008(channel=1)

while True:
    if light.value 

ここでは0.037の数値を境にして、その数値より小さいと暗い、その数値以上だと明るいと定めています。数値の境は照度センサーの数値を見ながら調整しましょう。ライトを当てると数値が0.037以上になり、画面上に「Light」と表示されます。

続けて、暗くなった時にLEDが光るようにしてみましょう。nanoエディタ上で以下のプログラムを入力します。

from gpiozero import MCP3008, LED
from time import sleep

light = MCP3008(channel=1)
led = LED(17)

while True:
    if light.value 

先ほど定めた0.037の境界に対して、その数値より小さいとLEDが光るように制御します。

実機をお持ちでない方のために、実際の動作を確認できる動画を用意しました。ぜひこちらを参考にイメージしていただければと思います。

最後に、照度に合わせてPWMLEDの強度が変化するようにします。nanoエディタ上で以下のプログラムを入力します。

from gpiozero import MCP3008, PWMLED
from signal import pause

light = MCP3008(channel=1)
led = PWMLED(17)

led.source = light.values

pause()

ここでは、半抵抗ボリュームのパートでも使用したsource/valuesにより、出力側のソースを入力側の数値に設定しています。プログラムを実行すると、照度センサーの数値に応じて、LEDの強度が変化するようになります。

プログラミングをしよう⑤~人感センサーを使った制御~

焦電人感センサーは焦電赤外線センサーとも呼ばれます。基本的な原理としては、センサーに入る赤外線の変化を検知します。検知エリア内に人などの熱源があっても動きがなければ動作しません。感度や検知出力保持時間などを調整することで様々な用途で使うことができます。

まずは、どのように検知しているのかを見ていきましょう。nanoエディタ上で以下のプログラムを入力します。

from gpiozero import MCP3008
from time import sleep

motion = MCP3008(channel=3)

while True:
	print(motion.value)
	sleep(1)

プログラムを実行すると画面上に数値が表示され、検知すると数値が大きく変動します。温度センサーや照度センサーの場合に比べてデジタルに近い挙動で数値が動きますが、これは人感センサーの特性上、検知していない時をオフ、検知した時をオンのように取り扱うためです。

次に、動きを判定できる仕組みを作りましょう。nanoエディタ上で以下のプログラムを入力します。

from gpiozero import MCP3008
from time import sleep

motion = MCP3008(channel=3)

while True:
    if motion.value 

ここでは、0.7の数値を境に、その数値より小さいと停止、その数値以上だと動作と定めています。動きを検知すると数値が0.7以上になり、画面上に「move」と表示されます。

続けて、動きを検知した時にLEDが光るようにしてみましょう。nanoエディタ上で以下のプログラムを入力します。

from gpiozero import MCP3008, LED
from time import sleep

motion = MCP3008(channel=3)
led = LED(17)

while True:
    if motion.value 

先ほど定めた0.7の境界に対して、その数値以上だとLEDが光るように制御します。

実機をお持ちでない方のために、実際の動作を確認できる動画を用意しました。ぜひこちらを参考にイメージしていただければと思います。

おわりに

いかがでしたか? 今回は、アナログ入力をテーマにセンサーとMCP3008を使った制御を行いました。センサーによって動作原理や数値は異なりますが、MCP008のモジュールを使ってプログラミングすることで、どのセンサーも簡単に制御できることを実感いただけたのではないでしょうか?

次回は、システム化をテーマに、これまでの内容を組み合わせた簡単なシステムを作りたいと思います。お楽しみに!

Blooomin代表。半導体ベンチャーや米系通信機器メーカーを経て、組み込みシステムのコンサルディングからフィジカル・コンピューティングのコンテンツ開発などに従事。ハードやソフトにおける設計から保守までの勘所を横断的に網羅しております。
Blooomin:https://blooomin.com
S&F PARTNERS副社長。素材メーカーを経てコンサルティング会社で事業開発に従事。その後、ベンチャーにてIoTサービスの企画・運営。現在はロボットプログラミング教室の運営やIoTサービスの企画・開発を展開。S&F PARTNERS:http://www.sf-partners.jp/

連載バックナンバー

Think ITメルマガ会員登録受付中

Think ITでは、技術情報が詰まったメールマガジン「Think IT Weekly」の配信サービスを提供しています。メルマガ会員登録を済ませれば、メルマガだけでなく、さまざまな限定特典を入手できるようになります。

Think ITメルマガ会員のサービス内容を見る

他にもこの記事が読まれています