平成 27 年度 卒業研究卒業論文
Raspberry Pi を用いた農業支援システム
自動灌水と定点観測をお手軽に構築
近畿大学工学部 情報システム工学科
学籍番号 12140960085 岡田裕樹
2016 年 2 月 8 日提出
目次
1 研究背景と目的 2 本論に入る前に 2.1 農業について 2.2 次世代農業とは 3 本論
3.1 農業支援システムについて 3.1.1 実装する機能
3.1.2 得られるメリット 3.2 画面説明・機能説明 3.2.1 定点カメラ 3.2.2 アルバム 3.2.3 連続再生 3.3 製作計画の変更点 3.4 製作結果
3.5 苦労した点 3.6 課題 4 技術要素 4.1 開発環境
4.2 Raspberry Pi(ラズベリーパイ)
4.2.1 OS Raspbian(ラズビアン)
4.2.2 GPIO
4.2.2.1 RaspberryPiのGPIO配置図 4.2.2.2 GPIOPIN各種説明
4.3 Apache 4.4 mjpg-streamer 4.5 HTML5 4.6 PHP 4.7 CGI 4.8 Python 4.9 JavaScript
4.10 シェルスクリプト 4.11 Bash
5 終わりに 6 謝辞
7 参考文献・引用 8 付録
1 研究背景と目的
私の祖父は農業従事者であり,子供の頃からその手伝いをしていた.農作業を経験していくう ちに農業に興味を持ち,農業について学習するために農業高校へと進学した.しかし,そのまま 農業を始めたり農業大学へと進学するわけではなく,農業と全く別の分野である情報技術に興味 を持った.
IT社会と呼ばれている現代社会では,情報技術を駆使することが競争社会で生き残るための1 つの方法ではないかと私は考えた.そのため,これから何をするにしても情報技術を活用するこ とは必要だと考え,今の近大工学部情報システム工学科へと進学し,情報技術を学習している.
2つの異なった分野からヒントを得て,情報技術を農業に組み合わせることによって農業を活 性化させることに繋がるのではないかと考えた.そして今回,人が農業を嫌う理由について追求 し,原因を軽減させることを目的とした情報技術の研究を進めることにした.
情報機材としては,低コストで応用の幅が広いということでRaspberry Piを採用した.
2 本論に入る前に
以下は本論に入る前に一読していただきたい文章である.
2.1 農業について
生きる上で必ず必要な「食」を提供する職業なのだが,農業従事者の減少や高齢化が進むな ど,様々な問題を抱えている.[1][2]
表1を見ると,人口の総数が昭和25年から平成20年にかけて増え続けたが,平成20年をピー クに年々減少し続けている.年少人口は昭和30年以降減り続けている.子供が減っているのは 最近の話だと思われがちだが,実はもっと昔から減り続けているということがわかる.一方で,
老年人口は昭和25年から増え続けており,少子高齢化が昔から続いていることがわかる.
表2では,農業の就業人口を表している.平成21年からのデータであるが,農業就業人口は 年々減り続け,平均年齢が上がっている.ここにも少子高齢化の影響が見て取れる.
表3では新規就農者数を表しており,6万人前後で増える年もあれば減る年もある.しかし,
平成25年は急に落ちており,新規就農者数が減りつつあるのかもしれない.
新規就農者が増えない原因として挙げられるのは,土地を購入する費用や農業機械を購入する 費用としての初期投資が大きいことである.また,農作物は天候や気温,湿度などの自然環境に も大きく影響されるため,確実な収入が見込めない職業でもあるということもある.これらの問 題を解決できない限り新規就農者は減る一方で,農業が発展することもなく衰退していくばかり だろう.
2.2 次世代農業
一般的には,機械や情報技術を駆使し,従来の農業より効率的に高品質の作物をつくることを 目的とする農業のことを次世代農業と言う.
機械や情報技術を使うことで人件費を減らし,一人あたりの生産量を増やすことで従来の農業 より収益を得やすくなっている.その反面,設備を設置するための初期投資が大幅に高くなって しまうという欠点がある.そのため,国からの農業支援のための助成金や貸出を利用することも 考えなければならない.
水温や栄養素をコンピュータで制御した水耕栽培や,監視カメラを使用した害獣対策,自動灌 水などを使った農業がそれにあたる.大型の機械を採用したものでは,全自動いちご収穫機など がある.[3]
3 本論
3.1 農業支援システムについて
今回制作した農業支援システムとは,農業や園芸を行っている方を対象としており,毎日の作 業量を少しでも減らすことを目的とした制作物である.
大規模なシステムを構築することは可能であるが,費用の関係上,実験として小規模での使用 を想定している.(プランターや植木鉢など)
3.1.1 実装する機能
• 赤外線カメラを使用し,夜間でも農場の様子を見ることができるようにする.
• 赤外線LEDを使用し,赤外線カメラの可視範囲を広げる.
• Raspberry Piをサーバー化し,Webを経由して映像の確認を可能にする.
• 土壌湿度センサーの値を取得し,電動ポンプによる自動灌水を可能にする.
3.1.2 得られるメリット
対象が家庭菜園だと仮定して,一度灌水するのにかかる時間と様子を見に行く時間を合わせて 5分程度とする.1日あたりで見るとほんの少しの時間であるが,灌水という作業は毎日あるの で,年間で約30時間をその作業に費やすこととなる.そして,灌水は毎日必要な作業のため,
泊まりがけで旅行にいくこともできない.
そういった作業による時間拘束を無くすために,この農業支援システムがある
また,自動灌水機能だけではなく定点観測の機能を実装させているため,自分が育てた植物が どのように成長していくかを見ることができる.
3.2 画面説明・機能説明
今回制作した農業支援システムはPC・タブレット端末・スマートフォン端末のどれでも使用 することができる.しかし,基本は外出時にいつでも使用することが出来るということを想定し ているため,スマートフォン端末で使用することを前提に設計している.
灌水先は植物の根本に設置し,水分センサは直接水がかからないよう,植物から離れた土壌に 差し込んでいる.今回の場合は植物から5cmほど離している.
3.2.1 定点カメラ 図1 [5]
このページは今回制作した農業支援システムのトップページであり,RaspberryPiのカメラ映像 を常時見ることができる.画面下には灌水ログがあり,自動灌水によって灌水が行われると,日 時と「灌水しました」という文章が表示されるようになっている.この表示によって,正しく灌 水ができているという確認ができるようになっている.
湿度の基準は水分センサから得られた電圧の数値を元に当てはめており,数値が30以下にな ると数値が40を超えるまで灌水するように設定している.
カメラ映像と灌水ログの間にアルバムと書かれたボタンがあり,それを押すと10分おきに撮 影された画像の一覧が表示されているページへ移動する.
3.2.2 アルバム 図2 [6]
このページでは,10分おきに定点カメラによって撮影された画像が一覧となって表示されて いる.並びは降順になっており,新しく撮影された画像が常に上に来るように設定している.
横4列で縦にあるだけ並ぶようになっているが,横4列にした理由としては,iPhoneに初期から 入っている写真閲覧アプリが横4列になっていることから参考にした.視認性が良い状態でかつ より多くの画像を表示するのは横4列が最適なのだろう.
画面上部の戻るを押すとトップページに戻り,連続再生のボタンを押すと,撮影した画像を連 続再生するページへ移動する.
3.2.3 連続再生 図3 [7]
このページでは,10分ごとに撮影した画像をスライドショーのように連続再生することができ る.画面上部のスライドバーは再生速度を表しており,10単位で速度を変えることができる.再 生速度は,10~300まで変更可能となっている.再生速度を変える場合,ストップボタンで再生 を一度止め,スタートボタンを押すことによって再生速度が適用されるようになっている.
画面上部の戻るを押すとアルバムのページに戻る.
全体の状態
ブレッドボード図 [8]
3.3 製作計画の変更点
初期の段階では,トップページにボタンを複数置き,それを押すことによって遠隔操作での潅 水を可能にしようとしていた.しかし,制作物の主な機能は自動潅水であり,自ら水をやる必要 がある状況になってはいけないと判断したため,遠隔操作の機能は取り外すことにした.
3.4 製作の結果
当初から予定していた機能はすべて組み込むことができ,実用性のある制作物となり満足のい く結果となった.また,動作の問題も起こらず,このまま実運転することもできる.しかし,時 間の都合上,最低限必要な機能の実装しかすることができなかった.デザインの変更や追加機能 を実装することも考えていたが断念した.
3.5 苦労した点
• Windows以外のOSを使ったことがなく,今回初めて使ったRaspbianというLinaxベース
のOSの使い方に戸惑った.
• Windowsなら情報量も多く,どうすればいいかある程度分かるが,Raspbianではどうす
ればいいのか全くわからず,情報量も少なかったので解決するまで時間がかかってし まった.
• 研究室の通信回線はプロキシが設定されており,その解決に多くの時間を使い苦労した.
製作途中にあった不具合の原因のほとんどがプロキシだった.
3.6 課題
• 育てる作物には適度な湿度が存在する.トマトは良い例で,ギリギリまで乾燥した状態 にすると品質の良い(糖度が高く形の良い)トマトができる.そのため,自動潅水をす る湿度を自分で変更できるように組み込むとより使い勝手が良くなる.また,主要な植 物の適切な湿度を一覧にして表示するページがあるとさらに便利である.
• ポート開放を行っての実験を行っていないため設定していないが,サーバーを立てる際 にセキュリティ面を考慮する必要がある.
• 実際に使用するテストを複数人にしてもらい,ユーザビリティに考慮したデザインへと 変更するべきである.
4 技術要素
開発環境,開発言語,使用したライブラリ等の各技術要素に関する項目を記述する.
4.1 開発環境 開発に使用するPC
デスクトップPCHPHP TouchSmart PC 520-1180jp/CT B3H31AV-ABYF
• プロセッサ:Intel(R) Core(TM) i7-3770S CPU @ 3.10GHz 3.10 GHz
• メモリ:8.00 GB
• システム:64ビット オペレーティング システム Raspberry Pi2モデルB
使用機材 ブレッドボード ジャンパーワイヤー 抵抗器
赤外線LED 水分センサ ポリタンク 電動灯油ポンプ
4.2 Raspberry Pi(ラズベリーパイ)
イギリスのラズベリーパイ財団(Raspberry Pi Foundation)によって開発された,クレジット カードサイズの低コストコンピュータである.世界中の子供達を対象としており,コンピュータ がプログラムによってどのように機能するのかを学ぶための教育に使用されることを目的として いる.[9](図1)
種別はシングルボードコンピュータとなる.
現在までに販売されているモデルは6つあり,Raspberry Pi 1であるModel A,Model A+,
Model B,Model B+,Raspberry Pi 2であるModel B,Raspberry Pi Compute Moduleがある.
4.2.1 名前の由来
従来から,「マイクロコンピューター(マイコン)」と呼ばれるものには何故か果物の名前が 付けられることがあった.
アップル社が開発したマイコンAppleⅡやMacintosh,三菱電機が開発したApricot PC.その流 行に乗って「Raspberry(ラズベリー)」と付けられた.[10]
そして,「Pi」はプログラミング言語である「Python」に由来しており,合わせて「Raspberry Pi」となっている.[11]
4.2.2 OS Raspbian(ラズビアン)
Raspberry PiのOSにはLinuxを使用すること意図している.推奨されているのはDebianをカス タマイズしたRaspbianである.
RaspbianにはRaspberry Piを使用する人に合わせて好きなアプリケーションをインストールで きるように,35,000以上のコンパイルされたパッケージが付属されている.[12]
4.2.3 GPIO
GPIOはGeneral Purpose Input/Output(汎用入出力)の略語である.
RaspberryPiには基盤の端に複数の並んだピンが備わっており,GPIOと呼ぶ.入力として動作し
た場合,他の部分からのデジタル信号を読み取り,出力として動作した場合,他デバイスの制御 や信号の通知を行う.
4.2.3.1 RaspberryPiのGPIO配置図 [13]
4.2.3.2 GPIOPIN各種説明
• Powor
電源のこと.
電力が必要な場合,ここから供給する.
RaspberryPiの場合,5Vと3.3Vの2種類のピンに分けられている.
• GND(接地)
アース(earth),グランド(ground)のこと.
電気を逃すためのピンで,配線する際はマイナス極側を接続する.
• General Inputs/outputs
GPIOのこと.
入力として動作した場合,他の部分からのデジタル信号を読み取り,出力として動作し た場合,他のデバイスの制御や信号の通知を行う.
• I2C Interface
I2CとはInter-Integrated Circuitの略で,アイ・スクエアド・シーが正式な読みとされてい
る.
PHILIPS社が開発した,電子回路におけるシリアル通信方式のひとつであり,組み込み
機器や携帯電話などで利用される.
I2C Interfaceに対応した温度センサなどを接続すると,比較的簡単にデータを取得するこ
とができる.
RaspberryPiでは,初期設定でI2Cが無効化されているため,有効化させる必要がある.
• SPI Interface
SPIとはSerial Peripheral Interfaceの略で,シリアル・ペリフェラル・インタフェースと読
む.
コンピュータ内部で使われるデバイス同士を接続するバスである.
(例えば,Webカメラや温度計,キーボードやホームオートメーションシステムなどが
デバイスにあたる)
比較的低速なデータ転送を行うデバイスに利用する.
• UART Interface
UARTとは,Universal Asynchronous Receiver Transmitterの略語である.
非同期(Asynchronous)にシリアル通信を行うための仕組みで,調歩同期方式によるシ リアル信号をパラレル信号に変換したり,その逆方向の変換を行うための集積回路であ る.
• ID EEPROM Interface
IDはidentificationの略語で,利用者を識別するための符号のことである.
EEPROMとは,Electrically Erasable Programmable Read-Only Memoryの略語である.
不揮発性のメモリの一種で,コンピュータなどの電子機器で電源を切っても保持してお くべきデータを格納するのに使われる.
4.3 Apache [14]
Apacheとは,最も人気の高いWebサーバソフトウェアの一つ.1995年にNCSA httpd 1.3を ベースに開発が始まり,UNIX系OSを中心に幅広い人気を獲得した.
Apacheはフリーソフトウェアとして無償で公開され,世界中のボランティアのプログラマた ちの手によって長年にわたって開発が続けられている.もともとNCSA httpdの細かいバグを修 正したり新しい機能を追加するためのパッチ(patch)集として公開されていたが,途中から単体 のWebサーバソフトとして公開された.
今回の制作物では,全てのWebページのサーバにApacheを使用している.
4.4 mjpg-streamer
動画のmpegと静止画のjpegを混ぜたような名前からも想像がつく通り,動画を静止画のjpeg 画像の塊(パラパラ漫画のイメージ)として扱い,ストリーミングするツールとなっている.m jpegとあるだけにjpeg変換ができないと使えないので,あらかじめlibjpeg-develのインストール が必要となる.
mjpg-streamerにはサーバを構築する機能が含まれているのだが,CGIやPHPなどの言語に対応 していない.そのため,それらの言語を使用する場合はApacheと併用する必要がある.
4.5 HTML5 [14]
Webページの記述などに用いるマークアップ言語,HTMLの第5版.WHATWGの提唱した仕 様を元にWeb関連技術を標準化しているW3Cで仕様の検討・標準化が進められている.
新たに追加された仕様には,音声を埋め込むaudioタグ,動画を埋め込むvideoタグ,任意の グラフィックスを描画できるcanvasタグなどがあり,こうした要素の再生やアニメーションなど の制御や,データの保存,ソケット通信,ドラッグ&ドロップなどをスクリプト言語から利用す るための標準仕様(API)も定義される.
4.6 PHP [14]
動的にWebページを生成するWebサーバの拡張機能の一つ.また,そこで使われるスクリプ ト言語.レイアウトの「雛形」となるHTMLファイル内に,処理内容を記述したスクリプトを 埋め込み,処理結果に応じて動的に文書を生成し,送出することができる.
正式名称の「PHP:Hypertext Preprocessor」にもあるように,動的に生成されるページの作成に 向いている.また,XMLのサポートや各種データベースとの連携に優れている点などから近年 普及しつつある.
プログラムの表記法はC言語,Java,Perlの各言語から転用したものがベースとなっているが,
PHP独自のものもある.言語仕様やプログラムはオープンソース・ソフトウェアとして無償で入 手することができる.
4.7 CGI [14]
CGIとは,Webサーバが,Webブラウザなどからの要求に応じて,プログラムを起動するため の仕組み.
プログラムファイルが置かれているURLにクライアント(ブラウザなど)がアクセスすると,
サーバ内部でそのプログラムが起動され,実行結果がクライアントに送信される.アクセス時に クライアント側からデータを送信することもでき,起動されたプログラムがデータを受け取って 処理内容に反映させたり,サーバ内部に保存したりすることができる.
現在では多くのWebサーバが標準でCGIに対応しているため,サーバの種類を問わず同じプ ログラムを利用することができる.また,CGIは特定のプログラミング言語に依存しないため,
様々な言語でプログラムを開発することができる.
4.8 Python [14]
簡潔で読みやすい文法が特徴的な汎用の高水準プログラミング言語の一つ.いわゆるスクリプ ト言語あるいは軽量言語(LL:Lightweight Language)の草分けの一つで,UNIX系OSを中心に広 く普及している.
基本的な特徴としては,豊富なデータ型とコンテナ型,ガベージコレクション,Unicodeによ る多言語対応,プログラムのモジュール(部品)化による他のプログラムへの容易な組み込み,
プログラムの仕様の文書化(ドキュメンテーション)を支援する機能などがある.ユニークな特 徴としては,多くの言語では人間にとってプログラムを読みやすくするために便宜的に行われる インデント(字下げ)を言語仕様上の構文の一つとして採用しており,ブロックの範囲を示すの に用いられる.
言語自体の文法や語彙,記法は最小限のシンプルなものに抑えられているが,対照的に極めて 広範囲の分野に渡り豊富な機能を提供する標準ライブラリが用意されている.当初は手続き型言 語とオブジェクト指向言語の特徴を備えた言語として設計されたが,関数型言語の要素の多くを 取り入れ,様々なスタイルのプログラミングが可能なマルチパラダイム言語として知られている.
他の言語や環境との連携機能も充実しており,Pythonからアクセスできない低レベルの機能を C言語で記述して拡張モジュールとして組み入れる仕組みが提供されているほか,Javaライブラ リを利用できる実行環境のJythonや,Microsoft.Net環境で,Net Frameworkの機能を利用できる
IronPythonなどの処理系もある.
標準の言語処理系(CPython)にはソースコードを読みながら同時に実行するインタプリタが 含まれ,コンパイルやビルドなど手間や時間のかかる作業を省略して記述したプログラムを即座 に実行してみることができる.この処理系はオープンソース・ソフトウェアとして公開されてお り,誰でも自由に入手,利用,改変,再配布などすることができる.
Pythonの最初のバージョンは1991年にオランダのグイド・ヴァン・ロッサム(Guido van
Rossum)氏によって発表された.現在ではWebアプリケーションの開発用言語として人気が高
いほか,データ処理や統計解析などの分野でよく利用されることで知られる.
4.9 JavaScript [14]
JavaScriptとは,主にWebページに組み込まれたプログラムをWebブラウザ上で実行するため に用いられるプログラミング言語の一つ.いわゆるスクリプト言語あるいは軽量言語(LL:
Lightweight Language)の一つで,実行環境をWebブラウザに組み込んで利用されることが多い.
C言語やJavaに似た記法や文法を採用した手続き型の言語で,簡潔な記述でプログラムを開発 することができる.オブジェクト指向にも対応しているが,他の多くの言語で一般的なクラスを 用いる方式ではなく,既存のオブジェクトの複製に機能を追加していくプロトタイプベースと呼 ばれる手法を採用している.関数を変数のように(第一級のオブジェクトとして)扱ったり,関 数を引数に取る高階関数を定義できるなど,関数型プログラミング言語の仕様も取り込んでいる.
JavaScriptはWebページのHTMLファイル内に特殊な記法を用いて埋め込まれて記述され,
Webブラウザに内蔵されたJavaScript処理系によってページの表示時に解釈・実行されることが 多い.JavaScriptのみを記述したファイルを読み込む形で利用されることもある.ページ内の要
素に動きや効果を加えたり,閲覧者の操作に即座に反応して何らかの処理を行ったりするのに用 いられる.
主要なWebブラウザの多くがJavaScriptに対応しているが,ブラウザの種類やバージョンに よって仕様や挙動に違いがあり,開発者を悩ませ続けている.JavaScriptの場合,他の言語にも ある言語そのものの仕様・実装の違い(バージョンの違いや各社独自の拡張や仕様・実装の相 違)の他に,HTMLやCSSの仕様や解釈の相違や,JavaScriptからHTMLの要素を扱う際に必要
となるDOM(Document Object Model)と呼ばれるAPIの違いが組み合わされるため,複数のブ
ラウザで同じように動作するJavaScriptプログラムを開発するのは難しい.
近年ではWebブラウザに留まらず様々な環境にJavaScript処理系が移植され,Webサーバ上で プログラムを実行して動的にWebページを生成するシステムに採用されたり(Microsoft IISの
ASP/ASP.NETやNode.jsなど),Adobe Systems社のFlashで標準のプログラミング言語として採
用されたり(正確にはActionScriptと呼ばれるJavaScript方言),OS上で実行されるスクリプト として利用したり(Windows Scripting Hostなど),様々な場面で汎用的に利用されている.
名称にJavaの語を冠しているが,他の「Java○○」技術とは異なりJavaの拡張仕様や関連技術 などではなく,記法や予約語などの一部が共通していること以外に直接的な繋がり互換性はない.
実際,JavaScriptは型システムや関数,オブジェクト指向の扱いなど言語仕様の根本的な部分の いくつかがJavaとは大きく異なる.また,JavaにもWebページ内にプログラムを埋め込んで実 行するJavaアプレットと呼ばれる仕様があるため,主に技術者以外のWebに携わる人々にとっ
てJavaとJavaScriptの名称は紛らわしく,混同や混乱を生み出している.
JavaScriptは1995年にNetscape Communications社のブランダン・アイク(Brendan Eich)氏に よって開発され,当時最も人気の高いWebブラウザだったNetscape Navigator 2.0に初めて実装さ れた.当初は「LiveScript」という名称だったが,同社がJava開発元のSun Microsystems社(当 時)と提携していたことから,Javaの名称を冠してJavaScriptに改称された.
JavaScriptはほとんどの主要なWebブラウザが対応し,次第にブラウザ以外にも広まったが,
当初は開発元による仕様の差異が大きかったため,標準化団体による標準規格の策定を求める声 が高まり,1997年に標準化団体Ecma Internationalにより,「ECMAScript」と通称される標準の 初版が発行された.同規格は現在も新機能を取り込みながら改訂が重ねられており,多くの
JavaScript処理系や対応製品,JavaScript互換言語が「ECMAScript X準拠」(Xはバージョン番
号)と,ECMAScriptへの対応水準を表明している.
4.10 シェルスクリプト [14]
シェルスクリプトとは,複数の処理をまとめて行う(バッチ処理)ときに使われる,OSの シェルが直接解釈・処理できるスクリプト.
シェルスクリプトはシェルごとに独自の機能を使用して処理されるため,起動の方法や文法は シェルによって変わってくる.例えばUNIX系OS(厳密にはその上で動作するbashなどのシェ ル)では,シェルにシェルスクリプトを引数として渡して実行したり,シェルスクリプトの冒頭 に起動プログラムを書き込んでシェルスクリプト自体を実行したりすると起動できる.
シェルスクリプトではシェルごとに独自の文法が採用されているが,おおむね1行が1つのコ マンドとして扱われる.特にUNIX系OSのシェルは複雑な繰り返し処理や条件分布などに対応 しており,シェルスクリプトだけでかなり複雑な処理を自動化できる.
4.11 bash(Bourne Again shell) [14]
bashとは,多くのUNIX系OSで標準的に使われるシェル(ユーザからの操作を受付,結果を 表示するソフトウェア)の一つ.また,それを実行するコマンド名.GNUプロジェクトの一部 として開発が進められ,オープンソース・ソフトウェアとして公開されている.
bashはそれ以前に存在したBourneシェル(コマンド名はsh)の後継として開発され,その名 称は”Bourne”と”Born Again”をかけたものと言われる.Kornシェル(ksh)やCシェル(csh)
などの持つ要素も取り入れられ,コマンド履歴やコマンド名の自動補完など今日では標準的に使 われる多くの機能を実装している.
5 終わりに
プログラミングの知識や経験が乏しく,ひたすら基礎知識を身につけるための勉強をすること から始まった.わけもわからず手当たり次第にサンプルプログラムを作る作業が続いたが,気づ けば自分でプログラムを書くことができるまでに成長した.
今回の制作物では多くの言語を使用したため,それぞれの学習を進めなければならず,その分 時間をかけてしまった.しかし,その甲斐があって,それぞれの言語の特徴や違いを知り,自分 なりに使い方を考えることもできるようになった.
今まで触れようとも思わなかった分野であったが,今回いただいた機会が将来必ず役に立つと 実感した.
6 謝辞
研究を行うにあたって,知識や経験の乏しい私に分かりやすく時には時間を非常に多く 割いてご指導して下さった徐丙鉄先生に感謝いたします.また,テーマは違いましたが 私より経験豊富な物理研究室のメンバーにも多くの助けをしていただきありがとうございまし た.
7 参考文献・引用
[1]総務省統計局 年齢別人口
http://www.stat.go.jp/data/jinsui/2013np/pdf/gaiyou2.pdf [2]農林水産省 農業労働力に関する統計
http://www.maff.go.jp/j/tokei/sihyo/data/08.html [3]三和サービス 全自動散水装置
http://www.san-san.co.jp/agri/sansui/
[4]農研機構 イチゴ収穫ロボット
http://www.naro.affrc.go.jp/brain/iam/urgent/urgent100/043434.html
[5]ものづくりエクスペリメント さRaspberry PiのCamera moduleとWebカメラでStreamingを
行う
http://denshikousaku.net/raspberry-pi-camera-module-web-camera-streaming [6]All About フォルダ内の画像を一覧表示する
http://allabout.co.jp/gm/gc/47434/
[7]平成26年度卒業研究論文 RaspberryPi監視カメラの可能性:出席確認 和泉大介
http://buturi.heteml.jp/student/2014/izumi/ronnbunsaisyuu6.pdf [8]fritzing 公式ホームページ
http://fritzing.org/
[9]RaspberryPi 公式ホームページ
https://www.raspberrypi.org/help/what-is-a-raspberry-pi/
[10]デジタル小噺 ミニサイズPC「RaspberryPi」の名前の由来は?
http://ryoh1212.blogspot.jp/2012/10/pcraspberrypi.html [11]Raspberry Pi 公式ホームページ The name 'Raspberry Pi'
https://www.raspberrypi.org/forums/viewtopic.php?f=2&t=2657 [12]BYTEMARK HOSTING Raspbian
http://www.raspbian.org/
[13]DESIGNSPARK RaspberryPi B+のご紹介
http://www.rs-online.com/designspark/electronics/jpn/blog/introducing-the-raspberry-pi-b-plus [14]IT用語辞典 e-Words
http://e-words.jp/
8 付録
今回の制作物を作る前に,Hibisビジネス事例に応募し,その研究を進め卒業論文にする予定 だった.しかし,残念ながら落選したため没となった.その内容を添付しておく.
制作物に関するプログラム
start_steam.sh mjpg-streamer起動
#!/bin/bash
cd mjpg-streamer/mjpg-streamer-experimental
./mjpg_streamer -o "./output_http.so -w ./www -p 8080" -i "./input_raspicam.so -fps 30 -x 320 -y 240"
streamer.sh 10分おきに写真撮影の起動
#!/bin/bash while true ; do
DATE=$(date +"%Y-%m-%d_%H%M_%S")
wget -O /var/www/Pictures-cron/$DATE.jpg http://192.168.11.44:8080/?action=snapshot sleep 600
done
water_supply.py 自動灌水機能の起動
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# Written by Limor "Ladyada" Fried for Adafruit Industries, (c) 2015
# This code is released into the public domain import time
import os
import RPi.GPIO as GPIO import datetime
IO_NO = 5
GPIO.setmode(GPIO.BCM) DEBUG = 1
GPIO.setup(IO_NO, GPIO.OUT)
# read SPI data from MCP3008 chip, 8 possible adc's (0 thru 7) def readadc(adcnum, clockpin, mosipin, misopin, cspin):
if ((adcnum > 7) or (adcnum < 0)):
return -1
GPIO.output(cspin, True)
GPIO.output(clockpin, False) # start clock low GPIO.output(cspin, False) # bring CS low commandout = adcnum
commandout |= 0x18 # start bit + single-ended bit commandout <<= 3 # we only need to send 5 bits here
for i in range(5):
if (commandout & 0x80):
GPIO.output(mosipin, True) else:
GPIO.output(mosipin, False) commandout <<= 1
GPIO.output(clockpin, True) GPIO.output(clockpin, False) adcout = 0
# read in one empty bit, one null bit and 10 ADC bits for i in range(12):
GPIO.output(clockpin, True) GPIO.output(clockpin, False) adcout <<= 1
if (GPIO.input(misopin)):
adcout |= 0x1 GPIO.output(cspin, True)
adcout >>= 1 # first bit is 'null' so drop it return adcout
# change these as desired - they're the pins connected from the
# SPI port on the ADC to the Cobbler SPICLK = 18
SPIMISO = 23 SPIMOSI = 24 SPICS = 25
# set up the SPI interface pins GPIO.setup(SPIMOSI, GPIO.OUT) GPIO.setup(SPIMISO, GPIO.IN) GPIO.setup(SPICLK, GPIO.OUT) GPIO.setup(SPICS, GPIO.OUT)
# 10k trim pot connected to adc #0 potentiometer_adc = 0;
last_read = 0 # this keeps track of the last potentiometer value tolerance = 5 # to keep from being jittery we'll only change
# volume when the pot has moved more than 5 'counts' while True:
# we'll assume that the pot didn't move trim_pot_changed = False
# read the analog pin
trim_pot = readadc(potentiometer_adc, SPICLK, SPIMOSI, SPIMISO, SPICS) *0.1
# how much has it changed since the last read?
pot_adjust = abs(trim_pot - last_read) if DEBUG:
print "soil moisture:", trim_pot, print "%"
#print "pot_adjust:", pot_adjust
#print "last_read", last_read
if ( pot_adjust > tolerance ):
trim_pot_changed = True
#if DEBUG:
#print "trim_pot_changed", trim_pot_changed if ( trim_pot_changed ):
set_volume = trim_pot / 10.24 # convert 10bit adc0 (0-1024) trim pot read into 0-100 volume level
set_volume = round(set_volume) # round out decimal value set_volume = int(set_volume) # cast volume as integer
#print 'Volume = {volume}%' .format(volume = set_volume)
set_vol_cmd = 'sudo amixer cset numid=1 - {volume}% > /dev/null' .format(volume = set_volume)
os.system(set_vol_cmd) # set volume
#if DEBUG:
#print "set_volume", set_volume
#print "tri_pot_changed", set_volume
# save the potentiometer reading for the next loop last_read = trim_pot
# hang out and do nothing for a half second if (trim_pot <=30 ):
water = 1 if (trim_pot >=40 ):
water = 0 if (water == 1):
print "water supply"
d = datetime.datetime.today() f = open('/var/www/index.html','a')
print >> f, '<center>%s年%s月%s日%s時%s分 灌水しました</center>' % (d.year, d.month, d.day, d.hour, d.minute)
f.close()
GPIO.output(IO_NO, True) time.sleep(0.5)
if (water == 0):
GPIO.output(IO_NO, False) time.sleep(3)
index.html トップページ
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>定点カメラ</title>
<meta name="viewport" content="width=360">
</head>
<body>
<header>
<center>
<h1>定点カメラ</h1>
</center>
</header>
<center>
<img src="http://192.168.11.44:8080/?action=stream" />
</center>
<center>
<button type="button" name="アルバム" value="リンク"
onClick="location.href='http://192.168.11.44/myphpdirpic.php'" style="width:320px;height:60px">
<font size="5">アルバム</font>
</button>
</center>
<h2 align="center">灌水ログ</h2>
</body>
</html>
myphpdirpic.php アルバムページ
<title>アルバム</title>
<meta name="viewport" content="width=360">
<center>
<a href="index.html">戻る</a><br><br>
<button type="button" name="連続再生" value="リンク"
onClick="location.href='http://192.168.11.44/motionImage.cgi'" style="width:320px;height:60px">
<font size="5">連続再生</font>
</button><br><br>
<?php
//画像ファイル一覧を表示するパスを指定する
$path = "/var/www/Pictures-cron";
//パスの表示
print("ディレクトリ「<b>".$path."</b>」の<br>画像ファイル一覧<br><br>");
//文法 scandir( パス ,[ ソート順 ] ) //scandir
//ソート順が省略された場合は,アルファベットの昇順にソートする //ソート順に"1"が指定された場合は,アルファベットの降順にソートする //
//昇順にソートする場合はソート順を省略する //$array = scandir($path);
//降順にソートする場合はソート順に"1"を指定する
$array = scandir($path,1);
//count命令により配列の個数を取得する
$num = count($array);
//HTML文を出力 テーブルの開始を指定
print("<table><tr>");
//横に並べる画像の最大数を設定する
$max = 4;
//カウント数の初期化
$cnt = 0;
//配列の数だけ繰り返す for ($i=0;$i<$num;$i++){
//$filenameにァイル名を設定
$filename = "http://192.168.11.44/Pictures-cron/" . $array[$i];
//ファイル名の拡張子が「gif」または「GIF」または「jpg」または「JPG」
//または「JPEG」または「png」または「PNG」の場合は実寸表示の //リンク付きで画像を表示する
if (Eregi('gif$', $filename) OR Eregi('jpg$', $filename) OR Eregi('jpeg$',$filename) OR Eregi('png$', $filename)) {
print("<td><a href=" .$filename . "><img src = " .$filename. " width=80></a></td>");
//カウント数の初期化
$cnt = $cnt + 1;
//カウント数の判定 最大数以上の場合は改行し,カウントを初期化する if ($cnt >= $max) {
print("</tr><tr>");
$cnt = 0;
} }
}
//HTML文を出力 テーブルの終了を指定
print("</tr></table>");
?>
<br>
</center>
motionImage.php 連続再生ページ
#!/bin/bash
echo "Content-type:text/html"
echo ""
echo '<!DOCTYPE html>'
echo '<html>' echo '<head>'
echo '<meta charset=UTF-8>' echo '<title>連続再生</title>'
echo '<meta name="viewport" content="width=360">' echo '</head>'
echo '<center>' echo '<style>
img{ display: block;
position: absolute;
top:200px;
left:0;
right:0;
margin: auto;
width: 320px;
}
</style>' echo '<body>'
echo '<a href="myphpdirpic.php">戻る</a><br><br>' files="/var/www/Pictures-cron/*"
④
for filepath in ${files}
do
file=`echo $filepath | cut -c 9-45`
echo "<img src="${file}">"
done read wait
echo '<input id="timeSlider" type="range" min="10" max="300" step="10" onchange="showValue()" />' echo '<span id="showRange">0</span>'
echo '</br></br><button onClick="startSlideShow()" style="width:160px;height:60px"><font size="5">
スタート</font></button>'
echo '<button onClick="stopSlideShow()" style="width:160px;height:60px"><font size="5">ストップ
</font></button></br>' echo '</div>'
echo '<script>'
echo 'var intervalTime = 100;'
echo 'document.getElementById("timeSlider").value=intervalTime ;'
echo 'document.getElementById("showRange").innerHTML = intervalTime;' echo 'function showValue () {
intervalTime = document.getElementById("timeSlider").value;
document.getElementById("showRange").innerHTML = intervalTime;
}'
echo 'var photos = document.getElementsByTagName("img");' echo 'var timer = null;'
echo 'var N = photos.length; //alert("N="+N);' echo 'var n = 0;'
echo '//zBase = photos[N].style.zIndex;' echo 'zBase = 100 ; //alert("zBase="+zBase);'
echo 'topZindex = 0;' echo 'function nextPhoto(){
++topZindex;
photos[n].style.zIndex = zBase + topZindex;
n++ ; n = n % N;
}'
echo 'function startSlideShow(){
if( timer == null ){
timer = setInterval("nextPhoto()", intervalTime );
} }'
echo 'function stopSlideShow(){
clearInterval(timer); timer = null;
}'
echo '</script>' echo '</body>' echo '<center>' echo '</html>'