2009年4月3日金曜日

自作 引き伸ばしタイマー

引き伸ばしタイマーを作ってみた。というか、正確にはタイマー部分は作っていない。そんな難しい物をつくる技術は俺にはない。実はこれ、以前、別の目的で作ったケーブルそのまんまだ。秋月電子のSSR(リレースイッチ)にACプラグ・ソケットと、シリアルポートへつなぐコネクタがつながっているだけのものだ。リレーの入力は、DTRと信号グランドに接続されている。
実はこのケーブル、以前これをCiscoルーターのコンソールポートやAUXポートに接続し、自宅サーバーの電源をコントロールするという用途に使っていた。サーバーからcronで一時間毎にルーターにtelnetして、再起動スケジュールのキャンセルコマンドと、1時間30分後の再起動スケジュールコマンドを投入しておく。もし、サーバーがフリーズした場合、cronも停止するので、ルーターの再起動スケジュールはキャンセルされずに1時間30分以内にはルーターは再起動を遂行する。ルーターの再起動中は、Asyncインターフェースもダウンするので、それに連動してサーバーの電源がリセットされる仕組みなのだ。実際に発動したこともあるが、サーバーが安定しているので今は使っていない。
今回、リレーの入力は、PCのシリアルポートに接続する。シリアルポートをOpen/CloseすることでAC電源のON/OFFするのだ。

あとは、Comポートをオープンし、タイマー秒数後にクローズする簡単なプログラムを作ればいいだけだ。とはいえ、プログラムは何年もやってないので素人同然だ。1秒以下には対応していない。ナントカ.hはこれら全部が必要かどうか不明。とりあえず動いた。引数にゼロを入れるとエラーが出るが気にしない。

stimer.c (Linux用)
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <termios.h>
#include <unistd.h>

#define PORT "/dev/ttyS0"
int main(int argc, char *argv[])
{
int fd;
int tval;
struct termios oldtio, newtio;
fd = open(PORT, O_RDWR);
tval = atoi(argv[1]);
sleep(tval);
close(fd);
return 0;
}

たとえば、10秒間スイッチONにする場合は、stimer 10 として実行する。ただし、このままでは一回実行すると終了してしまう。引き伸ばし作業の際、PCのディスプレイを点灯させておくわけにはいかない。一回実行したらあとは数字を入力してエンターを押すだけにするとか、任意でON/OFFする機能も必要なので改良した方がいい。

stimer.c 改良版(ディスプレイ無しで連続操作できるようにした)
  • ./stimer で実行
  • 1~998 Enterでタイマー秒数間スイッチON
  • 0 Enterで連続ONまたはそれのOFF
  • 999 Enterで終了

#include <string.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <termios.h>
#include <unistd.h>
#define PORT "/dev/ttyS0"

int main(int argc, char *argv[])
{
int fd;
char tstr[4];
int tval;
tval = 0;
char w[2];
struct termios oldtio, newtio;
while (-1)
{
printf("<1-998> interval\n");
printf("0 Continuous ON\n");
printf("999 Quit\n");
fflush(stdin);
scanf("%3s", tstr);
tval = atoi(tstr);
if (tval == 999)
{
return 0;
}
if (tval == 0)
{
fd = open(PORT, O_RDWR);
printf("ON\n");
printf("input 0 to turn OFF\n");
scanf("%1s", w);
close(fd);
printf("OFF\\n");
}
else
{
tval = atoi(tstr);
fd = open(PORT, O_RDWR);
printf("ON %d secsn",tval);
sleep(tval);
close(fd);
printf("OFF\n");
}
printf("\n");
}
return 0;
}

0 件のコメント: