Arduinoにスイッチサイエンス/フルカラーシリアルLEDテープを接続する

スイッチサイエンス/フルカラーシリアルLEDテープ

スイッチサイエンス社から発売されているフルカラーシリアルLEDテープは、信号線1本でフルカラーを制御できるLEDモジュールである。Adafruit製のArduino用ライブラリを流用可能で、特別なフォーマットのシリアル通信により1本の信号線でRGBを制御可能である。

Arduinoに接続する

フルカラーシリアルLEDテープは、テープの両端にGND, Do, Vcc(+5V)の3つの端子を備えている。各テープの両端同士を接続することでテープを延長した上で発光させることが可能である。GNDとVccはArduinoのGNDとVccに接続し、DoはArduinoのDigital Inputに接続する。今回は測距センサGP2Y0A710K0Fが出力した距離データに連動してLEDを点灯させるという構成とした。

フルカラーシリアルLEDテープ構成図

Adafruit製Arduino用ライブラリの組み込み

Arduinoは外部のライブラリを組み込むことが可能である。外部のライブラリを組み込むためには、「スケッチ」->「ライブラリを使用」から「ライブラリをインストール」を選択する。ライブラリをインストールすると、スケッチなどが保存されるのと同じディレクトリ内にライブラリファイルがコピーされる。

ライブラリをインストール

スケッチ

測距センサGP2Y0A710K0Fからデータを取得する方法はこちら。Adafruitライブラリは、RGBそれぞれ値を指定してLEDの色を決定することができるので、測距センサで計測した値が近い(距離が短い)ほど、LEDが赤く光るという制御している。

// ライブラリの読み込み
#include <Adafruit_NeoPixel.h>
#include <avr/power.h> // 電力制御
// テープLEDの数
#define NUMPIXELS 8
// ピンポート
const int gp2y0a710kPin  = 0; // アナログ
const int neoPixelPin    = 6;// デジタル

Adafruit_NeoPixel pixels = Adafruit_NeoPixel(NUMPIXELS, neoPixelPin, NEO_GRB + NEO_KHZ800);

void setup() {
  // put your setup code here, to run once:

  #if defined (__AVR_ATtiny85__)
  if (F_CPU == 16000000) clock_prescale_set(clock_div_1);
  #endif

  pixels.begin();
}

void loop() {
  // put your main code here, to run repeatedly:

  // 距離の測定
  int GP2Y0A710K = getGP2Y0A710K(gp2y0a710kPin);

  // LEDの制御
  int green = GP2Y0A710K * 255 / 60;
  if(green < 0 || green > 255) green = 0;
  int red = (255-green)/2;
  ctrlLED(red, green, 0); // 距離が近づくほどより赤く点灯する

  delay(1000);
}

// 距離の測定
int getGP2Y0A710K(int pin){
  int a_in = analogRead(pin);
  return (6762/(a_in-9))-4;
}

// LEDの制御
void ctrlLED(int red, int green, int blue){

  for(int i=0;i<NUMPIXELS;i++){
    // pixels.Color takes RGB values, from 0,0,0 up to 255,255,255
    pixels.setPixelColor(i, pixels.Color(red,green,blue)); // Moderately bright green color.
    pixels.show(); // This sends the updated pixel color to the hardware.
    delay(100); // Delay for a period of time (in milliseconds).
  }

}

Arduinoに測距センサGP2Y0A710K0Fを接続する

測距センサGP2Y0A710K0F

シャープの測距センサGP2Y0A710K0Fは、赤外線等を用いて1m〜5.5mまでの距離の測定を行うことが可能なセンサである。出力電圧は距離に反比例して出力される。

Arduinoに接続する

測距センサGP2Y0A710K0Fは、本体背面に刻印されている文字を読める向きから見て左から、黄(GND), 青(Vcc), 黒(Vcc), 白(Vo), 赤(GND)の順序でピンが配置されている。Vccが青、GNDが赤と通常と逆となっていることに注意が必要である。付属の説明書には、電源ライン安定化のためVcc-GNDライン間に、10μF以上のバイパスコンデンサを付加して使用することを奨励する記述がある。

GP2Y0A710K0Fブレッドボード接続図

上の図では、SE-10のVoutはアナログ入力のA0に入力されている。以下のプログラムは距離センサの出力電圧から距離への変換を行った上で、シリアル通信によりその数値の送信を行っている。

void setup() {
  // シリアル通信速度
  Serial.begin(9600);
}

void loop() {
  int a_in;
  a_in = analogRead(0);
  int dist = (6762/(a_in-9))-4;
  Serial.println(String(dist));

  delay(1000);
}

距離センサの出力電圧から距離への変換は以下の式で行う。

(6762/(a_in-9))-4

PHPプログラムをデーモン起動する(CentOS)

PHPで作成したプログラムをデーモン化しサービス起動させる場合には、デーモン化対応した「PHPプログラム」とそれを起動する「起動スクリプト」の2種類を用意する必要がある。

PHPプログラム

PHPプログラムでは、まず自プロセスをfork/execし端末から切り離し、実行中のプログラムをPIDファイルに書き込む。そのあと自分のプロセスをセッションリーダに指定する処理を行う。

<?php
// pid fileの生成
$pidfile = "/var/run/hoged/hoged.pid";
// 全てのエラー出力をOFF
error_reporting(0);
// 子プロセスの生成
$pid = pcntl_fork();
if($pid < 0){
        // 失敗時
        exit();
}else if($pid){
        // 親プロセスの終了
        exit();
}else{
        // pidファイルを生成
        $pid = getmypid();
        $fp = fopen($pidfile, "w");
        @fwrite( $fp, $pid, strlen($pid) );
        fclose($fp);
        // 現在のプロセスをセッションリーダにする
        $sid = posix_setsid();
        if($sid<0){
                // 失敗時
                exit();
        }
        // ループ処理
        while(TRUE){
                //////////////////////////
                //      定期処理       //
                /////////////////////////
        }
}
?>

起動スクリプト

起動スクリプトは、/etc/rc.d/init.dに設置される各デーモンの起動や終了を行うスクリプトである。/etc/init.d/skeletonもしくは/usr/share/doc/initscripts-*/sysvinitfilesにサンプルが存在する。スクリプト内chkconfigの欄は、RunLevel, 起動時のPriority, 終了時のPriorityの順に記述する。PIDを置くディレクトリは事前にmkdirしておく必要がある。

#!/bin/bash
#
# hoged                Startup script for the Hoge System
#
# chkconfig: 345 99 01
# descroption: The Hoge System.
# processname: hoged
#

# Source function library.
. /etc/init.d/functions

# Path to the script
hoged=/home/hoge/hoged.php
prog=hoged
pidfile=${PIDFILE-/var/run/hoged/hoged.pid}
lockfile=${LOCKFILE-/var/lock/subsys/hoged}
RETVAL=0

start() {
        if [ -f $lockfile ]; then
        echo "$prog is Started"
        exit 1
        fi

        echo -n "Starting $prog: "
        daemon --pidfile=${pidfile} --user hoge php $hoged
        RETVAL=$?
        echo
        [ $RETVAL = 0 ] && touch ${lockfile}
        return $RETVAL
}       

stop() {
        echo -n "Shutting down $prog: "
        killproc -p ${pidfile} $hoged
        RETVAL=$?
        echo
        [ $RETVAL = 0 ] && rm -f ${lockfile} ${pidfile}
}

case "$1" in
    start)
        start
        ;;
    stop)
        stop
        ;;
    status)
        status -p ${pidfile} $hoged
        RETVAL=$?
        ;;
    restart)
        stop
            start
        ;;
    *)
        echo "Usage: $prog {start|stop|status}"
        exit 1
        ;;
esac
exit $RETVAL

Raspberry Piをシングルユーザモードで起動する

ユーザ, パスワードを忘れてしまって、パスワードを設定しなおしたい場合や、
起動時の設定を誤ってしまった場合など、シングルユーザモードでRaspberry Piにログインする方法

cmdline.txtをエディタで開き、赤字の部分を追加します。

dwc_otg.lpm_enable=0 init=/bin/sh console=ttyAMA0,115200 \
> kgdboc=ttyAMA0,115200 console=tty1 root=/dev/mmcblk0p2 rootfstype=ext4 elevator=deadline rootwait logo.nologo
> 

cmdline.txtに、init=/bin/shを追加した上で、
Raspberry Piを起動すると、シングルユーザモードで起動するとのこと。

ただし起動直後は、/以下がreadonlyの状態でマウントされているので、
ファイルの読み込みはできても、変更などを行うことができない。

mount -o remount,rw /

で再マウントを行うことで、読み書きが可能となる。

Arduinoに人感センサ(焦電型赤外線センサ)SE-10を接続する

人感センサ(焦電型赤外線センサ)SE-10

人感センサSE-10は、焦電型赤外線センサを搭載した人体や動物に反応するセンサである。電源を入れて数秒後からセンサ前面周辺を監視し、人体などの35度程度の物体が動くとALARM信号がLOWの状態へと変化する。検知角度は120度である。

Arduinoに接続する

焦電型赤外線センサSE-10は正面から見て左から赤(+B),茶(GND),黒(ALARM)となっており、Arduinoで接続する場合は以下のように接続を行う。赤(+B)と黒(ALARM)との間には10KΩ程度のプルアップ抵抗を入れる。

SE-10ブレッドボード接続図

SE-10のALARM信号は、上の図ではデジタル入力のPin2に入力されている。以下のプログラムは、人感センサーが反応(ALARM信号がLOW)すれば、LEDを点灯させると同時にシリアル通信にて1を送信する処理を行っている。

const int ledPin = 13;
const int pirPin = 2;

void setup() {
  // put your setup code here, to run once:
  // シリアル通信速度
  Serial.begin(9600);
  pinMode(ledPin, OUTPUT);
}

void loop() {
  // put your main code here, to run repeatedly:
  if (digitalRead(pirPin) == LOW) {
    digitalWrite(ledPin, HIGH);
    Serial.println("1");

  } else {
    digitalWrite(ledPin, LOW);
    Serial.println("0");
  }
  delay(1000);
}

Raspberry Pi – Arduino間でシリアル通信を行う

シリアル通信を行うことが可能なscreenコマンドと、
Pythonでシリアル通信を行うことが可能なpython-serialモジュールを
apt-getを利用してRaspberry Piにインストールする

sudo apt-get install screen
sudo apt-get install python-serial

次に、Pythonでシリアル通信スクリプトを作成する

vi serial-arduino.py

このときにファイル名をserial.pyとかいう名前にしてしまうと、
Pythonのserialモジュールと名前が重複してしまい、

AttributeError: ‘module’ object has no attribute ‘Serial’

というエラーがでてしまうので、他の名前にするのが良い。

USBでRaspberry PiとArduinoを接続し、
なんというデバイス名称で認識されているか確認する

dmesg
lsusb

シリアル通信でArduinoから定期的に送られてくるデータをもとに、
JSONファイルを作成するサンプルは以下の通り。

  • カンマ区切りデータの場合
import serial

    def main():
            # デバイス名: /dev/ttyACM0 通信速度: 9600bps
            con=serial.Serial('/dev/ttyACM0', 9600)
            # デバイス名を出力する
            print con.portstr
            while 1:
                    # 1行ごとにデータを取得する
                    str=con.readline()
                    # ファイルに書き込み
                    f = open('/tmp/data.json', 'w')
                    f.write("[{\"data_1\":" + str + "}]")
                    f.close()

    if __name__ == '__main__':
            main()
  • JSON形式の場合
import serial
    import json

    def main():
            # デバイス名: /dev/ttyACM0 通信速度: 9600bps
            con=serial.Serial('/dev/ttyACM0', 9600)
            # デバイス名を出力する
            print con.portstr
            while 1:
                    try:
                            # strという変数名は使用できない
                            strs=con.readline()
                            dec=json.loads(strs)

                            f = open('/tmp/data.json', 'w')
                            f.write(strs)
                            f.close()
                    except KeyError:
                            print "KeyError"
                    except ValueError:
                            print "ValueError"
                    except NameError:
                            print "NameError"

    if __name__ == '__main__':
                    main() 

実行してJSONが吐き出されるか確認する

python serial-arduino.py

Raspberry Piのインストール

Raspberry Piの起動と終了

Raspberry Piの起動

Raspberry Piは、電源を投入すると自動的に起動する
インストール時のログイン名/パスワードは、
以下の通り設定されていて、piユーザにはsudo権限が付与されている

  • user: pi
  • pass: raspberry

Guiを開始する場合は、以下のコマンドを実行する

$ startx

Guiの終了は、メニューからログアウトを選択する

Raspberry Piの終了

終了や再起動は、通常のLinuxと同じで、
以下のいずれかのコマンドを実行する

$ sudo reboot
$ sudo shutdown -h now

Rasbperianのセットアップ

Raspberianのインストール

まず、Raspberry Piで使用するSDカードを
SD Formatterを利用して初期化する

SDカードのフォーマット
初期化されたSDカードにNOOBSをコピーする
NOOBSのコピー