2016年1月25日月曜日

markdown2impress を使って Markdown からスライドを作成してみた

概要

これまでスライドは Reveal.js を使って作成してきました
Reveal.js も良く出来ていて重宝しているのですが、編集が HTML を直接編集するため互換性やら見た目があまりよくありません
Jekyll にも Hekyll というプラグインがありこれを使えば Jekyll でスライドが作成できるのですが、スライドごとに Markdown ファイルを追加しなければいけないのでページが多いと大変です
今回は README.md 一個でスライドが簡単に作れる markdown2impress を試してみました

環境

  • CentOS 6.7 64bit
  • Perl v5.10.1
  • cpan 1.9402
  • Apache httpd 2.2.15
  • 動作確認ブラウザ Firefox 43.0.4

必要なモジュールのインストール

  • cpan -i Data::Section::Simple
  • cpan -i Text::Markdown
  • cpan -i Text::Xslate
  • cpan -i Path::Class

それぞれインストールしてください
インストールに結構時間がかかります

サンプルスライドの作成

About me
========

* @kakakikikeke
* [blog](http://kakakikikeke.blogspot.jp/)
  • mkdir -p /var/www/html/test
  • cp -ipr index.html js/ css/ /var/www/html/test

http://localhost/test/ にアクセスするとサンプルのスライドを確認することができると思います

sample_markdown2impress.png

Tips

YAML 系のエラーが出る場合は以下を試してみてください
http://kakakikikeke.blogspot.jp/2012/10/perlcpanyaml.html

cpan でモジュールをインストールする前にインストール時の yes の回答をデフォルトで全部 yes にしておくことをおすすめします
「Text::Xslate」のインストールが非常に長いので
http://kakakikikeke.blogspot.jp/2013/07/perlcpan.html

2016年1月21日木曜日

CentOS に最新の Nodejs をインストールする方法

概要

CentOS に最新版の Nodejs をインストールする手順を紹介します
epel を使うと v0.x 系のバージョンの Nodejs がインストールされてしまうので yum ではダメです

環境

  • CentOS 6.7 64bit
  • Nodejs 4.2.5
  • npm 2.14.12

インストール方法

コンパイル済みのバイナリファイルを展開して配置して終了になります

  • cd /var/tmp
  • wget https://nodejs.org/dist/v4.2.5/node-v4.2.5-linux-x64.tar.xz
  • tar xvf node-v4.2.5-linux-x64.tar.xz
  • mv node-v4.2.5-linux-x64 /usr/local/
  • ln -s node-v4.2.5-linux-x64/ node
  • cd /usr/bin
  • ln -s /usr/local/node/bin/node
  • ln -s /usr/local/node/bin/npm
$ node -v
v4.2.5
$ npm -v
2.14.12

こんな感じになれば OK です

2016年1月19日火曜日

楽譜を作成できる abc.js を試してみた

概要

abc.js はブラウザ上に楽譜を描画することができるライブラリです
楽譜の描画に必要な情報を渡すと SVG 形式で楽譜を描画してくれます

環境

  • CentOS 6.7 64bit
  • Apache httpd 2.2.15
  • Firefox 43.0.4
  • abc.js 2.3

abc.js のインストール

インストールは簡単です
必要な js ファイルを適当な場所に配置すれば OK です

今回は既存のサイトの <pre> 情報から楽譜を作成するプラグイン方式と、abc.js のメソッドをコールすることで楽譜を描画するベーシック方式の 2 種類で楽譜を作成してみました

abcjs_plugin を使ったサンプルコード

まずはプラグイン方式を使った方式を紹介します

  • cd /var/www/html/abcjs
  • wget https://raw.github.com/paulrosen/abcjs/master/bin/abcjs_plugin_2.3-min.js
  • vim plugin_sample.html
<!DOCTYPE html>
<html>
  <head>
  <meta http-equiv="Content-Type" content="text/html;charset=utf-8"/>
  <script src="abcjs_plugin_2.3-min.js" type="text/javascript"></script>
  <body>
    <pre>
X: 1
T: Musikalisches Opfer (BWV 1079)
T: No. 3 Canones diversi (Realisation)
C: J. S. Bach
K: Eb
V: 1
C4E4|G4A4|=B,4z2G2-|G2^F4=F2-|=F2=E4_E2-|_E2=D2_D2C2|
V: 2
C2E2G2c2|=Bcde fedc|dGdf edc=B|=A=Bce dc=B=A|GAB_d cBAG|FGAB AGFE|
V: 1
=B,2G,2C2F2|E4D4|C4E4|GFGc GEDE|FG=A=B cEFG|ADEF GFED|
V: 2
DEFG FEDA|GFEc =B=AGF|EDEG cGFG|E4C4|D4E4|F2C2G,2=B,2|
V: 1
EFGA BAGF|GABc _dBAG|=A=Bcd ec=B=A|=Bcde fdGd|cdef edc=B|c2G2E2C2:|
V: 2
C2_D2=D2_E2|-_E2=E4=F2|-=F2^F4G2|-G2z2=B,4|A4G4|E4C4:|
    </pre>
  </body>
</html>

これで http://localhost/abcjs/plugin_sample.html にアクセスすると楽譜の元データと楽譜の SVG 画像が表示されるとおもいます

abcjs_plugin_sample.png

プラグイン方式の場合は <pre> タグの中に <div> タグで SVG 情報を描画するので、既存の楽譜情報を削除することができません
( 別途、JavaScript を使えばできると思いますが )

もしすでに楽譜情報が HTML として存在しているなら、この方式を使ったほうが簡単ではあります

abcjs_basic を使ったサンプルコード

では、次に楽譜情報を作成する関数をコールすることで楽譜を描画してみたいと思います

  • cd /var/www/html/abcjs
  • wget https://raw.github.com/paulrosen/abcjs/master/bin/abcjs_basic_2.3-min.js
  • vim basic_sample.html
<!DOCTYPE html>
<html>
  <head>
  <meta http-equiv="Content-Type" content="text/html;charset=utf-8"/>
  <script src="abcjs_basic_2.3-min.js" type="text/javascript"></script>
  <script src="myabc.js" type="text/javascript"></script>
  <body onload="ABCJS.renderAbc('notation', score); return false;">
    <div id="notation"></div>
  </body>
</html>
  • vim myabc.js
var number_of_tunes = "1"; // 曲数
var title = "score_title"; // 楽譜タイトル
var measure = "4/4"; // 拍子 (e.g. 4 拍子)
var long = "1/4"; // 音符の長さ (e.g. 8分音符)
var rhythm = ""; // リズム
var major_key = ""; // 長調
var score = '\
X: ' + number_of_tunes + '\n\
T: ' + title + '\n\
M: ' + measure + '\n\
L: ' + long + '\n\
R: ' + rhythm + '\n\
K: ' + major_key + '\n\
C D E F|G A B c|C D E F|G A B c\n\
'

せっかくなので全く同じ楽譜ではなく自分で楽譜の情報を与えてみました
とは言ったも「ドレミファソラシド」を描画しているだけです
また、JavaScript と HTML を分けて、楽譜情報を JavaScript ファイルで管理するようにしています

ABCJS.renderAbc に描画する div タグの id 情報と描画する楽譜の文字列情報を渡せば OK です

コード中に各パラメータの説明を簡単に記載しています
自分は楽譜を読むことはできないので、解釈を間違っているパラメータがあるかもしれないのでご了承ください

ドレミファソラシドは英語で「CDEFGABc」に対応しているのでその情報を与えています

これで http://localhost/abcjs/basic_sample.html にアクセスすると楽譜の SVG 画像が表示されるとおもいます
先ほど違って楽譜の元情報は描画されないと思います

abcjs_basic_sample.png

最後に

とりあえず楽譜を描画することはできました

触っていて一番気になったのはドキュメントが非常に少ないことです
公式サイトにもちゃんとしたドキュメントがなく、楽譜を描画する際に与えるパラメータ情報が見つからず「X:」とか「L:」とかが一体何を表しているのかさっぱりわかりませんでした

なのでソースコードを Github からダウンロードして特定のキーワードで grep をかけることでパラメータをパースしている実装部分を探して何を表しているパラメータなのか判断しながら試しました

  • $ grep -r --exclude=jquery-1.11.3.min.js --exclude-dir bin/ 'R:' * | grep -v 'PER:'

結構たくさん指定できるパラメータがあって、ちゃんとこれらを使って楽譜を作成しようとしたら、楽譜を書く力もないと結構大変かもしれません

  • parse/abc_parse_header.js
var metaTextHeaders = {
        A: 'author',
        B: 'book',
        C: 'composer',
        D: 'discography',
        F: 'url',
        G: 'group',
        I: 'instruction',
        N: 'notes',
        O: 'origin',
        R: 'rhythm',
        S: 'source',
        W: 'unalignedWords',
        Z: 'transcription'
};

2016年1月18日月曜日

Arduino でサーボモータを制御してみた

概要

Arduino でサーボモータを制御してみました
Arduino にデフォルトで含まれている Servo ライブラリと独自で PWM を作成して制御する方法の 2 つを試してみました

環境

配線

Arduino UNO はデフォルトで PWM をサポートしているため配線は非常に簡単です
arduino_servo_circuit.jpg

サーボモータから出ている線の

  • 茶色 -> Arduino GND
  • 赤色 -> Arduino 5v電源
  • オレンジ色 -> Arduino GPIO 8 番

に接続します
GPIO は他の好きなところで OK ですが、今回は 8 番を使って進めていきます

制御用スクリプト

2 つ紹介します
どちらも流れとしては Serial.read で受け取った角度情報にサーボモータを回すという処理になります

独自の実装で PWM を送信

まずは自分で PWM 信号を作ってサーボモータを制御するスクリプトです

int deg = 610; // msec.
int pin = 8;

void setup() {
  pinMode(pin, OUTPUT);
  Serial.begin(9600);
}

void move_servo(int deg) {
  digitalWrite(pin, HIGH);
  delayMicroseconds(deg);
  digitalWrite(pin, LOW);
  delay(20);
}

int serialRead() {
  char c[4];
  for (int i = 0; i < 3; i++) {
    c[i] = Serial.read();
    if (c[i] == '\0') {
      break;
    }
  }
  return atoi(c);
}

void loop() {
  move_servo(deg);
  if (Serial.available() > 0) {
    delay(10);
    int input = serialRead();
    if ( input >= 0 && input <= 180 ) {
      deg = 610 + input / 180.0 * ( 2350 - 610 );
    }
  }
}

SG90 のサーボモータは送信するパルス幅の長さが約 610ms から 2350ms で 0 度 から 180 度の動きをするようです
そのパルスを送信する周期を 20ms にしています

送信の仕方は

digitalWrite(pin, HIGH);
delayMicroseconds(deg);
digitalWrite(pin, LOW);

で実現しており、HIGH の状態を指定ミリ秒続けることで幅の違うパルスを送信しています

あとは Serial.read で受け取った度数情報を delayMicroseconds に渡せるように変換してあげます

deg = 610 + input / 180.0 * ( 2350 - 610 );

loop メソッドはその名の通りずっとループしています
なので、move_servo は 20ms の wait をおいて常にコールされているため入力を変えない限り 20ms の間隔で同じパルス幅の信号が送信されていることになります

このプログラムで実際に動作させてみると入力した角度に動くのは動くのですが、サーボモータが動いていないときに「ジリジリ」という音と微妙な振動が発生してしまいました
おそらくですが、これは正確に PWM を送信されていないのが原因で、毎回 20ms 待つようにしていますが、Serial の読み込み等の他の処理があり周期が毎回正確になっておらず、サーボモータが不安定な状態になっているのだと思います

次に Servo ライブラリを使った制御を紹介しますが、結論から先に言うとライブラリを使った制御のほうが圧倒的に安定します
とりあえず今回は PWM の仕組みも知りたかったの、独自の制御方式も試してみた感じです

Servo ライブラリを使って PWM を送信

では、次に Arduino がデフォルトで提供している Servo ライブラリを使って制御してみたいと思います

#include <Servo.h>
Servo servo;

int pin = 8;
int deg = 0;

void setup() {
  servo.attach(pin);
  Serial.begin(9600);
}

void move_servo(int deg) {
  servo.write(deg);
  delay(200);
  servo.detach();
}

int serialRead() {
  char c[4];
  for (int i = 0; i < 3; i++) {
    c[i] = Serial.read();
    if (c[i] == '\0') {
      break;
    }
  }
  return atoi(c);
}

void loop() {
  move_servo(deg);
  if (Serial.available() > 0) {
    delay(10);
    int input = serialRead();
    if ( input >= 0 && input <= 180 ) {
      servo.attach(pin);
      deg = input;
    }
  }
}

ソースもかなり簡潔になりました
Servo ライブラリを使うと servo.write で角度の情報をそのまま渡せます
なので、パルス幅を計算するロジックがなくなります

独自のパルスを送信しているときにジリジリ言っていた問題は

delay(200);
servo.detach();

のロジックでほぼ言わなくなりました
当たり前といえば当たり前ですが、サーボモータを回したくないときは detach することで無駄な信号の送信を抑制します
再度サーボモータを回したいときに attach しています

サーボモータを servo.write で回してからdetach するまでに 200ms の delay を入れています
これは、回した直後に detach してしまうと write の情報がサーボモータに届く前にサーボモータを detach してしまうので、サーボモータが上手く回ってくれないためです

実行してみる

どちらもコードを Arduino IDE に貼り付けて配線して Run すれば OK です
動画等はなくて恐縮ですが、実行して比較してみると Servo ライブラリを使ったほうが断然いい感じにサーボモータが動きます

最後に

Arduino でサーボモータを制御してみました
PWM に詳しく実際に PWM でモータやセンサー等を制御したことある場合は独自の PWM 実装でもいいかもしれませんが、PWM について良くわからないということであれば素直に Servo ライブラリを使うことをオススメします

サーボモータは RaspberryPi でも制御できるので機会があれば RPi でも制御してみたいと思います
Arduino と RaspberryPi どちらでもできるけど、アナログ信号や PWM を扱う場合は Arduino のほうが簡単に制御できる気がします
両方使うとボードが増えて大変ですが、、

参考サイト

2016年1月16日土曜日

TinkerMode のスマートモジュール機能を使ってみた

概要

前回 TinkerMode を使ってデバイスの制御を行いました
今回は TinkerMode のスマートモジュールという機能を使ってみました
スマートモジュールは簡単に説明すると Webhook です
あるデバイスからのイベントが発生した際に、特定の URL に対して GET リクエストを送信することができます

環境

  • Mac OS X 10.10.5

今回は RaspberryPi 等の実際のデバイスを使って試していないので PC があれば OK です
ただ、前回行ったデバイスの登録や制御ができる環境は事前に構築しておいてください

Scriptr.io の登録

いきなり出てきましたが、Scriptr.io というサービスを今回使います
scriptr_top.png

Scriptr.io は任意の JavaScript を実行できるサービスで、スクリプトの実行を API (URL) で行うことができます
同様のサービスだと Parse.com のクラウドコード等があります

登録は簡単で Twitter や Github のアカウントをすでに持っていれば、それを使うこともできます
SNS サービスと連携したくない場合はメールアドレスを持っていれば、それを使って登録することもできます
自分は少しハマったのですが、Github のアカウントを使う場合には Github のアカウントのプロフィールでメールアドレスを Public にする必要があります
scriptr_registration.png

Scriptr.io でサンプルコードの作成

ログインできたら早速コードを作成します
今回は何でも良いので簡単な JSON レスポンスを返却するスクリプトを作成します

var http = require("http");
var log = require("log");
log.setLevel("DEBUG");

var name = request.parameters.myName
if (name != null) storage.local.theName = name
var ip = request.headers["x-forwarded-for"];
var requestObject = {
 "url": "https://scriptr.io/hello",
 "params": {"name": storage.local.theName, "ip": ip},
 "method": "GET"
}

log.debug("Access Remote IP : " + ip);
var response = http.request(requestObject);
if(response.status == "200"){
 var result = JSON.parse(response.body);
 return result
}

Scriptr.io のコンパネにログインすると「HelloDevice」というサンプルのスクリプトがあります
今回のスクリプトは、ほぼそれを流用しています
このスクリプトは https://scriptr.io/hello という Scriptr.io がデフォルトで提供するスクリプトがあり、そこにアクセスして取得できた JSON レスポンスを返却しています

追加で修正している箇所は log モジュールを require して独自のログを少し出すように修正しています

とりあえず今回は mySample という名前でスクリプトを保存しておきます

GET リクエスト作成

スクリプトを保存したら Scriptr.io のコンパネでスクリプトを実行してみましょう
実行ボタン ( Run ) があるのでそれをクリックすれば OK です
scriptr_execute_script.png

下段のペインに実行コマンドとレスポンスが表示されます
ここに記載されている POST の curl コマンドを GET 用のリクエストに変換します

スクリプトを実行するにはトークンが必要で POST の場合はヘッダにトークンを設定します
TinkderMode のスマートモジュールは POST のリクエストをコールすることができません
なのでこれを GET でコールできるように変更する必要があります
具体的には以下のように変更します

curl -X POST -H 'Authorization: bearer <Token>' 'https://api.scriptr.io/mySample'

curl -X GET 'https://api.scriptr.io/mySample?auth_token=<Token>&apsws.time=123456789'

パラメータの「auth_token」にトークンを設定します
また、apsws.time というパラメータにも適当な数字を設定します
ドキュメントにも記載がなかったので詳細はわかりませんが、適当な数字を設定しても通ったのでとりあえず、適当な数字を当て込んでいます

これでスマートモジュールの実行先の URL を作成することができました

スマートモジュールの作成

ここから TinkerMode での作業になります
まずスマートモジュールを作成します

Smart Modules -> New

で以下を設定します

  • Module ID・・・適当な名前を設定すれば OK (必須)
  • Description・・・スマートモジュールの説明を記載します (必須)
  • Command Webhook・・・今回は使いません
  • Event Webhook・・・先ほど作成した GET 用の URL を入力します

mode_create_smart_module.png

入力したら Save をクリックして保存します
これでデバイスからイベントが TinkderMode に対して発行されると指定した Event Webhook の URL にリクエストが送信されます

テスト実行

これで準備が整ったのでイベントを発行して挙動を確認してみます
TinkerMode でデバイスシミュレータを起動してイベントを発行します

Device -> 事前に作成したデバイスクラス -> 事前に登録したデバイス -> DEVICE SIMULATOR ( 別ウィンドウで開く ) -> Outgoing: Events

でイベントを登録します
今回はどんなイベントでもいいので適当に設定して「TRIGGER EVENT」をクリックしてイベントを送信します
mode_trigger_event.png

デバイスシミュレータ上では何が起きたか確認できないので、Scriptr.io に行ってアクセスログを確認してみます

コンパネの右上に「Logs」という項目があるのでクリックします
するとスクリプトに対するアクセスログが表示されます
ここに TinkerMode からのアクセスログがあれば OK です
scriptr_confirm_logs.png

ログを開いておけばリアルタイムで更新されるので、その状態でイベントを発行してもいいと思います

最後に

長文になりましたが以上です
とりあえず TinkerMode のスマートモジュールの挙動を確認することができました
リクエスト先として今回は Scriptr.io を選択しましたが、自信のサーバがあればそこでも OK ですし、データ保存系のサービスに直接リクエストしても良いと思います

ここから触ってみた所感を少し記載します
まず TinkderMode のスマートモジュールが GET でしかリクエストできないのは結構きついです
最近のクラウドサービスは REST-API なので POST や PUT が使えないとなると独自のラッパを実装してそこに GET リクエストを送った上でそこから POST や PUT を送信する必要が出てきます

あとは Scriptr.io 側の話ですが、npm で好きなモジュールを使えないのが痛いです
ここで例えば Parse.com やニフティクラウドモバイルバックエンドの Node.js SDK が使えれば Scriptr.io だけでデータを保存する機能を作ることができます
現状は Scriptr.io が提供する数個のモジュール (http, log, twitter, facebook など ) しか使えません
おそらくはセキュリティの関係だとは思いますが、これが好きな npm モジュールを使えるようになるとかなり応用が広がると思いました

参考サイト

2016年1月15日金曜日

RaspberryPi でダイナミック方式の 7 セグ LED を使ってみた

概要

RaspberryPi を起動した時に取得できた IP アドレスを 7 セグに表示したいなと思っていて、ずばりな記事を見つけたので試してみました
配線や Python スクリプトは、そのまま参考にさせていただきました

環境

  • Raspberry Pi Type B Single Board Computer 512MB
  • Raspbian 8.0 (Jessie)
  • Kernel Version 4.1.7+
  • Python 2.7.9
  • 7 セグ LED カソードコモン
  • ジャンパケーブル オスxメス 12 本
  • 抵抗 27オーム 4 個

配線

rpi_7_seg_led.jpg

参考サイトを元に実線してみましたが、各桁の表示 ON/OFF 用のジャンパで 4 本、7 セグの各セグメントを制御するためのジャンパが 8 本で、合計 12 本のジャンパと GPIO を使うのでかなりごちゃごちゃになってしまいました
もう少し GPIO に余裕のあるボードだともっと綺麗に配線できるかもしれません

抵抗は 27 オームの抵抗を使っていますが 47 オームの抵抗でも OK です

制御用の Python スクリプト

こちらも参考サイトのコードをそのまま使用させていただきました
今回は使っている GPIO も全く同じにしたのでそのまま動作します

  • mkdir -p ~/work/7_seg_led
  • cd ~/work/7_seg_led
  • vim turn_on_ip.py
!/usr/bin/env python
# -*- coding: utf-8 -*-

import RPi.GPIO as GPIO
import threading
import time
import socket

ledport = (14, 15, 18, 23)
segport = (4, 17, 27, 22, 10, 9, 11, 7)
digit = ((1, 1, 1, 1, 1, 1, 0),     # 0
         (0, 1, 1, 0, 0, 0, 0),     # 1
         (1, 1, 0, 1, 1, 0, 1),     # 2
         (1, 1, 1, 1, 0, 0, 1),     # 3
         (0, 1, 1, 0, 0, 1, 1),     # 4
         (1, 0, 1, 1, 0, 1, 1),     # 5
         (1, 0, 1, 1, 1, 1, 1),     # 6
         (1, 1, 1, 0, 0, 0, 0),     # 7
         (1, 1, 1, 1, 1, 1, 1),     # 8
         (1, 1, 1, 1, 0, 1, 1),     # 9
         (0, 0, 0, 0, 0, 0, 0),     # Blank
         (0, 0, 0, 0, 0, 0, 1))     # Minus

class DynamicLed:
    def __init__(self):
        for n in range(8):
            GPIO.setup(segport[n], GPIO.OUT)
            GPIO.output(segport[n], False)
        for n in range(4):
            GPIO.setup(ledport[n], GPIO.OUT)
            GPIO.output(ledport[n], True)
    def set_digit(self, no, num):
        dot = num & 0x80
        num = num & 0x7F
        if(no == 0):
            GPIO.output(ledport[3], True)
        else:
            GPIO.output(ledport[no - 1], True)
        for n in range(7):
            GPIO.output(segport[n], digit[num][n])
        GPIO.output(segport[7], dot)
        GPIO.output(ledport[no], False)

rlock = threading.RLock()

class LedThread(threading.Thread):
    def __init__(self):
        threading.Thread.__init__(self)
        self.ss = DynamicLed()
        self.dig = [0, 0, 0, 0]
        self.running = True
    def run(self):
        while self.running:
            rlock.acquire()
            for n in range(0, 4):
                self.ss.set_digit(n, self.dig[n])
                time.sleep(0.005)
            rlock.release()
    def stop(self):
        self.running = False
    def set(self, a, b, c, d):
        rlock.acquire()
        self.dig[0] = a
        self.dig[1] = b
        self.dig[2] = c
        self.dig[3] = d
        rlock.release()
    def set_num(self, num, width=0, dot=-1):
        str = '{0:>.{width}f}'.format(num, width=width)
        dp = 0;
        pos = 3;
        rlock.acquire()
        for n in range(len(str) - 1, -1, -1):
            if str[n] == '.':
                dp = 0x80
            elif str[n] == '-':
                self.dig[pos] = 11  # MINUS
                pos = pos - 1
            else:
                self.dig[pos] = int(str[n]) | dp
                dp = 0
                pos = pos - 1
            if pos < 0:
                break
        for n in range(0, pos + 1):
            self.dig[n] = 10    # BLANK
        if dot >= 0:
            self.dig[dot] = self.dig[dot] | 0x80
        rlock.release()

if __name__ == "__main__":
    GPIO.setmode(GPIO.BCM)
    GPIO.setwarnings(False)
    # get ip address
    sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    sock.connect(('google.com', 0)) # dummy connect
    ip = sock.getsockname()[0]
    sock.close()
    array = ip.rsplit('.')
    # led thread start
    led = LedThread()
    led.start();
    try:
        while True:
            led.set_num(int(array[0]), dot=3)
            time.sleep(1)
            led.set_num(int(array[1]), dot=3)
            time.sleep(1)
            led.set_num(int(array[2]), dot=3)
            time.sleep(1)
            led.set_num(int(array[3]))
            time.sleep(1)
    except KeyboardInterrupt:
        print '\nbreak'
    led.stop()
    led.join()
    GPIO.cleanup()

実行

作成したスクリプトを実行してみましょう

  • cd ~/work/7_seg_led
  • python turn_on_ip.py

これでグローバル IP に接続するために割り振られた IP アドレスが 7 セグに順番に表示されると思います
使っている RPi が古めの低スペックなので、若干表示がチラつくときもありましたが、読み取れないレベルではなかったです

無限に表示し続けるので終了したい場合は Ctrl + c で終了させてください

cron に登録する

一箇所だけソースを修正します
cron にする場合に無限ループになっていると次回動作したときに GPIO を取り合いうまく表示されません
104 行目にある無限ループをコメントアウトしてあげましょう

103     try:
104         # while True:
105             led.set_num(int(array[0]), dot=3)
106             time.sleep(1)
107             led.set_num(int(array[1]), dot=3)
108             time.sleep(1)
109             led.set_num(int(array[2]), dot=3)
110             time.sleep(1)
111             led.set_num(int(array[3]))
112             time.sleep(1)

これで cron に以下のように設定します
とりあえず 1 分ごとに表示してくれます

*/1 * * * * python /home/pi/work/7_seg_led/turn_on_ip.py

最後に

IP アドレス情報を取得して順番に 7 セグ LED に表示してみました
cron に登録しておけば、配線さえしておけばいつでも IP を確認することができるようになりました

まぁでも、RPi を起動するたびにこの配線をするのは面倒なので、やっぱり fping とかで検知して接続したほうが簡単かもしれません

2016年1月14日木曜日

RaspberryPi でフルカラー LED を制御してみた

概要

タイトル通り
RaspberryPi でフルカラー LED を制御してみました

環境

  • Raspberry Pi Type B Single Board Computer 512MB
  • Raspbian 8.0 (Jessie)
  • Kernel Version 4.1.7+
  • WiringPi
  • フルカラー LED

配線

実際の写真はこちら
rpi_full_color_led_circuit.jpg

frizing で作成した配線はこちら
rpi_full_color_led_circuit.png

赤の制御は GPIO 17
青の制御は GPIO 22
緑の制御は GPIO 27

で行います
足と色のひも付けは左から「赤」「カソード」「緑」「青」になります
http://akizukidenshi.com/download/ds/optosupply/OSTA5131A.pdf

テスト

配線ができたらあとは WiringPi で GPIO に信号を送信して動作を確認します


    • gpio -g mode 17 out
    • gpio -g write 17 1
    • gpio -g write 17 0

    • gpio -g mode 22 out
    • gpio -g write 22 1
    • gpio -g write 22 0

    • gpio -g mode 27 out
    • gpio -g write 27 1
    • gpio -g write 27 0

今回の配線だと、どの色もかなり明るく発光するので、まぶしい場合は適当に抵抗を挟んで明るさを調整してください
( 本当はちゃんと電源電圧や順方向電圧、順方向電流を考慮して抵抗を選択する必要があります )

参考サイト