工作室

作った物(ソフト・ハード)を何らかの方法で記録し残しておかないと、後日、修理・修正をしようとした時に非常に困ります。
忘れてしまうからです。あの時何故そうしたのか、といった事が意外とわからず苦労することがよくあります。

特にプログラムに関しては、なぜこの関数を使ったのか、これは必要ないのでは?などです。またあまり綺麗なプログラムコードではなく、よりスマートで美しいコードを見つけた時には、どうしてこんなやり方をしたのだろうと後悔する事も多いのです。回路も設計図を残しておかないと、後で大変! 最近物忘れが多いのです。


回路

PIO1:VB-EX50の入力にトリガーを入れる
PIO2:LED付きファンを回す
PIO3:充電池への充電時間制御
EXP:PhoMosリレーへの電源供給(3V 2mA)

PIO1からのトリガー
    VB-EX50のIN2
        PhotoMosリレーをON
            餌あげ機にDC5V供給(時間調整はカメラサーバーで)

PIO2からのトリガー
    ファンの電源回路を短絡

人感センサーの鳥感知
    VB-EX50のIN1 トリガー
        カメラの向きを変える

ファン・LEDは昼間は太陽電池・充電池からの供給があるため回りますが、夜間は途絶えるため、回らず点灯しません。

拡大あり

 

T&D ProDigio開発セット(アーカイブ版)

おなじみの秋月電子通商で購入。ネット経由で遠隔操作をしようとすると、Lan-RS232cプロトコルコンバータEthernetデジタル出力ボードなどを一般的に使いますが、 これらに共通する最大の欠点は、ブラウザでネットアクセスするのは、あくまでも管理者としてであり、管理者権限、root権限でログインしないと、機器のコントロールが出来ないという事です。サイトに来てもらった方々に気軽に周辺機器のコントロールをしてもらうのに、「ID」「 PASSWORD」を入力しもらい、管理者専用の決してユーザーフレンドリーでは無い画面から操作するというのは、敬遠されてしまいます。更に、root権限の「ID」「 PASSWORD」を教えるということは、設定を変更されてしまう危険性もあり、管理する側としても非常に困るわけです。

そこでProDigioの登場です。このモジュールは、HTTPサーバ機能を有しており、スクリプトを記述することで、cgi、ssiとして動作させることが可能となります。これはとても「美味しい」機能です。外部入出力には、IO端子、USBメモリコネクタ、comポート、CFカードがあり、まさにテンコ盛り状態。ブラウザ経由でこれらにアクセス、もしくは、ここに接続した周辺機器のコントロールが可能とな ります。

今回は、温湿度計LED付きファン、餌あげ機のモーター、カメラサーバー、充電池のコントロールをしています。リレー制御すれば、掃除機や電灯などの消費電力が大きい機器のOn Offが可能ととなります。

スクリプトはc言語体系に非常に似ており、c や java を習得した人なら抵抗無く扱えると思います。

Function main()
{
var fd ; //ファイルディスクリプタ
var size ; //書き込みサイズ
var rtn ; //dummy
var now ; //現在時刻
var open_time ; //餌あげ開始時刻
var close_time ; //餌あげ終了時刻
var int_time ; //餌あげ間隔時間
var last_time ; //直近の餌あげ時刻
var next_time ; //次回の餌あげ時刻
var time1 ; //年月日
var time2 ; //時分秒
var t2 ;
var str_time ;
var str ;
var flag_t ;

flag_t=0; //flagの初期化
// 現在日時の取得
now = getrtctime() ;
time1 = getdatestring("yyyy/MM/dd") ; // 年月日を文字列へ
time2 = gettimestring("HH:mm:ss") ; // 時分秒を文字列へ
last_time = time1 + " " + time2;

t2=int(left("%time2%",2)); //時間のみを抽出整数化
if ((t2<6)||(t2>14)) //6:00-15:00可能とする
{
flag_t=1;
}

//時刻チェック
fd=fileopen("B:\\wrnlog.txt","r");
rtn=fgets("B:\\wrnlog.txt",str,1);
fileclose(fd);
if (str=="1")
{
flag_t=1;
}

if (flag_t=="1")
{
// timerイベント時間が経過していないもしく許可時間以外であれば終了
// 自動的に元のページに戻す
webprint("<HTML>");
webprint("<meta http-equiv=\"refresh\" content=\"
1; url=javascript:history.back()\" />");
webprint("</HTML>");
break ;
}
// else
// {
// 初期化 ---------------------------------------------
// 各ポート出力設定(使うポートのみ)

setport(7,1) ; //PIO[7]:Output

putport(7,0) ; //PIO[7]初期化
putport(7,1) ; //出力
sleep(1*1000) ; //インターバル1000msec
putport(7,0) ; //再初期化

//logファイル出力
fd=fileopen("B:\\wrnlog.txt","w");
if(fd<0)
{
//ファイルが無いときは新規に作成
fd=filecreat("B:\\wrnlog.txt");
if(fd<0)
{
error("fileCreatErr");
return;
}
}

// "1"をファイルへ出力する
rtn=filewrite(fd,"1");
if(rtn<0)
{
error("FileWriteErr");
fileclose(fd);
return;
}

fileclose(fd);

//2時間後にresetfile.wcrの呼び出しスクリプトのイベント関数
event("TIMER","C:\\www\\scripts\\resetfile.wcr","",
2*60*60*1000,0,1,60*1000);

//直近餌あげ時刻をファイル出力
//ファイル出力
fd=fileopen("B:\\lastfeedtime.txt","w");
if(fd<0)
{
//ファイルが無いときは新規に作成
fd=filecreat("B:\\lastfeedtime.txt");
if(fd<0)
{
error("fileCreatErr");
return;
}
}

// 時刻をファイルへ出力する
rtn=filewrite(fd,last_time);
if(rtn<0)
{
error("FileWriteErr");
fileclose(fd);
return;
}

fileclose(fd);

// 自動的に元のページに戻す
webprint("<HTML>");
webprint("<meta http-equiv=\"refresh\" content=\"
1; url=javascript:history.back()\" />");
webprint("</HTML>");
// {
}


 

餌あげのスクリプト

 「餌をあげる」ボタンから呼び出される

 変数宣言

 

 

 

 

 

ボタンを押した時刻を取得し、可能な時刻かチェック

 

 

 

 

前回実行できた場合のflagをファイルに保存しておくため、そのファイルをopenして、flagのチェック

 

 

flagチェック通過した場合、pio出力

 

 

 

 

 

インターバル1000msec(1sec)

 

 

flagファイルに状態書き込み

 

 

 

 

 

 

 

 

 

2時間後にflagをtrueにするスクリプトの呼び出し

実行した時刻をファイルへ書き込み

 

温度湿度測定スクリプト

Function main()
{
var dat[] ; // 受信データ
var str ; // ファイル識別子
var temp ; // チャンネル1温度
var temp_i ; // 温度算出用
var temp_f ; // 温度算出用
var hum ; // 年月日
var hum_i ; // 字分秒
var cnt ; //
var port ;


// シリアル通信 ------------------------------
port = 2 ; // シリアル通信ポート
sioctrl(port, 1200) ; // 通信速度を1200bpsに設定
siorxclr(port) ; // 通信バッファのクリア


// 現在値取得コマンド送信
sioputb(port, 0x00) ; // break信号送信
// sleep(100) ;

sioputb(port,0x0B) ; // 現在の温度取得コマンド送信
// sleep(100) ; // 100ms待機

cnt = siogetd(port, dat[], 10,1000) ; // 10Byte受信

if ( arg[0] == "T=1" ) { // 温度データの取得
temp = dat[2] + (dat[3] << 8) ;
temp_i = (temp / 10) - 100 ;
temp_f = temp - ((temp_i + 100) * 10) ;
str = "%temp_i%.%temp_f%"
}
else if ( arg[0] == "T=3" ) {
temp = dat[2] + (dat[3] << 8) ;
temp_i = (temp / 10) - 100 ;
temp_f = temp - ((temp_i + 100) * 10) ;
str = "%temp_i%.%temp_f%"
str = int(str) * 9 / 5 + 32 ; //華氏温度
str = left("%str%",4);
}
else
{
hum = dat [4] + (dat[5] << 8) ;
hum_i = (hum / 10) - 100 ;
hum_i = (hum_i * 100) / 92 ; // 湿度補正
str = "%hum_i%" ;
}
// Webへ表示
webprint("%str%") ;
}
おんどとりデータ読み取りスクリプト

 

 

 

 

 

 

 

 

 

 

 

 

 

 

華氏温度に変換

 

 

 

/92は湿度補正

時刻表示スクリプト

Function main()
{
var fd ; //ファイルディスクリプタ
var str ; //
var rtn ; //dummy
var now ; //現在時刻
var last_time ; //直近の餌あげ時刻
var next_time ; //次回の餌あげ時刻
var time1 ; //年月日
var time2 ; //時分秒
var yy_t ; //餌あげ間隔時間
var mm_t ; //直近の餌あげ時刻
var dd_t ; //次回の餌あげ時刻
var hh_n ; //時間部分
var mm_n ; //分部分
var ss_n ; //秒部分
var t2 ;
var diffsec ;
var difftime ;

//直近餌あげ時刻をファイル出力

// 現在日時の取得
now = getrtctime() ;
time1 = getdatestring("yyyy/MM/dd") ; // 年月日を文字列へ
time2 = gettimestring("HH:mm:ss") ; // 時分秒を文字列へ
last_time = time1 + " " + time2;

fd=fileopen("B:\\lastfeedtime.txt","r");
if(fd < 0){
error(" エラー:ファイルが開けません");
}else{
rtn=fgets("B:\\lastfeedtime.txt",str,255);
}

fileclose(fd);

t2["year"]=int(left("%str%",4));
t2["month"]=int(mid("%str%",5,2));
t2["day"]=int(mid("%str%",8,2));
t2["hour"]=int(mid("%str%",11,2));
t2["minute"]=int(mid("%str%",14,2));
t2["second"]=int(mid("%str%",17,2));

diffsec=difftime(now,t2); //餌あげ時刻からの経過時間

//2時間経過した場合
if( diffsec > 2*60*60 ){
difftime="今すぐにあげられます";

} else {
diffsec=2*60*60-diffsec; //次回餌あげ時刻までの残時間(2時間)
hh_n=diffsec/(60*60); //時間部分
hh_n=int(uintstr(hh_n)); //時間の整数値
mm_n=diffsec-hh_n*(60*60); //分部分
mm_n=int(uintstr(mm_n/60)); //分の整数値
ss_n=diffsec-hh_n*60*60-mm_n*60; //秒数

difftime="%hh_n%" + "時間" + "%mm_n%" + "分" + "%ss_n%" + "秒";
}
// Webへ表示
webprint("%difftime%") ;
}
餌あげコントロール画面で「次回までの時間」に表示するためのスクリプト

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

可能な場合ここのメッセージが表示される

その他以下のスクリプトで動作しています。

ファンを回すスクリプト
一定時間経過後、flag変更のスクリプト
SNTPサーバーに1時間毎に接続し時刻補正
リセット時メモリー上のファイルが消失するため時刻、flagのファイルを作成するスクリプト
現在時刻を表示するスクリプト
FANを5分で強制的にOFF

自分でハンダゴテをしなければいけない小さなパーツがあります。ハンダゴテが苦手な人は半完成品もありますが、高価になります。私はケチって自作しましたが、ノートパソコンの改造のために、内臓ボードの基盤回路を変更した時以来の緊張する細かな作業になりました。

 


餌あげ機

1号機(失敗)

 

パイプを通して餌台へ

ファンの上がセンサー

餌あげ機は、通販で買いました。即分解して改造しました。餌の補給部が透明なので残量のチェックが容易でこの点は気に入っています。

しかし、モーター・ギア周辺はかなり安っぽく、歯車がかみ合わない事もしばしばで不安定。定価¥18000を¥10000で購入しましたが、内容的には、制御基盤¥500、駆動部分¥500、プラスチック本体¥1000のtotal 2000円前後程度の製品と思います。

Tsukumo Robot 王国で、1000円出せばもっと良質な made in Japan の駆動部分が手に入るので、いずれ2号機を作成予定です。

台は檜原産の檜です。とてもいい香がします。

音声受信

音声受信はjava版ビュワーでは不可能です。PC版(アプリ型)なら可能ですが、ユーザーにダウンロードしてもらい、インストールしてアクセスしないと聞かれません。そこで、CANONが開発支援ツールとしてSDK KITを提供しているので、VisualBasic6.0で音声受信専用のプログラムを作りました。

意外と鶯(恥ずかしながら、他にあまり知らない)の鳴き声が良く聞こえてくるのには、感激します。道路を走る車の音も拾いますが・・・

セキュリティ

サーバーは、カメラサーバーとProDigioのHTTPサーバーの2台体制で運用しています。どちらもハードディスクのないMemoryベースの運用なので、セキュリティは高いです。ProDigioにはかなり強力なスクリプトが内蔵されているため、ハッカーによる乗っ取りにあうと、極めて危険なウィルス発信基地、踏み台となる危険性もありますが、ProDigio基板上のDipでMemoryへの書き込みを禁止しているため、泥棒に入られない限り、書き換えは不可能です。この辺の運用はHDD使用の 一般的PCベースサーバーとは一線を隔しているところで、安心できるところです。

固定IPでの運用で、ルーターのNATアドレス・ポート変換で対応しています。ProDigioのftpサーバーがポートを変換しているせいか、外からのPASVモードでのアクセスがうまくいきません。原因はなんとなく分かっていますが、若干不便です。現在はポートを閉じています。

マルチターミナル VB-EX50との連携

ProDigioのEXP出力をVB-EX50のOUT1に接続してモーターをコントロールしています。直接ProDigioからPhotoMOSリレーAQZ105)経由による制御が可能ですが、モーター回転時間をチョッとでも変更する場合、プログラムの書き換え、Memory書き込み解除、Debug作業、ftp転送、再度Debug作業、Memory書き込み禁止と非常に面倒になります。

VB-EX50の出力時間は、カメラサーバの管理者画面から、0-30秒まで任意に設定変更を手軽にできるので、回路は複雑ですが、管理が楽な方が良いのです。

人感(鳥感?)センサー 超高感度/一般広角両用タイプ焦電型赤外線センサキット Ver.2

人感センサーの出力はVB-EX50のIN1接続され、鳥がきたらカメラが餌台に自動で向きます。この時、静止画を10秒間自動撮影します。ベストショットを選んで、公開しています。

もともと、このKITにはコイル使用のメカニカルリレーがついていました。しかし、メカニカルリレーは消費電力が大きく、駆動電力も大きいのが欠点です。センサーは太陽電池パネルにより電力供給されていますが、当初動きませんでした。そこでリレーをPhotoMOSリレーに変更して動かしています。

メカニカルリレー (右端)

PhotoMOSリレーに変更後

画面分割器

館内のテレビモニターでは、滝と鳥の両映像を同時に見る事が可能です。2系統のビデオ信号は画面分割器のPinP機能を利用して、モニターに出力されます。また、人感(鳥用)センサーの出力をセンサー入力にinputして、子画面と親画面を入れ替えると同時に、電子オルゴールにも接続し、音で来鳥を知る事も可能にしています。
画面分割機もアラーム音が出ますが、非常に大きく耳障りで、Offに出きないため、基盤の一部パターンを切断しました。

PinP画面(Mac)

電子オルゴール

充電池

太陽電池から、余った電力を充電池に充電しています。しかし、夜間もLED付きファンを回すと、充電池が完全放電してしまい、寿命が尽きてしまいます。そこで、ProDigioからTimer 関数で放電時間を制限しています。

太陽電池パネル

Power 9W Voltage 18V Current 500mA(MAX)、Power 4.5W Voltage 18V Current 250mA の2枚を並列接続

電気料金

ProDigio    290mA    24h
VB-50i    MAX25W    06:00-18:00

餌あげ機のモーターは、5秒間、1日最大6回で30秒ですから無視、センサー、ファンは太陽電池で0円。温湿度計は電池です。電気料金は最も一般的な従量電灯B契約で1ヶ月間約9kWhで200円程度です。餌代のほうが遥かに大きいです(もちろん自腹)。

■趣味

1つ々々は単機能ですが、脳神経組織のように、お互いが相互に有機的に結ばれ、機能していく様子は、機能的で美しくさえあり、また便利でもあります。この考えは職場においても生かされており、趣味と実益を兼ねております。