2016年10月14日金曜日

乾電池だけで L チカしてみた

概要

Arduino やら RaspberryPi などから電子工作に入門した自分はマイコンやシングルボードコンピュータを使わないで L チカをしてみたことがありませんでした
応用から基礎を勉強する感じですが、それらを使わないで LED を点灯させてみました

環境

  • ブレッドボード
  • 単三電池 x 2
  • 電池ソケット
  • 抵抗 1kΩ
  • LED
  • ジャンパケーブル
  • タクトスイッチ

配線 (電池のみ)

2 本の電池を使って LED を点灯させます
プルダウンで GND 側に 1kΩ の抵抗を接続しています
blink_led_only_battery.jpg

せっかくなので回路図も作成してみました
見た目の配線は適当です
blink_led_only_battery_circuit.png

動作確認

電池をセットすると LED が点灯します
適当にテスターで LED にかかる電圧を計測したのですが、だいたい 2V くらいでした

配線 (タクトスイッチ)

毎回電池をセットしたり外したりするのが面倒なのでタクトスイッチで点灯できるようにしてみます
単純にスイッチが押されたときに回路がつながるように配線し直すだけです
抵抗は同じくプルダウンで接続しています
blink_led_only_battery_with_sw.jpg

こちらも回路図を作成しました
配線がガタガタです
blink_led_only_battery_with_sw_circuit.png

動作確認

タクトスイッチを押すと LED が点灯します
この回路でもだいたい 2V の電圧が LED に掛かっていました

おまけ

おまけでタクトスイッチの反対側にも LED をつけてみました
これでも問題なく点灯しましたが、LED が一つのときよりかは光が暗くなりました
blink_led_only_battery_with_sw_2.jpg

LED と抵抗がスイッチに対して並列に接続されているだけです

最後に

乾電池だけで LED を点灯させてみました
タクトスイッチも入れることでスイッチを押したときだけ点灯する回路も作成しました

Arduino や RaspberryPi の GPIO も今回使ったようなタクトスイッチのような働きがありますが、GPIO は read もできるし一番はプログラムできるのが大きいと思います
逆にいうとそのような必要がない場合はハードウェア (回路) だけでも動くものは作れるということです

参考サイト

2016年10月13日木曜日

TinkerMODE の MQTT を ruby から直接使ってみた

概要

TinkerMODE の MQTT エンドポイントを ruby から使ってみました
イベントとコマンド用のトピックに対して pub/sub を実行してみました

環境

  • Mac OS X 10.11.6
  • Ruby 2.2.3p173
  • Gem 2.4.5.1
  • TinkerMODE (2016/10/12 時点)

前提知識

TinkerMODE では MQTT のエンドポイントを公開しています

  • mqtt.tinkermode.com:1883

SecurePort で 8883 も公開しているので証明書を使えば SSL を使うこともできます (今回は 1883 ポートを使います)

利用者側では pub/sub できるトピックが限定されています
Publish できるトピックは「/devices/DEVICE_ID/event」で Subscribe できるトピックは「/devices/DEVICE_ID/command」になります
公式でも以下のような見解を述べています

  • A device can only PUBLISH to the topic /devices/<device Id>/event
  • A device can only SUBSCRIBE the topic /devices/<device Id>/command

要するにイベントは Publish のみでコマンドは Subscribe のみ提供しています
ではイベントに対する Subscribe とコマンドに対する Publish はどうするかというと「コンパネ」と「REST API」が用意されています

図にすると以下のような感じです
tinkermode_mqtt_fig.png

ということで実際に挙動を確認していきます

ライブラリ準備

  • bundle init
  • vim Gemfile
source "https://rubygems.org"

gem "mqtt"
  • bundle install

イベントへの Publish

まずはイベントの挙動を確認します
Ruby スクリプトは Publish するスクリプトになります

  • vim pub_event.rb
require 'mqtt'
require 'json'

MQTT::Client.connect(
  :host => 'mqtt.tinkermode.com',
  :port => 1883,
  :version => '3.1.1',
  :clean_session => true,
  :username => 'nnn',
  :password => 'v1.ZHw4MDh8MA==.xxxxxxxxxx.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx') do |c|

  payload = {
    'eventType' => 'test-event',
    'eventData' => {
      'value': 1
    }
  }.to_json
  c.publish('/devices/nnn/event', payload)
end

「username」に TinkerMODE 上で作成したデバイスの Device ID を「password」には API Key を設定してください

:version => '3.1.1' の記述がないと「Failed to read byte from socket (MQTT::ProtocolException)」が発生するので注意してください

記載できたら実行しましょう

  • bundle exec ruby pub_event.rb

これで TinkerMODE の MQTT を使ってイベントを送信することができます
送信できたらコンパネでイベントが送信されているか確認してみましょう
tinkermode_mqtt_receive_event.png

こんな感じでコンパネ側で Subscribe できているのがわかります

イベントの Publish と大きく絡む機能は SmartModule という機能です
今回 eventType に「test-event」という値を設定して Publish しました
SmartModule でもイベントをSubscribe しており、この eventType ごとに実行すると SmartModule を振り分けることができます

例えば「test-event」が Publish されたときはサイト A に Webhook を送る、「test-event2」が Publish されたらサイト B に Webhook を送るみたいなことができるようになります

これは所謂イベントパイプラインと呼ばれる仕組みで、あるイベントの発生に応じて次に実行する処理を振り分けることができます
TinkerMODE の SmartModule ではそのような機能を提供しています

コマンドの Subscribe

次のコマンドの挙動を確認します
Ruby スクリプトは Subscribe するスクリプトになります

  • vim sub_command.rb
require 'mqtt'

MQTT::Client.connect(
  :host => 'mqtt.tinkermode.com',
  :port => 1883,
  :version => '3.1.1',
  :clean_session => true,
  :username => 'nnn',
  :password => 'v1.ZHw4MDh8MA==.xxxxxxxxxx.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx') do |c|

  c.get('/devices/nnn/command') do |topic,message|
    puts "#{topic}: #{message}"
  end
end

username, password には同様に Device ID と API Key を設定してください
また、Subscribe するトピックにも Device ID が必要になるので記載してください
記載できたら実行しましょう

  • bundle exec ruby sub_command.rb

エラーにならなければ Subscribe が始まります

ではコマンドを送信してみます
アプリシミュレータから REST 経由のコマンド送信できるのでアプリシミュレータを使います
起動してコマンド情報を入力し送信してみましょう
tinkermode_mqtt_send_command.png

すると以下のような感じで ruby スクリプト側でコマンドを Subscribe できると思います

/devices/808/command: {"action":"taction","parameters":{"key":1}}

最後に

TinkerMODE の MQTT エンドポイントを試してみました
当初はイベントとコマンドはどちらも pub/sub できると思っていたのですが、それぞれで pub/sub に制限があるということがわかりました

用途としてイベントはスマートモジュールと絡めて使うのがメインで、コマンドはデバイスのリアルタイムな遠隔操作 (メッセージの送信) に使うのがユースケースかなと感じました

参考サイト

2016年10月12日水曜日

Hakko RED のハンダごてのこて先を変更した

概要

こて先を変えただけですが、簡単にやり方を載せておきます
こての保存方法も紹介します

環境

付け替え方法

写真つきで紹介していきます

既存のこて先をはずす

まずは既存のこて先を外しましょう
先端部分にあるネジを緩めるだけでこてを外すことができます
exchange_handa0.jpg

写真だとわかりづらいですが、こて先はほぼサビてしまい全くハンダが載らない状態です
外すと以下のようになります
exchange_handa1.jpg

変更するこて先を袋から出す

今回変更するこて先です
東急ハンズや冒頭の環境部分の URL にあるように Amazon でも購入できます
exchange_handa2.jpg

包装は簡単で袋に入っているだけなので開封しましょう

こて先を付け替える

では、こて先を付け替えます
と言っても元あるところに差し替えて終わりです
差し替えたらネジを締め直しましょう
exchange_handa3.jpg

やはり新品なのでかなりキレイです

温めてハンダを載せる

こて先にハンダが載るか確認してみましょう
こて先を付け替えたら電源を入れてハンダごてを温めます
こて先が温まったらハンダをあててこて先に載るか確認しましょう
exchange_handa4.jpg

ハンダが載ったら電源を抜いてそのまま保管しましょう
こて先にハンダが載っている状態で保存しないとこて先はあっというまに酸化してサビて前と同じような状態になってしまいます
こて先に載っているハンダは仕様する直前にスポンジで落として利用します

一点注意としては保存するときにこて先にハンダを載せすぎないようにしてください
ハンダを載せすぎるとこて先を冷やしているときに予熱でハンダが溶けてしまいこて先が見えてしまい、そこが酸化してしまうためです

最後に

Hakko RED のこて先を交換する方法を紹介しました
こて先自体の交換は非常に簡単ですが、保管するときの方法は注意してください
保管時にこて先にハンダを載せることは必須ですが、こて先の根本の部分にもハンダがないとそこから酸化してしまうので、全体に載せるようにしてください
基本はこて先にハンダを載せると、熱で溶けてこて先全体に広がるはずです
むしろ広がらないと、もうその部分が酸化している可能性が高いのでリフレッサーなどを使って修復する必要があります

2016年10月5日水曜日

Xcode8 のエラーを解消してビルドできるようにした

概要

Elcaptain で Xcode8 にアップデートしました
案の定既存のプロジェクトがエラーだらけになったのでとりあえずエラーを解消させてビルドできるまで対応してみました
ライブラリ管理は Cocoapod だけ使っています

環境

  • Mac OS X 10.11.6
  • Xcode 7.3.1 -> Xcode 8.0 (8A218a)
  • Cocoapod 1.0.1

やったこと

コードに関して

1 - プロジェクトを選択 -> Target -> プロジェクト名 -> Build Settings -> Use Legacy Swift Language Version -> Yes

2 - Edit -> Convert -> To Current Swift Syntax -> Convert to Swift 2.3 を選択する

Xcode 起動時にもコンバートするかどうか聞かれるので、そこで Later -> Later と選択していれば上記は実施する必要なし

3 - Podfile の編集

Podfile の最後に以下を追記する

post_install do |installer|
  installer.pods_project.targets.each do |target|
    target.build_configurations.each do |config|
      config.build_settings['SWIFT_VERSION'] = '2.3'
    end
  end
end

追記したら再度 pod install し Xcode を開き直す

4 - Module file was created by an older version of the compiler

上記のエラーが発生したので Cmd + Alt + Shift + k でクリーンしsた

5 - NSBluetoothPeripheralUsageDescription について Info.plist について追記

Xcode8 でビルドして iTunesConnect にバイナリをアップロードしたら以下の警告がメールで来て弾かれた

This app attempts to access privacy-sensitive data without a usage description. 
The app's Info.plist must contain an NSBluetoothPeripheralUsageDescription key with a string value 
explaining to the user how the app uses this data.

どうやら Info.plist に以下を追記する必要があるらしい

Key -> NSBluetoothPeripheralUsageDescription
Value -> Advertisement would like to use bluetooth.

他にも Admob を使っている場合やカレンダーにアクセスする場合などいろいろなケースで説明が必要になるらしい
http://dev.classmethod.jp/smartphone/iphone/ios10-privacy-data-purpose-description/

Storyboard

Storyboard のベースデバイスを iPhone6s にする
すべての ViewController に対して Update Frames を掛ける必要がある

最後に

上記の内容だけ実施すれば自分のプロジェクトはとりあえずビルドできるようになりました
結局 Swift は 3.0 ではなく 2.3 を使っています
ライブラリが順次 3.0 に対応してきたら本体も 3.0 に上げる感じでしょうか
コードコンバートは自動で行ってくれるはずなので、そこまで大変な感じにならないといいのですが、、、

参考サイト

2016年10月4日火曜日

Arduino Pro mini で圧力センサを使ってみた

概要

Arduino Pro mini で圧力センサ (FSR402) を使ってみました

環境

  • Arduino Pro mini (5v/16MHz)
  • Arduino IDE 1.6.9
  • FSR402

配線

配線した写真は以下の通りです
fsr402_with_promini_circuit.jpg

特に難しいところはないですが簡単に説明すると

  • FSR402 カノード (赤) -> VCC
  • FSR402 アノード (白) -> 10KΩ -> GND
  • FSR402 アノード (白) -> A0

で今回電源の VCC は 3.3v を使っています
抵抗は 10KΩ以上あったほうが分解能の MAX (1024) まで近づけます
抵抗の値が小さいと FSR402 をつまんだときに中々値が上がりません

今回の場合、 AO をアノード側につないでいるので摘んでいない場合は 0v になります
つまむと電圧が発生して数字が増えていきます

スケッチ

アナログリードするだけです

int fsrPIN = 0;

void setup() {
  Serial.begin(9600);
}

void loop() {
  int ain = analogRead(fsrPIN);
  Serial.println(ain);
  delay(500);
}

スケッチが書けたらシリアル経由で書き込んでください

動作確認

シリアルモニタを開いて動作確認します
FSR402 をつまむと値が増えるのが確認できると思います

fsr402_with_promini_ret.png

最後に

Arduino Pro mini で圧力センサを使ってみました
アナログピンは 5v まで読み込めるので精度を上げたい場合は 5v のほうがいいかもしれません

2016年10月3日月曜日

heatmap.js を使ってみた

概要

heatmap.js はその名の通りヒートマップを簡単に作成することができる JavaScript のライブラリです
とりあえずブラウザだけで動作する簡単なサンプルを作成してみました

環境

  • Mac OS X 10.10.5
  • Apache httpd 2.4.12
  • heatmap.js 2.0.2

サンプルコード

作業は DocumentRoot 直下で行っているものとします

ライブラリのダウンロード

HTML の作成

  • cd heatmap
  • vim index.html
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="utf-8"/>
  <title>heatmap.js test</title>
  <link rel="stylesheet" href="heatmap.css"/>
</head>
<body>
  <div class="wrapper">
   <h2>Demo</h2>
    <div class="demo-wrapper">
      <div class="heatmap">
      </div>
    </div>
  </div>
  <script src="heatmap.min.js"></script>
  <script src="test-heatmap.js"></script>
</body>
</html>
  • vim heatmap.css
.demo-wrapper { 
    height:400px;
    background:rgba(0,0,0,.03);
    border:3px solid black;
}
.heatmap {
    width:100%;
    height:100%;
}

CSS ファイルでヒートマップを描画する領域のサイズを定義しています
この定義がないと後述のエラーになるので注意してください

test-heatmap.js はこのあと作成します

JavaScript の作成

  • cd heatmap
  • vim test-heatmap.js
// minimal heatmap instance configuration
var heatmapInstance = h337.create({
  // only container is required, the rest will be defaults
  container: document.querySelector('.heatmap')
});

// now generate some random data
var points = [];
var max = 0;
var width = 840;
var height = 400;
var len = 200;

while (len--) {
  var val = Math.floor(Math.random()*100);
  max = Math.max(max, val);
  var point = {
    x: Math.floor(Math.random()*width),
    y: Math.floor(Math.random()*height),
    value: val
  };
  points.push(point);
}
// heatmap data format
var data = { 
  max: max, 
  data: points 
};
// if you have a set of datapoints always use setData instead of addData
// for data initialization
// heatmapInstance.setData(data);
heatmapInstance.setData(data);

最後の heatmapInstance.setData でヒートマップを描画しています
その前に描画するデータ (data) をランダムで作成しています

動作確認

これで httpd を起動して http://localhost/heatmap にアクセスしてみてください
以下のようなサンプルが表示されると思います
try-heatmap.js-ret.png

画面をリロードするとヒートマップの状況が変わると思います

最後に

heatmap.js を使ってみました
あとはリアルタイムでの描画と組み合わせたり他の画像 (マップなど) と組み合わせると更におもしろい感じになるんじゃないかと思います

その辺も紹介できたら紹介したいと思います

Tips

実行時に Failed to execute 'getImageData' on 'CanvasRenderingContext2D': The source width is 0. というエラーが発生することがあります
その場合はヒートマップを描画する div クラスのサイズを確認してみてください
今回は demo-wrapper -> heatmap というクラスの div タブに描画していますが、このサイズが 0 以上のサイズでないと当該エラーが発生します
なので、今回のサンプルだと CSS ファイルの適用をサボるとエラーが発生します

参考サイト

2016年10月1日土曜日

AWS Cognito を使ってユーザのログインを試してみた

概要

前回 Cognito を使ってユーザの登録ができるところまで試しました
今回はその登録したユーザでログインするところを実装してみたいと思います

環境

  • Mac OS X 10.11.6
  • AWS Cognito 2016/09/30 時点
  • Apache httpd 2.4.18
  • Google Chrome 53.0.2785.116 (動作確認用)

事前準備

User Pool, Federated Identities の作成は前回の記事と全く同じなので、前回の記事を参考に作成してください
基本は AWS のマネージメントコンソールでポチポチしていけば OK です

必要なライブラリのダウンロードも前回と同じなので、そこまでは前回の記事を参考にしてください

ログイン処理の実装

登録したユーザでログインするための画面を実装します

  • cd /Library/WebServer/Documents/cognito
  • vim signin.html
<!DOCTYPE html>
<html >
<head>
  <meta charset="UTF-8">
  <title>signin</title>
  <script src="js/jsbn.js"></script>
  <script src="js/jsbn2.js"></script>
  <script src="js/sjcl.js"></script>
  <script src="js/moment.js"></script>
  <script src="js/aws-cognito-sdk.min.js"></script>
  <script src="js/amazon-cognito-identity.min.js"></script>
  <script src="js/aws-sdk.min.js"></script>
  <script src='js/jquery-3.1.1.min.js'></script>
  <script src='js/signin.js'></script>
</head>
<body>
<div>
<div>
<form>
  <h2>ログイン</h2>
  <label for="inputUsername" >ユーザー名</label>
  <input type="text" placeholder="Username" id="name">
  <label for="inputPassword">パスワード</label>
  <input type="password" placeholder="Password" id="password">
  <br />
  <input type="submit" id="login-button" value="ログイン"></input>
</form>
</div>
</div>
</body>
</html>

必要な js ファイルを読み込んでユーザ名とパスワードを送信するためのフォームを作成しています

  • vim js/signin.js
AWS.config.region = 'ap-northeast-1';
AWS.config.credentials = new AWS.CognitoIdentityCredentials({
  IdentityPoolId: 'ap-northeast-1:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx',
});
AWSCognito.config.region = 'ap-northeast-1';
AWSCognito.config.credentials = new AWS.CognitoIdentityCredentials({
  IdentityPoolId: 'ap-northeast-1:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'
});
var data = {
  UserPoolId: 'ap-northeast-1_xxxxxxxxx',
  ClientId: 'xxxxxxxxxxxxxxxxxxxxxxxxxx',
};
var userPool;
var cognitoUser;

$(function() {
  $("#login-button").click(function(event){
    event.preventDefault();
    var authenticationData = {
      Username : $('#name').val(),
      Password : $('#password').val()
    };
    var authenticationDetails = new AWSCognito.CognitoIdentityServiceProvider.AuthenticationDetails(authenticationData);
    userPool = new AWSCognito.CognitoIdentityServiceProvider.CognitoUserPool(data);
    var userData = {
      Username : $('#name').val(),
      Pool : userPool
    };
    cognitoUser = new AWSCognito.CognitoIdentityServiceProvider.CognitoUser(userData);
    cognitoUser.authenticateUser(authenticationDetails, {
      onSuccess: function (authresult) {
        alert('Login Success');
      },
      onFailure: function(err) {
        alert(err.message);
      },
    });
  });
});

前回と設定する箇所が異なるところが 1 点あります
ClientId の部分が前回は signup_app の App client id でしたが、今回は cognito アプリの App client id を指定してください
他の値は前回と同様で OK です

処理としてはログインボタンが押されたあとで authenticateUser をコールしてユーザ名とパスワードで認証します
問題なく認証できれば「Login Success」とダイアログで表示します

ログインできない場合の主な原因は

  • Incorrect username or password. -> ユーザ名とパスワードが違う
  • User is not confirmed. -> まだ認証許可が降りていない

辺りかと思います
2 つめの「User is not confirmed.」は User Pool の画面から設定することができます
登録されたユーザを選択し「Confirm user」を選択すると confirm され認証できるようになります
try_cognito_confirm_user.png

動作確認

では動作確認してみましょう
問題なく認証に成功すると以下のように表示されると思います
try_cognito_login.png

最後に

前回からの引き続きで今回は AWS Cognito を使ったログイン処理を試してみました
ユーザ登録後には Confirm してあげないとログインできない点がポイントだったかなと思います

とりあえず基本的な動作は確認できました
あとは、AWS のリソース制御やモバイル連携、各種 SNS サービスの認証と連携するあたりが実運用を考えると必要なパーツになるかと思います

今回はお試しとしてやってみただけなので、実際にサービスに組み込む機会があったらその辺りも検証してみたいなと思っています

参考サイト