2011年5月14日土曜日

すんげーニッチだけどw

PCに接続して使う広帯域受信機「IC-PCR100」のコントロールソフトを
Linuxで使うために自作して使っていたのですが、そのソースを晒してみます。
まあLinuxのシリアルポート制御の基礎ってところですかね。
昔書いたコードなので、突っ込み所満載w
今見ると、16進変換関数(GetHexStr)なぞは
sprintf(str,"%x",num);
の一行で済むじゃんねwww
まあ基数変換の基礎ってことでおながいしますwww

/* 
/* 
 * File:   pcr100.c
 * Author: kouji
 *
 * Created on 2009/01/05, 11:29
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <termios.h>
#include <time.h>

#define WAIT_TIME  50000
#define BUF_MAX  100
#define ID_FALSE  -1
#define ID_TRUE  1
#define ID_DEFVOL  2
#define ID_FM  0
#define ID_AM  1
#define FREQ_LEN     21
#define RS232C_PORT  "/dev/ttyS0"
#define PCR_RESET    "H000"
#define POWER_ON     "H101"
#define POWER_OFF    "H100"
#define POWER_REQ    "H1?"
#define INITPCR_C    "H101\r\nG300"
#define CRLF_C       "\r\n"
#define RESP_REQ     "G0?"
#define RESP_OK      "G000"
#define RESP_NG      "G001"
#define FREQ_HEAD    "K00"
#define FREQ_AM      "0201"
#define FREQ_FM      "0604"
#define FREQ_FOOT    "00"
#define VOL_SET      "J40"
#define VOL_DEFAULT  "J4088"
#define SQL_OFF      "J4100"
#define OFF_CMD      "off"

// グローバル構造体宣言
struct termios NewTIO,OldTIO;

// Usage表示
void Usage(void)
{
    printf("pcr100 (off) [freq(nnnn or nn.n)] [vol]\n");
    printf("[fleq]:周波数を4桁で指定します。コンマが含まれるとFMに、\n");
    printf("       それ以外はAMとして認識します。\n");
    printf("[vol] :ボリュームを指定します。0〜255までの範囲で指定します。\n");
    printf("off   :PCR100の電源を切ります。このオプションが指定されると、\n");
    printf("       他のオプションは無視されます。\n");
}

// 10進整数を16進文字列に変換
void GetHexStr(int num,char *str)
{
    int x,y;
    char tmpStr[3],hexStr[] ="0123456789ABCDEF";
    if(num > 255) num = 255;
    else if(num < 0) num = 0;
    x = num % 16;
    y = num / 16;
    tmpStr[0] = hexStr[y];
    tmpStr[1] = hexStr[x];
    tmpStr[2] = 0;
    strcpy(str,tmpStr);
}

// シリアルポート初期化
int InitSerial(char *port)
{
    int fd;
    fd = open(port,O_RDWR | O_NOCTTY);
    if (fd < 0){
        perror(port);
        return -1;
    }
    tcgetattr(fd,&NewTIO);
    tcgetattr(fd,&OldTIO);  
    cfsetispeed(&NewTIO,B9600);
    cfsetospeed(&NewTIO,B9600);
    NewTIO.c_cflag |= (CLOCAL | CREAD);
    NewTIO.c_lflag |= (ICANON);
    NewTIO.c_lflag &= ~(ECHO | ECHOE);
    NewTIO.c_oflag &= ~OPOST;
    NewTIO.c_cflag &= ~PARENB;
    NewTIO.c_cflag &= ~CSTOPB;
    NewTIO.c_cflag &= ~CSIZE;
    NewTIO.c_cflag |= CS8;
    NewTIO.c_cflag &= ~HUPCL;
    tcflush(fd, TCIFLUSH);
    tcsetattr(fd, TCSANOW, &NewTIO);
    return fd;
}

// シリアルポートを閉じる
void CloseSerial(int fd)
{
    // プログラム終了後も、信号線の切断をしない。
    OldTIO.c_cflag &= ~HUPCL;
    tcsetattr(fd,TCSANOW,&OldTIO);
    close(fd);
}

// 指定時間待機する
void WaitTimer(int second)
{
    clock_t stTime = clock();
    while(clock()-stTime <= second);
}

// コマンドを送信する
void SendCommand(char *cmd)
{
    int fd,len;
    char output[BUF_MAX];
    fd = InitSerial(RS232C_PORT);
    if(fd <= 0) return;
    strcpy(output,cmd);
    strcat(output,CRLF_C);
    len = write(fd,output,strlen(output));
    WaitTimer(WAIT_TIME);
    CloseSerial(fd);
}

// PCR100の電源を入れ、初期化する
void InitRadio()
{
    WaitTimer(WAIT_TIME);
    SendCommand(INITPCR_C);
    SendCommand(SQL_OFF);
    SendCommand(VOL_DEFAULT);
}

// PCR100の電源を切る
void EndRadio()
{
    SendCommand(POWER_OFF);
}

// 周波数をコマンドに変換する
int GetFreqStr(char *freq,char *tmpStr)
{
    char *p,*p1;
    char addStr[BUF_MAX],tmpFreq[BUF_MAX];
    int freqType;
    if(strlen(freq) != 4) return ID_FALSE;
    strcpy(tmpStr,FREQ_HEAD);
    strcpy(tmpFreq,freq);
    p=strtok(tmpFreq,".");
    p1 = strtok(NULL,".");
    if(p1 == NULL){
        sprintf(addStr,"00%s000%s",p,FREQ_AM);
        freqType = ID_AM;
    }else{
        sprintf(addStr,"0%s%s00000%s",p,p1,FREQ_FM);
        freqType = ID_FM;
    }
    strcat(tmpStr,addStr);
    strcat(tmpStr,FREQ_FOOT);
    return freqType;
}

// ボリュームをコマンドに変換する
int GetVolStr(char *vols,char *tmpStr)
{
    char addStr[BUF_MAX];
    int intvol = atoi(vols);
    if(intvol < 0) intvol = 0;
    if(intvol > 255) intvol = 255;
    strcpy(tmpStr,VOL_SET);
    GetHexStr(intvol,addStr);
    strcat(tmpStr,addStr);    
 return intvol;
}

// メインルーチン
int main(int argc, char** argv) {
    char freqStr[BUF_MAX],volStr[BUF_MAX];
    int fType,vValue;
    /* Debug
    argc = 3;
    argv[1] = malloc(sizeof(char)*4);
    argv[2] = malloc(sizeof(char)*3);
    strcpy(argv[1],"80.4");
    strcpy(argv[2],"100");
    *  Debug End */
    if((argc < 2)||(argc > 3)){
        Usage();
        return ID_FALSE;
    }
    if(argc > 1){
        if(strstr(argv[1],OFF_CMD) == NULL){
            InitRadio();
            fType = GetFreqStr(argv[1],freqStr);
            SendCommand(freqStr);
            printf("周波数=%s",argv[1]);
            if(fType == ID_AM) printf("KHz(AM MODE)にセットしました。\n");
            else printf("MHz(FM MODE)にセットしました。\n");
            if(argc == 3){
                vValue = GetVolStr(argv[2],volStr);
                SendCommand(volStr);
                printf("ボリューム値:%3d に設定しました。\n",vValue);
            }
        }else{
            EndRadio();
            printf("PCR100の電源を切りました。\n");
            return 0;
        }
    }
    /* Debug
    free(argv[1]);
    free(argv[2]);
    *  Debug End */
    return 0;
}

2011年3月1日火曜日

久々にVBS

ホームサーバのラジオアプリ(PCRC)の挙動が怪しいのでVBSでスクリプトを
組んでみた。
やってることは、PCRCが起動している場合は終了させて5秒待機、
指定のオプションを付けて再起動させるというもの。
VBさえ知っていればお手軽に作れるのが素敵です。
Option Explicit

'各種パラメータ設定
Const PCRC_PATH = "C:\Extract\PCRC\"
Const PCRC_NAME = "pcrc.exe"
Const EXEC_DELAY = 5000

'各種変数宣言
Dim strResetComm
Dim strRadioComm
Dim objShell
Dim objProcList
Dim objProcess

If WScript.Arguments.Count > 0 Then
    strResetComm = PCRC_PATH & PCRC_NAME
    strRadioComm = strResetComm & " " & WScript.Arguments.Item(0)
    Set objShell = CreateObject("WScript.Shell")
    Set objProcList = GetObject("winmgmts:").InstancesOf("win32_process")
    For Each objProcess In objProcList
        if LCase(objProcess.Name) = PCRC_NAME Then
            objShell.Run strResetComm,0,false
            WScript.Sleep(EXEC_DELAY)
            Exit For
        End If
    Next
    objShell.Run strRadioComm,0,false
Else
    WScript.Echo "パラメータを指定してください"
End If

2011年2月16日水曜日

目下勉強中!

只今応用技術者試験に向け勉強中です。
で、現在は過去問を解いてみて軽く絶望していますw
やべぇこれw
テクノロジ系はともかくとして、ストラテジ系とマネジメント系はもはや別物です。
頑張って丸暗記作戦かねこりゃ。

並行してEulerも進めてます。今は39問目というところ。
もうすこしでLevel2です。
さすがにここまでくると問題文を見た時点で大まかな実装プランが思い浮かぶようになりました。
きっと慣れてきたんでしょうね。習うより慣れろとはよく言ったモノですw
で、中学レベルの数学力も徐々に取り戻してきている感じです。
三平方の定理なんてひさしぶりにやったなあ。
この調子で言語をコード化する訓練をしていれば、午後問もなんとかなるかな?
という手応えを感じつつあります。

まあなんというか、継続は力なりというか、コツコツやってりゃ
それなりの結果は出るのかなと最近思い始めています。
そういう手応えを学生時代に少しでも感じることが出来てたら、
自分の人生も少しは変わっていたのかなーとも思ったり。
まあ人生にたらればは無いですからね。今を頑張るしかないのですがw

2011年1月23日日曜日

近況など。

お久しぶりです。
そんで明けましておめでとうございます。今年もよろしう。

今年の4月に実施される情報技術者試験ですが、応用情報技術者試験に申し込みました。
まあ会社の先輩方が続々と玉砕している試験なので、全く受かる気がしませんw
でもまあ人事は尽くすつもりではあります。
自分が今どのレベルにいるかの指標にもなるしね。

その試験対策、ってわけでもないですが、最近Project Eulerなるプログラムで解く
数学の問題集をやっています。その総問題数はなんと約320。かなりなボリュームです。
今のところ、33問目まではクリアしましたが、それでもまだ全体の10%です。
後半の問題をチラ見してみましたが、こんなん出来るかヴォケ!という問題だらけです。
でもこの問題集をやっていると、自分の中の引き出しが増える感じで、
上達しているという手応えを感じられるので、やっていて楽しいです。
今は試験対策というよりも、単純に楽しくて続けている感じ。
もうちょっと早くこういうものと出会いたかったなあ。
つくづくいい時代になったものです。