大人がAkerunでIoT鬼ごっこしてみたら最高に楽しかった

Akerun Advent Calendar21日目の記事です。

※ 本記事は Photosynthエンジニアが主催しているイベント記事です。Akerunを本来の目的以外に使用しないでください。

今回はフォトシンス社員有志で、オトナのガチ鬼ごっこをやってきた報告です。

ところで、フォトシンスはIoTサービスを提供している最先端の会社です。

したがって普通の鬼ごっこで満足できるはずがありません。

鬼ごっこもIoTじゃないとね。ええ。

というわけで

Akerun で 鬼ごっこしてみた

f:id:photosynth-inc:20171224230320j:plain

今回の戦場はこちら

SWEET GLASS @北軽井沢

f:id:photosynth-inc:20171224230842j:plain

f:id:photosynth-inc:20171224231058p:plain

参加者登録

Akerunには、写真と名前を設定する機能があります。

f:id:photosynth-inc:20171224231218j:plain

この機能を使って参加者を登録してみましょう。

参加してくれた猛者たち。

f:id:photosynth-inc:20171225090740p:plain

ルール

  • 鬼は逃げまどう人々のAkerunをアプリであけて捕獲ください
  • 捕獲したらSlackで通知が飛びます
  • 捕獲されたら鬼に変わります。10秒間その場でフリーズして再開してください
  • 15分経過で鬼だった人が負けです

ルール説明です。真面目に聞いてます。

若干ろくろを回しているのがゲームマスターのぼくです。

f:id:photosynth-inc:20171224232138j:plain

やってみた

鬼はスマホ片手に追いかけてます。

f:id:photosynth-inc:20171225151947p:plain

BLEで捕まえるのでこんな光景も。

f:id:photosynth-inc:20171225152022p:plain

捕まったらslackで通知が飛びます。IoTです。ゲームマスターは走らなくても誰が鬼なのか監視できますね。楽でいいですね。

f:id:photosynth-inc:20171224232850p:plain

f:id:photosynth-inc:20171224232741p:plain

やってみた考察

  • 楽しい
  • 走っているとBLEでなかなか接続できない。これは想定外でした。Central、Peripheral双方が移動していることで、掴みが悪くなっていそうです。
  • 大人がAkerunとスマホをもって鬼ごっこをしていると、こどもたちが興味津々にみてくる(が声はかけられない
  • 大人がAkerunとスマホをもって鬼ごっこをしていると、若者たちも興味津々にみてくる(が声はかけられない
  • 楽しい

事件発生

疲れ果ててコテージに向かっていた参加者たちですが、

「あれ、、、鍵がない。。。」

なんと、はしゃいでいるうちに鍵を落としてしまったようです。(実話)

f:id:photosynth-inc:20171224234000p:plain

今回は幸いすぐにみつかりました。

ですが、物理鍵ってこわいですね。

スマホで鍵をあけられたらいいのに。

後付で設置できたらいいのに。

ん? そんなIoT製品あったような?(ステマ

Akerun設置してみた

f:id:photosynth-inc:20171224233714j:plain

f:id:photosynth-inc:20171224233831j:plain

ばっちり設置できました。もちろん原状回復できます。外出時の鍵の受け渡しも不要になりました。最高か。(ステマ

おわりに

軽井沢でもAkerunがばっちり使えることがわかりましたね。また、IoTのエンターテインメント的な可能性を感じました。

あと、SWEET GLASS さんはとっても快適に楽しめたのでぜひ皆様遊びに行ってください。

告知

弊社ではエンジニアを募集しています!

www.wantedly.com

Akerunをクリスマス仕様にする(前編)デザイナーとの懸け橋ツールで捗った話

こちらは Akerun Advent Calendar 2017の記事です。

聖なる夜にこんばんは。 yuyakmです。

クリスマスということで、日々接するAkerun Proをクリスマス仕様にしてみたいと思います。

今回は、クリスマスといえばイルミネーションといういことで、LEDパターンを変えてみたいと思います!

製品の点灯パターンについてはこちらの動画をご覧ください。

youtu.be

Akerun ProのLED仕様

①フルカラーのLEDを4灯搭載

左上                   右上
LED1(R, G, B)         LED4(R, G, B)

左下                   右下
LED2(R, G, B)         LED3(R, G, B)

②各 RGBは8bit(0-255)の幅で明るさを設定することができる

ディスプレイのように任意の色を表現することができます。

スペック上は、256 * 256 * 256 = 16,777,216通りの色が表現できます。

③4灯のLEDの色を個別に更新できる

例えば、20msecおきに色を更新することでリフレッシュレートが50Hzのディスプレイのようにふわっと点灯させたり色をじわーっと変える表現ができます。

点灯パターンを考える

今回は、3つの点灯パターンをこんな感じに変更してみたいと思います。

1. 接続時

→赤・緑のクリスマスカラーでふわっと点灯

2. 施錠時

→赤・黄のイルミネーション風点滅をした後に、サンタ帽イメージカラー(赤・白)で点灯して消える

3. 解錠時

→緑・黄のイルミネーション風点滅をした後に、もみの木イメージカラー(緑・白)で点灯して消える

点灯パターンをつくってみる

@ishturk さんが便利なツールをつくってくれているのでそれを使ってつくります。 タイトな開発スケジュールの中、こういう社内連携用の機能もサクッとつくって提案してくれてホント最高。 f:id:photosynth-inc:20171224220613j:plain

点灯パターン検討の流れ

1. スプレッドシートでデータ作成

自動的にPro用データに変換してくれる!

2. 作成されたPro用データを専用Proに流し込む

確認&調整がエンジニアなしでできる!

3. 完成したら@ishturkさんにOTAイメージをつくってもらって実機で運用

いつも近くにいて一瞬でやってもらえるのもありがたい…

作成データ例

こんな感じでセルに値を入れるだけでできます。

リフレッシュのインターバル時間も入力できるので表現の幅が広がる~ f:id:photosynth-inc:20171224220619j:plain

点灯させてみた

こんな感じになりました

youtu.be

けっこうクリスマスっぽい!雪が積もったもみの木(解錠)とサンタ帽(施錠)に見えないこともない。

色の変化のスピードや微妙なグラデーション変化を何度かトライして改善しました。

また、今回の試行錯誤で24Hz(fps)以下にすると映像と一緒で明確にカクカク感を感じることを実感。

社内向けに適当に作った割には良いのではないでしょうか。

ただし施錠パターンについては、最初はサンタ帽に見えたけど今はモンスターボールにしか見えない…

製品でLED点灯パターンを考える上でのTIPS

今回はネタ記事ですが、TIPS的なことをざっくり紹介します。

そもそもLEDに頼りすぎない

LEDのインジケーターで表示できる情報量には限りがあるので、できるだけシンプルな方が良いです。 アクセシビリティの観点で、色がわからない・光が見えない人でも使えることを考慮しましょう。

微妙な色の違いはユーザーは気づかない前提で考える

例えば、赤と朱色で意味が違うことに気づいてもらうのは難しいです。色にメッセージ性を持たせたい場合は、明確に色が違うと感じるレベルで色を変えると良いです。

色のパターン例

LEDで色に意味を持たせる場合の色の選び方を紹介します。例えば、電話で使い方を説明する場合に言葉で説明しても認識がずれにくいと思います。

<基本>
  • ◯赤(R:100%, G:0%, B:0%)
  • ◯緑(R:0%, G:100%, B:0%)
  • ◯青(R:0%, G:0%, B:100%)
  • ◯黃(R:100%, G:100%, B:0%)
  • △紫(R:100%, G:0%, B:100%)(赤紫や青紫に偏ることがあるので避けた方が無難かも)

これをベースにしてデザイナーの意図する色に微調整すると良いのではないでしょうか。

<NG>
  • ✕白(R:100%, G:100%, B:100%)

→RGBのそれぞれを100%で点灯しても人間の視覚上白に見えるバランスで点灯するとは限らないため 環境光の色温度等によっても影響を受ける(青白く見えたりオレンジ色に見える)ため

  • ✕シアン(R:0%, G:100%, B:100%)

→青と混同されるおそれがあるため

※勿論、グラデーションの表現をしたり微妙な色味を調整するのはOKです

モニタのRGBとLEDの色は違うと認識する

RGBの値が同じなら同じ色になるわけではありません。AkerunProでは実機の発色を見ながら調整しました。

個体差による色のバラつきがあることを認識する

モノなので多かれ少なかれ色のバラつきは生まれます。細かいことを言うと、同じ基板上の4灯のLEDも全く色や明るさで光ることはできません。仕様の時点で色のバラつきの許容度は大きい方が良く、色を管理したい場合は別途検査やキャリブレーションの方法を考えましょう。

少しでも電池持ちを良くするために

*  点灯時間をできるだけ短くする
*  必要最低限の明るさにする
*  消費電力が大きい色は長時間点灯させない

白(255, 255, 255)>黄(255, 255, 0)>青(0, 0, 255)>赤(255, 0, 0)の順番で消費電力が大きい。

まとめ

  • デザイナーとエンジニアの架け橋となるツールをつくることで生産性アップ
  • エンジニアなしで気軽にトライできる環境があることで生まれるものがある

次回は筐体の装飾的にクリスマス感を上げた記事を紹介したいと思います。

求人

フォトシンスでは、他レイヤーと協力しながら一緒にものづくりができるエンジニアを募集しています! www.wantedly.com

google spread sheetでRedmineのチケットを操作してみる

こんにちは。Akerunエンジニアの @ishturk です。

Akerun Advent Calendar17日目の記事です。遅刻です。

弊社ではプロジェクト管理にRedmineを活用しています。

ありますよね?

さて、

チケットの内容をspreadsheetで表示したいと思ったことありませんか?

チケットをspreadsheetから発行したいと思ったことありませんか?

ありますよね?ありまくりますよね?

二重管理になるじゃん、、、と思ったアナタ!Redmineをマスターデータとしていれば二重管理は防げるのです!

たとえばこんな機能

  • チケット番号を入力して、タイトル、内容、担当者が表示する
  • spreadsheetに内容を入力したら「チケット発行」ボタンでチケット発行できる

これは捗りますね!

それ、API + GASでできます

実はRedmineにはREST APIが用意されており、チケットの参照・発行・編集など色々な事ができます。

REST API — Redmine用語解説

google spreadsheetには google apps script(GAS)と連携できます。

developers.google.com

Redmineの設定

上に貼ったリンクにも書いていますが、REST API を使用するにはRedmineのシステム管理者権限で有効にする必要があるので、管理者にお願いをしてください。有効にさえしてもらえば、使うのは一般ユーザーで大丈夫です。

「アクセスキー」が表示されてない場合は、無効になっている可能性が高いです。

チケットを参照するGASを書いてみる

番号からチケットタイトルを取得する

function ticket_name(id){
  var url = "https://redmineのURL/issues/" + id + ".json?key=個人のアクセスキー";
  // basic認証をかけている場合はヘッダに認証情報を入れる
  var user = "ユーザー名";
  var pass = "パスワード";
  var options = {
    "headers" : {"Authorization" : " Basic " + Utilities.base64Encode(user + ":" + pass)}
  };
  var response = UrlFetchApp.fetch(url, options);
  var results = JSON.parse(response.getContentText()); //レスポンスをjson解析してresultsを取り出す
  return results.issue.subject
}

ベーシック認証をかけている場合はヘッダに認証情報を付与します。(自分は素人なのでココでハマりました) アクセスキーを使うので、Redmine自体のユーザーid/passwordは不要です。 取得できる内容は以下を参照してくださいね。

www.redmine.org

チケットを作成する

function createIssue() {
  var redmine_url = 'https://RedmineのURL/issues.json';
  var project_id = プロジェクトのid
  var owner = チケット発行者のid
  var issue = {
    'subject': 'タイトル',
    'description': '説明',
    'tracker_id': トラッカーid
    'assigned_to_id': アサインするユーザーのid,
    'status_id': 7,  セットするステータスのid
  }
  var payload = {
    'issue': issue, 
    'project_id': project_id,
  };
  payload = JSON.stringify(payload);
  var user = "ユーザー名";
  var pass = "パスワード";
  var headers = {
    "Authorization" : " Basic " + Utilities.base64Encode(user + ":" + pass),
    'X-Redmine-API-Key': 個人のアクセスキー,
    'X-Redmine-Switch-User': owner,
    'Content-Type': 'application/json',
  };
  var options = {
    'method': 'POST',
    'headers': headers,
    'payload': payload,
    'contentType': 'application/json',
    'muteHttpExceptions': true
  };
  var response = UrlFetchApp.fetch(redmine_url, options);
  return response;
}

issue変数でチケットの諸々の値を設定しています。この辺の値をセルから取得するようにすれば、任意の内容でチケット発行ができますね。もちろん、カスタムフィールドも設定可能です。

実際に運用しているとチケットオーナーを 指定したいことが多々あるので、指定できるようにしています。この方法もちょっとハマりました。

また、プロジェクトのid、トラッカーのid、ユーザーのidなど、数値で指定しなくてはなりません。 調べる方法はいろいろあるので、またどこかでまとめたいと思います(本記事では割愛します)

チケット参照してみた

f:id:photosynth-inc:20171224203746g:plain

こんな感じでサクサク動きます。 捗りますね。

おわりに

RedmineREST APIや、GASなど、非webエンジニアでも気軽に触れる環境が増えて、とても楽しい今日このごろです。

プロマネも、この辺りのエンジニアリングできると楽しくなるんじゃないでしょうか。躓いたときにwebエンジニアに相談すると会話もはずんでますますプロジェクトが捗りますね。

告知

弊社ではエンジニアを募集しています!

www.wantedly.com

腰に優しいIoTテスト 〜 Akerunつくったエンジニアのそこそこ大規模なIoTプログラミング 〜

こんにちは。Akerunエンジニアの @ishturk です。

Akerun Advent Calendar13日目の記事です。

弊社フォトシンスは、ご存知のようにAkerunProKitというIoTサービスを提供しています。

昨年はラズパイを使った腰に優しい開発方法を紹介しました。

akerun.hateblo.jp

今回はさらに踏み込んで自動テストまで組み込んだ話です。

構成

  • akerun web APIs
  • AkerunProの動作ログをモニタリングする治具
  • ラズパイ
    • Logger
    • テストランナー

f:id:photosynth-inc:20171222175050p:plain

akerun web APIをコールするとAkerun Remote を経由して、指示がAkerun Proに到達して処理を実行します。 Loggerは起動後テキストでファイルに吐き出し続ける構成にしています。 テストランナーでAPIをコールし、Logに期待する結果するまで待つという構成です。 テストランナーはGoを使って書いてみました。

コード

package main

import (
    "fmt"
    "strings"
    "os/exec"
    "strconv"
     "encoding/json"
     "io/ioutil"
     "log"
     "net/http"
     "net/url"
)

func isWait(current int) bool {
    cmdstr := "wc -l autotest_log.log | cut -d \" \" -f 1"
    out, err := exec.Command("sh", "-c", cmdstr).Output()
    _ = err;
    s := string(out)
    s = strings.TrimRight(s, "\n")
    filelen, err := strconv.Atoi(s)
    if (current > filelen) {
        return true
    } else {
        return false
    }
}

func callAPI() {
     values := url.Values{}
     values.Add("param", "hogehoge")
     client := &http.Client{}
     req, err := http.NewRequest("POST", "https://あけるんAPI/hoge/hogera", nil)
     if err != nil {
          log.Fatal(err)
     }
     req.Header.Add("Authorization", "Bearer hogehogehogehogehogehogehogehogehogehogehogehogehogehogehoge")
     req.URL.RawQuery = values.Encode()
     res, err := client.Do(req)
     if err != nil {
          log.Fatal(err)
     }
     defer res.Body.Close()
     if res.StatusCode != http.StatusOK {
          log.Fatal(res)
     }
     body, err := ioutil.ReadAll(res.Body)
     if err != nil {
          log.Fatal(err)
     }
}

func isContain(line int, interval int, str string) bool {
    cmdstr := "sed " + strconv.Itoa(line) + "," + strconv.Itoa(line + interval) + "p autotest_log.log"
    out, err := exec.Command("sh", "-c", cmdstr).Output()
    _ = err;
    if (strings.Contains(string(out), str)) {
        return true
    } else {
        return false
    }
}

func main() {
    line := 0
    interval := 20
    timeout := 6000
    count := 0
    for count < timeout {
        if (isWait(line)) {
            continue
        }
        if (isContain(line, interval, "期待するログ")) {
            break;
        }
        count++
        line += interval
    }
    if (cout < timeout) {
        fmt.Println("PASS")
    else {
        fmt.Println("FAIL")
    }
}

APIは認証ヘッダ、パラメータ付与などしてPOSTしてます。もちろんいろいろできます。ggったらいろいろできるのでお試しあれ。 また、ログファイルの監視は sed コマンドを使って順番にキャプチャする方法で実現しました。無理してます。もっといい方法がある気がします。

おわりに

今回は APIを使ってE2Eテストを書いています。APIさえあればいろんなテストバリエーションを自動化できるのでいいですね。 エンジニアが拘束される作業時間が短くなるのでとても腰に優しいです。

また、Goは初めてコードを書いたのですが、とても書きやすいですね。組み込み畑のエンジニアがAPIをカジュアルに叩きたい場合は、オススメです。

告知

弊社ではエンジニアを募集しています!

www.wantedly.com

【15分解説】Bluetooth 4.2 → 5 でなにが変わったか?

す〜( @ksksue )です。

"私が知っているのは、自分が何も知らないということだけだ。" ― ソクラテス

ということでBluetooth 5についてまじめに調べました。

Bluetooth 4.2 → 5でなにが変わったのかを、Bluetoothの仕様書を読み解いてスライド10枚ちょっとにまとめています。 理解しにくい点を噛み砕いて解説しています。

※ フォトシンスで8月頃に実施した社内15分勉強会の資料

告知

フォトシンスではエンジニアを募集中

www.wantedly.com

Redmineでカンバンを見やすくしたら3倍捗った話

こんにちは。Akerunエンジニアの @ishturk です。

Akerun Advent Calendar11日目の記事です。

みなさん、スクラムしてますか?

弊社ではプロジェクト管理にRedmineを活用しています。

背景はこちら。

kazuph.hateblo.jp

僕のレイヤーでは開発はAgile(っぽい)進め方をしています。

RedmineAgile 。結構多いのではないでしょうか。そして僕らが悩んだようなコトを同じように悩んだ経験があるのではないかと。

  • デイリースタンドアップが、なんとなくだるい
  • カンバンツールとチケットが2重管理になって詰んだ
  • 付箋でカンバンをやっていたが、字が汚くて詰んだ←
  • アサインミスでチケットが迷子になって漏れた
  • イテレーションが終わったのにチケットがたくさん残っている

それ、解決しましょう。

プラグインの導入

チケットをカンバン化するプラグイン

www.redmine.org

最初は無料のLite版を使っていましたが、最近ボスにおねだりをしてPRO版を導入しました。

ユーザーに顔(アバター)を表示するプラグイン

これがとても重要です。 わかりやすさが3倍になります。アバターは赤くなくても大丈夫です。

github.com

はじめの一歩 バージョンの作成とチケットへの設定

僕のおすすめの運用は、イテレーション毎に、Redmineの標準機能の「バージョン」を作成します。最低、直近のイテレーションバックログ分を作成しましょう。

f:id:photosynth-inc:20171212004824p:plain

タスクをチケット化するときは作成したバージョンを設定します

f:id:photosynth-inc:20171212005320p:plain

できたカンバンがこちら

f:id:photosynth-inc:20171212005339p:plain

見やすいです。弊社では毎朝このカンバンをiPadと大型ディスプレイでミラーリング表示してデイリースタンドアップを実施しています。 ここでアバターを設定しておくと、カンバンに表示されます。責任感が3倍です。

f:id:photosynth-inc:20171212005625p:plain

動きます。だいたいその場でスクラムマスターがステータス更新してます(良いとは言ってない)

f:id:photosynth-inc:20171212005811p:plain

なんと!アサインもドラッグでいけます。アバター大活躍です。(機能自体はアバターがなくても使えます)

(弊社環境では他のプラグインが干渉してドラッグしたメンバーがカンバンの裏に行っていまいますがw ちゃんと使えます)

また、Lite版では以下の機能がないです。

  • チケットカンバン、ステータスなどの色分け
  • チケットステータスの2段(SubColumn)表示
  • カンバンのSwimLaneの設定
  • カスタムクエリの保存
  • チケットカンバン表示数(500制限)

弊社は最初に表示500制限にぶちあたり、PRO版を導入しましたが、期待以上に見易くなってgoodです。

なんとなくやっていたデイリースタンドアップの効果が大幅に上がっていることを実感できています。

体感3倍です。赤くなくても大丈夫です。

チケット全体の見通しも良くなるので漏れもなくなりました。

イテレーションが終わったら

振り返りと同時に持ち越しチケットを次のバージョンに移動しましょう

f:id:photosynth-inc:20171212005942p:plain

おわりに

Redmineでカンバンを活用するツールとして紹介しました。

僕的には先天的にとても字が汚いので、とてもとても重宝しています。

また、PRO版の本領は各種Agileに使えるチャート系の機能が拡充されていますが、そちらはまだ使いこなせていないので、またどこかで。

告知

弊社ではエンジニアを募集しています!

www.wantedly.com

治具に役立つ RPi3 x node x I2C電子部品 3選

回路設計・ファーム開発担当のす〜(@ksksue)です。

技術を磨くな、治具を作れ

ということで今回は基板検査治具で役立った電子部品の話題です。

治具はざっくり以下のような構成をよく取ります。

  • Raspberry Pi 3 : 汎用性が高い、Webと親和性が高い、nodeが使える
  • nodejsでドライバ設計 : C/C++等に比べ圧倒的に開発スピード早い、Webと親和性が高い
  • センサは秋月・ストリナ・スイッチサイエンスなど市販モジュールを使用 : 入手性が良い、壊れてもすぐ交換/購入できる
    • 通信方式はなるべくI2C : SW側でインタフェース統一できる

開発スピード早く、組合せでさっと環境が整うのが良いです。

よく使っているI2C電子部品は以下の3つ

  • IOエキスパンダ
  • ADC
  • 電流センサ

それぞれ1つずつ紹介していきます。

IOエキスパンダ

f:id:photosynth-inc:20171210032702j:plain

16bit I2C I/Oエキスパンダー MCP23017: 半導体 秋月電子通商 電子部品 ネット通販

RPiのIOを使えばOKといえばOKなのですが

  1. RPiのIOピンだけだと足りない
  2. RPiのピン保護(故障した場合IO Expanderの交換でOK)

という理由でIO Expanderを使う場合があります。

16個のIOが増えるので重宝します。

ライブラリコードは以下

var i2c = require('i2c-bus');
var debug = require('debug')('IoEx');

const IOEX_ADDR = 0x20;
var self;

const IOEX_BANK_A_GPIO = 0x12;
const IOEX_BANK_B_GPIO = 0x13;

const IOEX_GPIO_HOGE_ON = 0x01;

function IoEx() {
  if(!(this instanceof IoEx)) {
    return new IoEx();
  }

  self = this;
  this._i2c = i2c.openSync(1);
  this._i2c.writeByteSync(IOEX_ADDR, 0x00, 0xFF); // BANK A 全て input
  this._i2c.writeByteSync(IOEX_ADDR, 0x01, 0x00); // BANK B 全て output
}

function setGpio(gpioVal) {
  let val = self._i2c.readByteSync(IOEX_ADDR, IOEX_BANK_B_GPIO);
  val = val | gpioVal;
  self._i2c.writeByteSync(IOEX_ADDR, IOEX_BANK_B_GPIO, val);
}

function clearGpio(gpioVal) {
  let val = self._i2c.readByteSync(IOEX_ADDR, IOEX_BANK_B_GPIO);
  val = val & (~gpioVal);
  self._i2c.writeByteSync(IOEX_ADDR, IOEX_BANK_B_GPIO, val);
}

function readGpio(gpioVal) {
  let val = self._i2c.readByteSync(IOEX_ADDR, IOEX_BANK_A_GPIO);
  val = val & gpioVal;
  if(val === 0) {
    return 0;
  } else {
    return 1;
  }
}

IoEx.prototype.setHoge = function() {
  setGpio(IOEX_GPIO_HOGE_ON);
}

IoEx.prototype.clearHoge = function() {
  clearGpio(IOEX_GPIO_HOGE_ON);
}

module.exports = new IoEx();

使う時

var ioex = require('./lib/IoEx');

// Hoge ピン ON
ioex.setHoge();

// Hoge ピン OFF
ioex.clearHoge();

ADC

このADCは12ビット4チャネルと精度そこそこでチャネル数が多いので汎用性が高いです。 npmにドライバがあります。

f:id:photosynth-inc:20171210040416j:plain

ADS1015使用12ビット4チャンネルADコンバータ(プログラマブルゲインアンプ付): 半導体 秋月電子通商 電子部品 ネット通販

先述したとおりnpmモジュールがあるのでインストール

npm i node-ads1x15 --save

それを使いやすくラップ

var ads1x15 = require('node-ads1x15');
var deasync = require('deasync');
var debug = require('debug')('Ads1015');

const CHANNEL_3_3V = 2;

const ADC_SAMPLES_PER_SECOND = '250';
const ADC_GAIN_AMP = '4096';

function Ads1015() {
  if(!(this instanceof Ads1015)) {
    return new Ads1015();
  }

  self = this;
  this._adc = new ads1x15(0); // 0 for ads1015, 1 for ads1115
  this._done = false;
  this._result = false;
}

function readAdc(channel, callback) {
  if(self._adc.busy) {
    return process.nextTick(function() { callback(new Error('ADC is busy')); });
  } else {
    self._adc.readADCSingleEnded(channel, ADC_GAIN_AMP, ADC_SAMPLES_PER_SECOND, function(err, data) {   
      if(err) {
        console.error(err);
        self._result = 0;
        self._done = true;
        if(callback) { callback(err); }
      } else { 
        debug('data : ' + data + ' mV');
        self._result = data;
        self._done = true;
        if(callback) { callback(null, data); }
      }
    });
  }
}

Ads1015.prototype.read3V = function(callback) {
  readAdc(CHANNEL_3_3V, callback);
}

Ads1015.prototype.readSync3V = function() {
  readAdc(CHANNEL_3_3V, null);
  deasync.loopWhile(function(){ return !self._done; });
  return self._result;
}

module.exports = new Ads1015();

使う時

var adc = require('./lib/Ads1015');
result = adc.readSync3V();
console.log(result + 'mV');

結果

3300mV

電流センサ

f:id:photosynth-inc:20171210044612j:plain

INA226PRC 【精密タイプ】I2Cディジタル電流・電圧・電力計モジュール - INA226PRC - ネット販売

0.1mAの分解能で電流値をセンシングすることができます。

電源ラインに流れる電流値の確認に使用しています。

詳細な使い方はストロベリーリナックスさんのモジュール説明書参照してもらうとして。。。

ライブラリコードは以下

var i2c = require('i2c-bus');
var debug = require('debug')('Ina226');

const INA226_ADDR = 0x41;

const MA_PER_LSB = 0.1; // 1 LSB 当たりの mA
const MV_PER_LSB = 1.25; // 1 LSB 当たりの mV

const INA226_CURRENT= 0x01;
const INA226_VOLT= 0x02;

var self;

function INA226() {
  if(!(this instanceof INA226)) {
    return new INA226();
  }

  self = this;
  this._i2c = i2c.openSync(1);
}

function i2cRead(cmd) {
  let buf = new Buffer(2);
  self._i2c.readI2cBlockSync(INA226_ADDR, cmd, 2, buf);
  debug(buf);
  return buf.readInt16BE();
}

INA226.prototype.readCurrentMa = function() {
  let val = i2cRead(INA226_CURRENT);
  debug('current raw : ' + val);
  return (val * MA_PER_LSB);
}

INA226.prototype.readVoltMv = function() {
  let val = i2cRead(INA226_VOLT);
  debug('volt raw : ' + val);
  return (val * MV_PER_LSB);
}

module.exports = new INA226();

使い方

var isense = require('./lib/Ina226');
result = isense.readCurrentMa();
console.log(result + ' mA');

結果

52.2 mA

配線

そういえばRPiとの繋ぎを描いてなかったので 以下の絵のように Raspberry Pi 3と繋ぐことで使えます。プルアップ抵抗描いてませんが適当(2.2k - 10k)な値のものを入れればOKかと。

I2Cで統一するとなにかとラクですね。

f:id:photosynth-inc:20171210044036p:plain

告知

フォトシンスではエンジニアを募集しています

www.wantedly.com