読者です 読者をやめる 読者になる 読者になる

Arduino + RubyでプチIoT

本日はサークルの,後期プロジェクト活動報告会でした. 3Dの音楽ゲーム,VR,mrubyが扱えるマイコンの開発,SECCONの報告などなど楽しそうなものがたくさん.

うちの班は,ArduinoとRubyで植物管理システムを作りました.

備忘録も兼ねてちょっとメモ.

作ったもの

植物管理システム.

  • Webページから,植物にあたっている光の量,植物の湿り気,周りの温度を確認できる

  • 取得したデータはGoogle Spread Sheetに随時記録され,センサからのデータの変化を可視化出来る

作ったもののUIはこんな感じ.

f:id:McG:20160213164050p:plain

使ったもの

Arduino UNO: 各種センサから値を取得するのに必要.

Ruby: Arduino UNOとシリアル通信させて値を取得している.

Ruby on Rails: 受け取った値をWebページに表示させる.サーバサイドのスクリプトはRailsで書かれている.

センサ類: CdSモジュール, 土壌湿度センサ,温度センサを用いた.

使用センサの選定

今回,植物の状態を管理するシステムを作成するにあたって,「植物にあたっている光の量」,「植物周辺の気温」,「土壌の湿り気」の3つをとることが必要であったため,その目的にあったセンサを選定した.

  • CdSセル

植物にあたっている光の量を検出するために,CdSセル(硫化カドミウムセル)と呼ばれる素子を用いた.CdSセルは,受光する光の量に応じて抵抗値が変化するため,その特徴を生かしてあたっている光の量を検出することができるようになっている.

  • 温度センサ

植物周辺の気温を測定するための温度センサに関しては,Texas Instruments社のLM61CIZと呼ばれるセンサを使用した.このセンサは-30度から100度までを測ることができる.-30度~100度を300mV~1600mVの範囲で出力するため,Arduinoを用いて電流を測定することによって温度を得ることができる.

  • 土壌湿り気センサ

土壌の湿り気を検出するために,DFROBOT社の土壌湿度センサを用いた.土は,湿っている時と乾燥している時で抵抗値が変化するため,それを利用して土に含まれている水分量を測定することができる.

回路周り

回路図はこんな感じ.

f:id:McG:20160213170353p:plain

まぁ各センサの値をArduinoのアナログピンに繋げてるだけです.

配線考えるときに参考にしたサイトはこれ.

CdS周り

arduino使い方:CDSでLED点灯

土壌湿度センサ周り

Moisture Sensor (SKU:SEN0114) - Robot Wiki

温度センサ周り

http://www.geocities.jp/zattouka/GarageHouse/micon/Arduino/Temp/Temp.htm

データの受け渡し方

まず,温度センサ・光センサ・土壌湿度センサのそれぞれのセンサから取得したアナログ値をArduinoが受け取る.そして,ArduinoとPCがシリアル通信を行いデータを取得する.次に,送信されたデータをRubyの スクリプトを用いてテキストファイルに書き込む.その書き込まれたデータをもとに,後述のGoogle Drive APIを用いて,Google Spread Sheetでグラフを生成する.そして,そのグラフとデータの値をWebサイトに反映させることによって,ユーザが植物の状況を監視できるようになっている.

Google Spread Sheetとの連携

今回,上記にも述べた通りにデータの収集と可視化を行うために,Google Spread Sheetを用いて値を整理,グラフ化を行った.グラフはデータを受信する度に更新されるため、リアルタイム性があり,かつ植物にあたっている光量の変化量などが一目でわかるようになっている.そのグラフを共有機能でWebサイトへ埋め込むことで利便性の向上を図った.Google Spread Sheetへデータを書き込む際はGoogle Drive APIを用いてRubyのスクリプトから書き込みを行う方法を取った.

gem install google_driveを行うとGoogle Driveのgemを使えるようになる.

qiita.com

詳しくはこのあたりを参照.

require 'openssl'
require "google_drive"

OpenSSL::SSL::VERIFY_PEER = OpenSSL::SSL::VERIFY_NONE

client = Google::APIClient.new
auth = client.authorization
auth.client_id = "取得したclient_id"
auth.client_secret = "所得したclient_secret"
auth.refresh_token = "取得したrefresh_token"
auth.fetch_access_token!
session = GoogleDrive.login_with_oauth(client)
ws = session.spreadsheet_by_key("スプレッドシートのkey").worksheets[0] #keyはスプレッドシートのURLから取る

loop{
    count = ws.num_rows+1
    doc = File.open("data.txt").read
    i = 0
    doc.split("\n").each do |line|
      case i % 3
      when 0
        $temp = line
      when 1
        $lite = line
      when 2
        $soil = line
      end
      i += 1
    end

    temperature = $temp
    light = $lite
    humidity = $soil

    ws[count, 1] = "#{count-1}"
    ws[count, 2] = "#{Time.now.to_s}"
    ws[count, 3] = "#{temperature}"
    ws[count, 4] = "#{light}"
    ws[count, 5] = "#{humidity}"
    ws.save()
    sleep 5
}

こんな感じで,テキストデータからの情報をとってきてスプレッドシートにあげる. 上のコードの,スプレッドシートのkeyっていうのは,以下の画像のaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaのところをコピペする. f:id:McG:20160213171619p:plain

RubyとArduinoでシリアル通信

Arduino側で,以下のようなコードを記述

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

void loop() {
  ch = Serial.read();
  if(ch == 'a'){
    int bri = analogRead(A0);
    int temp = analogRead(A1);
    int moist = analogRead(A2);
    Serial.println(temp);
    Serial.println(bri);
    Serial.println(moist);
    Serial.println();
  }
}

Ruby側では,SerialPortのgemが必要になる.こちらを参考にする. 橋本商会 » Rubyでシリアルポートを使う(最新版)

require 'rubygems'
gem 'serialport','>=1.0.4'
require 'serialport'

sp = SerialPort.new(port, 9600, 8, 1, SerialPort::NONE)

temp = sp.readline
lite = sp.readline
soil = sp.readline

と,こんな感じにRubyのスクリプトを書いてやればArudinoから取ったデータをrubyでいじれるようになる.

あとはこれをRailsとかでいい感じにWebに表示してあげたら完成.

© 2016 Yuki Sako.