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

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

参考サイト

2016年1月13日水曜日

Mac で Arduino を使う環境を整えてみた

概要

Mac で Arduino を操作できる環境を整えてみました
簡単なコードの実行まで試してみます

環境

  • Mac OS X 10.10.5
  • Arduino UNO
  • Arduino IDE 1.6.7

Arduino IDE のインストール

まず Arduino のサイトに移動します
https://www.arduino.cc/

Download のリンクをクリックします
arduino_top.png

IDE は OS ごとにインストールするパッケージが異なるので Mac 用のパッケージを選択します
「Mac OS X 10.7 Lion or newer」をクリックします
arduino_for_mac.png

ダウンロードのリンクが表示されるので JUST DOWNLOAD をクリックして zip ファイルのダウンロードを開始します
arduino_download.png

arduino-1.6.7-macosx.zip というファイルがダウンロードできたら解凍します
すると Arduino.app というファイルが出てくるのでアプリケーションフォルダに移動します
移動したら Aruduino.app をクリックして開きます
初めはインターネットからダウンロードしたファイルを開くかどうかの警告が表示されるので「開く」を選択します

Arduino IDE が起動すれば OK です
start_arduino_ide.png

Mac と Arduino を接続する

USB ケーブルを使って接続すれば OK です
IDE を起動してからでも大丈夫です
connect_arduino_mac.jpg

接続できたら IDE に Arduino が接続しているポートを教えてあげます

ツール -> シリアルポート -> /dev/cu.usbmodem1421 (Arduino/Genuino UNO)

を選択します
最後のポートは環境によって異なる可能性があるので自信環境で Arduino を接続している USB ポートを選択してください

L チカ用の簡単な配線をする

とりあえず今回は HelloWorld として L チカをやってみます
カソード側を GND に接続し、アノード側を GPIO の 11 番に接続します
arduino_led_circuit.jpg

サンプルのコードの作成

IDE に以下のコードを貼り付けます

int led_pin = 11;

void setup() {
  pinMode(led_pin, OUTPUT);
}

void loop() {
  digitalWrite(led_pin, HIGH);
  delay(1000);
  digitalWrite(led_pin, LOW);
  delay(1000);
}

記載したら IDE の左上にある「検証」をクリックします
コンパイルが成功すると以下のように表示されます
arduino_verify.png

あとはこのコードを Arduino 側に書き込みます
書き込みは IDE の「マイコンボードに書き込む」を選択すれば OK です
書き込みに成功すると LED が点滅し始めると思います

最後に

Arduino を Mac で動作できるようにしてみました

Arduino は RaspberryPi とは違い OS がありません
その代わりに専用の IDE と Arduino 独自の言語を使って GPIO やペリフェラルを制御することができます
他にもいろいろと違い ( デフォルトでアナログ信号を受信できるとか ) がありますが、用途に合わせて使うボードを使い分けられると電子工作も捗ると思います

参考サイト

2016年1月12日火曜日

RaspberryPi で人感センサーを使ってみた

概要

RaspberryPi で人感センサーを使ってみました
その名の通り人が近づくと反応するセンサーです

環境

配線

rpi_motion_sensor_circuit.png

プラスとマイナスがあるので注意してください
真ん中が信号を送信するピンになります

テスト

今回、センサが反応した際の信号は GPIO 17 番で受信します

  • gpio -g mode 17 in
  • while :; do gpio -g read 17; sleep 1; done;

で手を近づけると 0 が 1 に変わると思います
手を話すと 0 に戻りますが、瞬時に切り替わるわけではなく少し待ってから 0 になるようです

最後に

やはりデジタル信号を送ってくれるセンサは簡単に使えます
またセンサ側で電圧降下も対策してくれているので、回路を組むのに抵抗やコンデンサを使わないのも嬉しい点です

2016年1月11日月曜日

同一ネットワーク内で応答可能なマシンを調べる方法

コマンド

  • fping -g 192.168.1.0/24

結果

192.168.1.1 is alive
192.168.1.2 is alive
192.168.1.55 is alive
192.168.1.3 is unreachable
192.168.1.4 is unreachable
192.168.1.5 is unreachable
192.168.1.6 is unreachable
...

DHCP の環境に RaspberrPi を接続したときとかルータ配下に何台マシンがぶら下がっているとか調べたいときに使えます
IP からマシン名もわかると更にいんですが

2016年1月9日土曜日

Express + CoffeeScript で簡単な REST API アプリを作成してみた

概要

Express は Nodejs 用の Web フレームワークです
CoffeeScript は JavaScript を簡単に書けるようにしたラッパー言語でコンパイルすることで JavaScript のコードを生成できます
今回は CoffeeScript 内で Express を使うことで CoffeeScript だけで簡単な REST API アプリを作成してみました

環境

  • CentOS 6.7 64bit
  • Nodejs 0.10.36
  • npm 1.3.6
  • CoffeeScript 1.10.0
  • Express 4.13.3

各種インストール

Nodejs と npm は yum コマンドでインストールしました
EPEL を使えば yum でインストールすることができます

  • yum install nodejs npm –enablerepo=epel

CoffeeScript のインストール

  • npm install -g coffee-script

Express のインストール

  • cd work/
  • npm install express

サンプルアプリのソースコード

  • cd work/
  • vim app.coffee
app = require('express')()                                                                                               
http = require('http').Server(app)
port = 3000

app.get '/', (req, res) ->
  res.json {"status":"200"}

app.get '/error', (req, res) ->
  res.status 404
  res.json {"status":"404"}

http.listen port, ->
  console.log "listening on *:", port

「/」と「/error」の URI に GET メソッドでアクセスすることができる API アプリになります

実行してみる

  • cd work/
  • coffee app.coffee

で 3000 番ポートで LISTEN します
curl を使って確認してみます

  • curl http://localhost:3000/

{“status”:”200”}

  • curl http://localhost:3000/error

{“status”:”404”}

上記のようにレスポンスが返ってくれば OK です

最後に

簡単ですが、API アプリを作成してみました
Experss 自体は Nodejs 用の Web フレームワークなので、JavaScript だけで書くこともできます
わざわざ CoffeeScript を使う理由としては JavaScript よりシンプルに書けるというのが一番の理由だと思います

2016年1月8日金曜日

RaspberryPi で PWM の制御をしてみた

概要

PWM (パルス幅変調) はある一定周期の間隔で動的に変化するパルスを送信することができる仕組みです
モーターの制御や光の強弱の変化などに使われます
RaspberryPi でも PWM が使えるようなので LED を使って試してみました

環境

  • Raspberry Pi Type B Single Board Computer 512MB
  • Raspbian 8.0 (Jessie)
  • Kernel Version 4.1.7+
  • WiringPi
  • wiringpi2 (Python) 1.1.1

事前準備

今回は WiringPi を使って PWM 制御を行うので事前にインストールしておいてください

wiringpi2 のインストール

wiringpi2 は WiringPi 用の Python ライブラリです
pip を使えば簡単にインストールできます

  • sudo pip install wiringpi2

今回は Python スクリプトから PWM を制御します

配線

今回は LED の調光を PWM で変化させてみます
なので、L チカ配線をしてください
L チカ配線の方法はこちらを参考にしてください
wiring_bread_board.png

一点ポイントとしては RaspberryPi 上で PWM の信号を送信するためには GPIO 18 番を使う必要があります
なので、アノード ( + ) 側の GPIO は 18 番に接続するようにしてください

PWM 送信用スクリプトのデプロイ

  • cd work/
  • mkdir python_wiringpi_pwm
  • cd python_wiringpi_pwm
  • vim controls_pwm.py
import wiringpi2 as wiringpi
import time

OUTPUT = 2
PWM_PIN = 18
SLEEP_TIME = 0.03

wiringpi.wiringPiSetupGpio()
wiringpi.pinMode(PWM_PIN, OUTPUT)

for i in range(0, 1024, 16):
    print(i)
    wiringpi.pwmWrite(PWM_PIN, i)
    time.sleep(SLEEP_TIME)

for i in range(1024, 0, -16):
    print(i)
    wiringpi.pwmWrite(PWM_PIN, i)
    time.sleep(SLEEP_TIME)
  • sudo python controll_pwm.py

で実行すると LED が明るくなった後に徐々に暗くなると思います

ポイント

wiringPiSetupGpio で 18 番の GPIO を初期化します
実は初期化の方法には 3 通りあり他に「wiringPiSetup」「wiringPiSetupSys」があります
前者で初期化した場合は 1 番を指定する必要があり、後者で初期化した場合は 12 番を指定する必要があります
どれを使って初期化しても同じ GPIO を指すことになりますが、コールするメソッドによって初期化する GPIO の番号が違うので注意してください

range で 0 から 1024 の範囲でパルス幅を変化させています
RaspberryPi の場合指定できるパルス幅の範囲が 0 から 1024 のためそうしています
他のマイコンボードなどではもっと広い範囲の指定ができる場合があり、その場合にはより精度の高い制御ができます

二つ目の for 文は LED の明るさを暗くするために用意しています

最後に

紹介は以上です
PWM を使うと、このような動的な制御がプログラム上でできるようになります
PWM の王道といえばおそらくサーボモータだと思うので次回はサーボモータの制御をしてみたいと思います

2016年1月7日木曜日

busted で Lua スクリプトのテストをやってみた

概要

busted は Lua スクリプトをテストするためのテストフレームワークです
インストールから簡単な使い方まで紹介したいと思います

環境

  • CentOS 6.7 64bit Final
  • Lua 5.1.4
  • LuaRocks 2.1.2
  • busted 2.0.rc11-0

busted のインストール

luarocks を使ってインストールできます
luarocks のインストールはこちらを参照してください

  • luarocks install busted

依存するライブラリが結構ありました

busted
2.0.rc11-0 (installed) - /usr/lib/luarocks/rocks
dkjson
2.5-2 (installed) - /usr/lib/luarocks/rocks
lua-term
0.3-1 (installed) - /usr/lib/luarocks/rocks
lua_cliargs
2.5-5 (installed) - /usr/lib/luarocks/rocks
luafilesystem
1.6.3-1 (installed) - /usr/lib/luarocks/rocks
luasocket
3.0rc1-2 (installed) - /usr/lib/luarocks/rocks
luassert
1.7.9-0 (installed) - /usr/lib/luarocks/rocks
mediator_lua
1.1.2-0 (installed) - /usr/lib/luarocks/rocks
penlight
1.3.2-2 (installed) - /usr/lib/luarocks/rocks
say
1.3-1 (installed) - /usr/lib/luarocks/rocks

サンプルテストコードの作成

今回は function を定義している別の Lua スクリプトを busted でテストしてみたいと思います

  • sample_function.lua
function sum(a, b)
  return a + b
end

とりあえず引数の値を足しあわせて返却する簡単なメソッドを定義しておきます
これをテストするテストコードを作成します

  • sample_busted.lua
require 'busted.runner'()

require("sample_function")

describe("sum method test", function()
  it("is three", function()
    local val = sum(1, 2)
    assert.are.equal(val, 3)
  end)
end)

describe("sum method test2", function()
  it("is occured error", function()
    local val = sum(1, 2)
    assert.are.equal(val, 4)
  end)

  it("is not three", function()
    local val = sum(1, 2)
    assert.are_not.equal(val, 4)
  end)
end)

テスト冒頭で require 'busted.runner'() することで busted のテストコードであることを明示します
次にテストしたい Lua スクリプトを require します

あとはテストを記載していきます
基本形は describe -> it -> assert でテストを記載していきます

describe はテストの説明を記載するためのメソッドで階層を持たせることもできます
describe 配下に it を定義します
具体的なテストコードは it 配下に記載します
1 つの describe 内に複数の it を記述することも可能です

実行してみる

では実行してみましょう
今回は作成した 2 つの Lua スクリプトは同一ディレクトリに存在することを想定しています

  • busted sample_busted.lua

結果は以下のようになると思います
2 つ目のテストはあえて失敗するテストにしています

●?●
2 successes / 1 failure / 0 errors / 0 pending : 0.000965 seconds

Failure → sample_busted.lua @ 13
sum method test2 is occured error
sample_busted.lua:15: Expected objects to be equal.
Passed in:
(number) 4
Expected:
(number) 3

サンプルの結果だと色はないですが、失敗か成功かを丸と色で表示してくれます
成功した場合は緑になります
失敗したテストは結果と期待値を表示してくれます
あとはテストにかかった時間を表示してくれます

参考サイト

2016年1月6日水曜日

RaspberryPi でタクトスイッチの信号を受信してみた

概要

タクトスイッチ (タクタイルスイッチ) の信号を RaspberryPi で受信してみました
タクトスイッチはいわゆる普通のスイッチで押した状態 (1) or 押していない状態 (0) を制御することができます

環境

  • Raspberry Pi Type B Single Board Computer 512MB
  • Raspbian 8.0 (Jessie)
  • Kernel Version 4.1.7+
  • Python 2.7.9
  • タクトスイッチ

配線

実際に配線した写真は以下の通り
rpi_tact_switch.jpg

fritzing で書いた配線図は以下の通り
rpi_tact_switch_circuit.png

今回はプルダウンスイッチをソフトウェア側ではなくハード側で制御するので GPIO で信号を受け取る前に 10kオームの抵抗を配置しています
これがプルダウン抵抗です

タクトスイッチのサンプルは他にもいろいろと情報が転がっているので、調べればプルダウン抵抗なし版の回路も簡単に見つかると思います

ソースコードデプロイ

  • mkdir -p ~/work/tact_switch
  • vim ~/work/tact_switch/receive_signal.py
#!/usr/local/bin/python
# -*- coding: utf-8 -*-

import RPi.GPIO as GPIO

pin = 17

def setup(): 
    GPIO.setmode(GPIO.BCM)
    GPIO.setup(pin, GPIO.IN)

def main(): 
    try:
        GPIO.wait_for_edge(pin, GPIO.FALLING)
        print(GPIO.input(pin))
        print("pushed")
    except KeyboardInterrupt:
        print "KeyboardInterrupt"
    except:
        print "Quit"
    finally:
        print "clean up"
        GPIO.cleanup()

if __name__=="__main__":
    setup()
    main()

GPIO は 17 番を使っています
ポイントは wait_for_edge というメソッドでこれを使うことで指定された GPIO が FALLING (押された) 状態になったら次の処理に進むことができます

スクリプトを実行するとスイッチからは 0 が送信されているため入力待ち状態になるはずです
その状態でスイッチを押すと「pushd」と表示されスクリプトが終了します

自分がハマったのは信号が 0 と 1 を繰り返してしまい、待ち状態に入らない現象が発生しました
原因は超単純で別のスクリプトが同じ GPIO を制御しており、そのスクリプトを停止したら正常に動きました
回路がおかしい場合や、抵抗の値が小さい場合にも正常に動かないようです

参考サイト