昨日の吹雪が嘘のように今日は穏やかな天気。
予想気温も-1℃と高め。
午後、先々日の吹雪の際に破れてしまったハウスの北面上部の修復。
クリンテートを張り直して2時間程度で終了。
2013年1月31日
ハウスの修復
2013年1月30日
ノートパソコン
以前より15,000円くらいのWindowsVista以降搭載ノートパソコンを探していた。
なかなか無くて、タブレット+USBキーボード+スマフォのテザリングでリモートデスクトップでも
良いかと思っていた所、先日、某市のハードオフにて5,000円のノートパソコンを発見。
数あるジャンク品のなかで、それだけはHDD有り。(OSは無し)
raspiやらLS-GLで2.5inchHDDが欲しかったこともあり、先日札幌で中古を探しても安くなかった。
仮にHDDを1,500円で買ったとしてもノートPCが3,500円で買えることになる。
安めのSSDを買って換装すればまだまだ使えるだろうと。
Lenovo 3000 C200。スペックは、
CPU ●CeleronM 430(WindowsVistaモデル)
チップセット ●945GM(WindowsVistaモデル)
メモリ ●1GBに増設済み
ディスプレイ ●15.0V型TFT液晶(1,024×768ドット)
HDD ●80GB
光学ドライブ ●CD-RW&DVDコンボ・ドライブ、
無線LAN 標準装備(Lenovo IEEE802.11b/g ワイヤレスLAN(Wi-Fi準拠))
だった。
スマフォで検索しても、10,000円より下ということは無かったので、思わず購入。
自宅に戻り、HDDのチェックを行い問題無いことを確かめ、Windows7をインストール。問題無し。おぉ、使えるねぇ。
裏を見て、簡単に外せるネジと蓋を開けてみる(3ヶ所)。
メモリはBuffaloの1GBx1枚に換装されている。・・・あれ?これってウチで以前BuffSHOPのジャンク箱に入っていたメモリが使えるじゃん。
って、ことで1GBx1枚が2GBx2枚の4GBに換装。(が、チップセットの制限で3GBまでの認識となる。)
HDDの蓋を開けてみると換装は容易。NTT-XストアでSP032GBSS2T10S25 を発注。3,703円。
もうひとつの蓋はCPUファンとCPUソケットの蓋だった。ワシはあまりノートパソコンを買っていなかったので知らなかったのだが、
この頃のCPUはSocketMで構成されており、CPUの換装も容易だった。
まぁしかしBIOSの対応状況はメーカー製PCということで不明。
Celeron M430は 1.73 GHz (133×13) / FSB533MHz ということなので、FSB800MHzは対応していないかもしれない。
悩んだ結果、中古価格もこなれている Core2 Duo T5600/1.83G/667 をチョイス。ヤフオクゲット。
無事、BIOSでも認識して換装成功となった。
SSD・CPU・メモリーが換装されて、新生Lenovo 3000 C200。
心配だったのはCore2Duoの発熱。Windows8proをインストールしてOCCTを動作させたところ、MAX84℃で高値安定。
1時間のテストを乗り越えたのでまぁ通常使用には問題無いだろうと思う。
本体:5,250円
SSD:3,703円
メモリ:死蔵品だったので0円
CPU:2,160円
——————–
Total: 11,113円
予定どおり、15,000円以内で必要十分なスペックのノートPCが手に入り満足。
SSDの効果もあるがWindows8は起動が早くて良い。ただ、他に良い所は無い。はっきり言って使い辛い。
・・・本当はDELLのCore i3 搭載15インチノート 24,980円が欲しかったのだが。(新規かつ法人限定だったため購入不可だった)
2013年1月28日
RaspberryPiのリモコン化3
リモコンのindex.html
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 |
<html> <head> <meta http-equiv="Content-Type" content="text/html;charset=UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=5"> <title>リモコン</title> <script type="text/javascript"> <!-- function sendIr(cmdstr,port){ xmlhttp = new XMLHttpRequest(); xmlhttp.open('GET', 'sendIr.php?cmdstr='+cmdstr+'&port='+port, true); xmlhttp.onreadystatechange = function() { if (xmlhttp.readyState == 4 && xmlhttp.status == 200) { } } xmlhttp.send(null); } function sendrs(cmdstr){ xmlhttp = new XMLHttpRequest(); xmlhttp.open('GET', 'sendrs.php?cmd='+cmdstr, true); xmlhttp.onreadystatechange = function() { if (xmlhttp.readyState == 4 && xmlhttp.status == 200) { } } xmlhttp.send(null); } //--> </script> </head> <body> <div style="text-align: center">テレビ<br> <hr> <INPUT type="Button" value="電源ON" name="btnTVPOWON" style="WIDTH: 142px; HEIGHT: 36px" ONCLICK="sendIr('TVPWR',3);"> <INPUT type="Button" value="電源OFF" name="btnTVPOWOFF" style="WIDTH: 142px; HEIGHT: 36px" ONCLICK="sendrs('1');"> <br> <INPUT type="Button" value="チャンネル↑" name="btnTVPOWOFF" style="WIDTH: 142px; HEIGHT: 36px" ONCLICK="sendrs('7');"> <INPUT type="Button" value="チャンネル↓" name="btnTVPOWON" style="WIDTH: 142px; HEIGHT: 36px" ONCLICK="sendrs('8');"> <br> <INPUT type="Button" value="ボリューム↑" name="btnTVPOWOFF" style="WIDTH: 142px; HEIGHT: 36px" ONCLICK="sendIr('TVVOU',3)"> <INPUT type="Button" value="ボリューム↓" name="btnTVPOWON" style="WIDTH: 142px; HEIGHT: 36px" ONCLICK="sendIr('TVVOD',3)"> <br> <INPUT type="Button" value="Blu-Ray" name="btnTVPOWOFF" style="WIDTH: 142px; HEIGHT: 36px" ONCLICK="sendrs('2');"> <INPUT type="Button" value="LinkTheater" name="btnTVPOWON" style="WIDTH: 142px; HEIGHT: 36px" ONCLICK="sendrs('3');"> <br> <INPUT type="Button" value="AVAMP" name="btnTVPOWOFF" style="WIDTH: 142px; HEIGHT: 36px" ONCLICK="sendrs('4');"> <INPUT type="Button" value="PS2" name="btnTVPOWON" style="WIDTH: 142px; HEIGHT: 36px" ONCLICK="sendrs('5');"> <br> <INPUT type="Button" value="Wii" name="btnTVPOWOFF" style="WIDTH: 142px; HEIGHT: 36px" ONCLICK="sendrs('6');"> <INPUT type="Button" value="入力切替" name="btnTVPOWON" style="WIDTH: 142px; HEIGHT: 36px" ONCLICK="sendIr('TVINP',3)"> <br> <INPUT type="Button" value="地デジ" name="btnTVPOWOFF" style="WIDTH: 142px; HEIGHT: 36px" ONCLICK="sendrs('9');"> <INPUT type="Button" value="BS" name="btnTVPOWON" style="WIDTH: 142px; HEIGHT: 36px" ONCLICK="sendrs('10');"> <br> <INPUT type="Button" value="CS" name="btnTVPOWOFF" style="WIDTH: 142px; HEIGHT: 36px" ONCLICK="sendrs('11');"> <INPUT type="Button" value="消音" name="btnTVPOWOFF" style="WIDTH: 142px; HEIGHT: 36px" ONCLICK="sendrs('12');"> <hr>AVアンプ<br> <INPUT type="Button" value="電源" name="btnTVPOWOFF" style="WIDTH: 290px; HEIGHT: 36px" ONCLICK="sendIr('AMPPWR',1)"> <br> <INPUT type="Button" value="ボリューム↑" name="btnTVPOWOFF" style="WIDTH: 142px; HEIGHT: 36px" ONCLICK="sendIr('AMPVOU',1)"> <INPUT type="Button" value="ボリューム↓" name="btnTVPOWON" style="WIDTH: 142px; HEIGHT: 36px" ONCLICK="sendIr('AMPVOD',1)"> <br> <INPUT type="Button" value="BD/DVD" name="btnTVPOWOFF" style="WIDTH: 142px; HEIGHT: 36px" ONCLICK="sendIr('AMPBD',1)"> <INPUT type="Button" value="CBL/SAT" name="btnTVPOWON" style="WIDTH: 142px; HEIGHT: 36px" ONCLICK="sendIr('AMPCBL',1)"> <br> <INPUT type="Button" value="STB/DVR" name="btnTVPOWOFF" style="WIDTH: 142px; HEIGHT: 36px" ONCLICK="sendIr('AMPSTB',1)"> <INPUT type="Button" value="GAME" name="btnTVPOWON" style="WIDTH: 142px; HEIGHT: 36px" ONCLICK="sendIr('AMPGAME',1)"> <br> <INPUT type="Button" value="PC" name="btnTVPOWOFF" style="WIDTH: 142px; HEIGHT: 36px" ONCLICK="sendIr('AMPPC',1)"> <INPUT type="Button" value="AUX" name="btnTVPOWON" style="WIDTH: 142px; HEIGHT: 36px" ONCLICK="sendIr('AMPAUX',1)"> <br> <INPUT type="Button" value="AM" name="btnTVPOWOFF" style="WIDTH: 142px; HEIGHT: 36px" ONCLICK="sendIr('AMPAM',1)"> <INPUT type="Button" value="FM" name="btnTVPOWON" style="WIDTH: 142px; HEIGHT: 36px" ONCLICK="sendIr('AMPFM',1)"> <br> <INPUT type="Button" value="TV/CD" name="btnTVPOWOFF" style="WIDTH: 142px; HEIGHT: 36px" ONCLICK="sendIr('AMPTV',1)"> <INPUT type="Button" value="NET" name="btnTVPOWON" style="WIDTH: 142px; HEIGHT: 36px" ONCLICK="sendIr('AMPNET',1)"> <br> <INPUT type="Button" value="USB" name="btnTVPOWOFF" style="WIDTH: 142px; HEIGHT: 36px" ONCLICK="sendIr('AMPUSB',1)"> <INPUT type="Button" value="" name="" style="WIDTH: 142px; HEIGHT: 36px" > <br> <INPUT type="Button" value="↑" name="btnTVPOWOFF" style="WIDTH: 290px; HEIGHT: 36px" ONCLICK="sendIr('AMPUP',1)"> <br> <INPUT type="Button" value="←" name="btnTVPOWOFF" style="WIDTH: 142px; HEIGHT: 36px" ONCLICK="sendIr('AMPLEFT',1)"> <INPUT type="Button" value="→" name="btnTVPOWON" style="WIDTH: 142px; HEIGHT: 36px" ONCLICK="sendIr('AMPRIGHT',1)"> <br> <INPUT type="Button" value="↓" name="btnTVPOWON" style="WIDTH: 290px; HEIGHT: 36px" ONCLICK="sendIr('AMPDOWN',1)"> <br> <INPUT type="Button" value="ENTER" name="btnTVPOWOFF" style="WIDTH: 142px; HEIGHT: 36px" ONCLICK="sendIr('AMPENT',1)"> <INPUT type="Button" value="RETURN" name="btnTVPOWON" style="WIDTH: 142px; HEIGHT: 36px" ONCLICK="sendIr('AMPRET',1)"> </div> </body> </html> |
index.htmlからajaxで呼ばれるsendrs.php
1 2 3 4 |
<?php if (!isset($_GET['cmd'])) { $cmd=1;} else {$cmd=$_GET['cmd'];} exec(dirname(__FILE__)."/sendrc ".$cmd); ?> |
同じくsendIr.php
1 2 3 4 5 |
<?php if (!isset($_GET['cmdstr'])) { $cmdstr="NULL";} else {$cmdstr=$_GET['cmdstr'];} if (!isset($_GET['port'])) { $port=1; } else {$port=$_GET['port'];} exec(dirname(__FILE__)."/sendIr ".$cmdstr." ".$port." /dev/ttyUSB0"); ?> |
これで、スマフォでもリモコンが快適に。
とりあえず、AVアンプとテレビだけだが。
なにかケースを作らなければ。
RaspberryPiのリモコン化2
前回はGPIOからのスイッチ入力でAQUOSをコントロールした。
今回はKURO-RSをRaspberryPiに接続。
思わぬところでハマったのがftdi_sio。これがなぜだかハングアップする。
ググってみるとどうやらそういうものらしい。とりあえず /boot/cmdline.txtにdwc_otg.speed=1を追記。
これはUSBをフルスピード固定にしてしまうものらしい。フルスピードと言えば12Mbps。シリアル通信には充分ではある。
さらに、電源つけっぱなしで放置しておくとネットワークがフリーズすることが度々・・・。
これは/boot/cmdline.txtにsmsc95xx.turbo_mode=Nを追記することで解決した。
これも半2重にする意味のようなので遅くはなるのだろう。リモコン用途では充分。
kuro-rsを接続してもftdi_sioは自動では読み込まれない。これは
/sbin/modprobe ftdi_sio vendor=0x0411 product=0x00b3 とする。これで/dev/ttyUSB0ができる。
通常www-dataでは/dev/ttyUSB0は読み書きできないのでこれへの対処。(ユーザーを追加とか、chmodしちゃうとか)。
kuro-rsで使用するソフトウェアはkuro-rsに付属していたものなのでソースはアップできない。
rs_rec.cをコンパイルして、TVPOWやその他リモコンのデータを取得。
rs_send.cをコンパイルしてsendIrとした。
lighttpdとphpをapt-getして、lighttpdでPHPを使えるようにする。
phpからraspiのシリアル(/dev/ttyAMA0)を経由してAQUOSをコントロールするためのsendrc.c
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 |
#include <stdio.h> #include <stdlib.h> #include <bcm2835.h> #include <signal.h> #include<string.h> #include<strings.h> #include<termios.h> #include<unistd.h> #include<fcntl.h> #include<stdarg.h> #include<unistd.h> #include <syslog.h> #include <errno.h> //スイッチコマンド #define SW1_CMD "\rPOWR0000\r" //POWER OFF #define SW2_CMD "\rIAVD1 \r" //入力切り替え1 #define SW3_CMD "\rIAVD2 \r" // 2 #define SW4_CMD "\rIAVD3 \r" #define SW5_CMD "\rIAVD4 \r" #define SW6_CMD "\rIAVD5 \r" #define SW7_CMD "\rCHUP \r" //チャンネルUP #define SW8_CMD "\rCHDW \r" //チャンネルDOWN #define SW9_CMD "\rCTBD031 \r" //地デジ #define SW10_CMD "\rCBSD103 \r" //BS #define SW11_CMD "\rCCSD350 \r" //CS #define SW12_CMD "\rVOLM0 \r" //消音 #define BAUDRATE B9600 /* 通信速度の設定 */ #define MODEMDEVICE "/dev/ttyAMA0" /* デバイスファイルの指定:COM1 */ #define FALSE 0 #define TRUE 1 #define MC 4 /* 読み込む文字数 */ volatile int STOP=FALSE; //シリアルへのコマンド送信 void main(int argc,char *argv[]) { int cmdno=1; int fd, c, res, i; /* fd:ファイルディスクリプタ res:受け取った文字数 */ struct termios oldtio, newtio; /* 通信ポートを制御するためのインターフェイス */ char buf[255]; /* 受信文字を格納 */ if (argc == 2) { cmdno=atoi(argv[1]); if (cmdno==0) cmdno=1; if (cmdno > 12) cmdno=1; } if((fd=open(MODEMDEVICE, O_RDWR | O_NOCTTY))== -1){ /* O_RDWR:読み書き両用 O_NOCTTY:tty制御をしない */ perror(MODEMDEVICE); exit(-1); } tcgetattr(fd, &oldtio); /* 現在のシリアルポートの設定を退避させる */ bzero(&newtio, sizeof(newtio)); /* 新しいポートの設定の構造体をクリア */ newtio.c_cflag= (BAUDRATE | CS8 | CLOCAL | CREAD); /* CRTSCTS:フロー制御有り CS8:8ビット、ノンパリティ、ストップビット1 * CLOCAL:モデムの状態信号を無視 CREAD:受信可能にする */ newtio.c_iflag=IGNPAR; /* IGNPAR:パリティエラーの文字は無視 */ newtio.c_oflag=0; /* rawモード */ newtio.c_lflag=0; /* 非カノニカル入力 */ newtio.c_cc[VTIME]=0; /* キャラクタ間タイマは未使用 */ newtio.c_cc[VMIN]=MC; /* MC文字受け取るまでブロックする */ tcflush(fd,TCIFLUSH); /* ポートのクリア */ tcsetattr(fd, TCSANOW, &newtio); /* ポートの設定を有効にする */ char strbuf[20]; switch (cmdno){ case 1: strcpy(strbuf,SW1_CMD); break; case 2: strcpy(strbuf,SW2_CMD); break; case 3: strcpy(strbuf,SW3_CMD); break; case 4: strcpy(strbuf,SW4_CMD); break; case 5: strcpy(strbuf,SW5_CMD); break; case 6: strcpy(strbuf,SW6_CMD); break; case 7: strcpy(strbuf,SW7_CMD); break; case 8: strcpy(strbuf,SW8_CMD); break; case 9: strcpy(strbuf,SW9_CMD); break; case 10: strcpy(strbuf,SW10_CMD); break; case 11: strcpy(strbuf,SW11_CMD); break; case 12: strcpy(strbuf,SW12_CMD); break; default: strcpy(strbuf,"\rPOWR0000\r"); } //コマンド送信 write(fd,strbuf,sizeof(strbuf)); tcsetattr(fd, TCSANOW, &oldtio); /* 退避させた設定に戻す */ close(fd); /* COM1のシリアルポートを閉じる */ printf("cmdno: %d",cmdno); exit(0); } |
使い方は./sendrs 1 とか。1~12に送信するコマンドをハードコーディングしている。
本来ならusageやら設定ファイルやらで変えられるのが望ましいのだが、めんどい。
RaspberryPiのリモコン化
さて、1月ももう終わり。
USBカメラ+motionでは安定して動作できなかったRaspberryPi。
使い道を模索していたのだが、リビングに置いてあるLS-GLをPiに置き換えようかと。
さらにどうせなら外部スイッチでの動作もさせたい。
ウチはAQUOSなのだが、本体に電源ボタンが無い(リモコンの電源)。
出かける際(本体の電源をオフにしても良いのだが)にリモコンを探してオフする必要がある。
テレビ近くにタクトスイッチを用意しておけばこれで解決。
さらに入力切替が気に入らない。ボタンを何度も押さなくてはならない。
幸いAQUOSにはPCと繋げるためのRS-232Cがあるのでこれを利用しない手はない。
LS-GL+KURO-RSの学習リモコンでは解決できなかったこれら課題をクリアしよう、と。
まず、raspiのGPIOポートの内、3V3POWERとGround、TXDとRXDを用いて、AQUOSとの通信を可能とする。
3.3Vのレベルなので、RS-232Cとの接続のために手元にあったADM3202ANを使用。AQUOSとはクロス結線。
とりあえず、コマンドを送って電源オフなりが出きることを確認。1段階クリア。
次に、タクトスイッチの取り付け。これは当初プレステのコントローラでもGPIOに接続してやろうかと
思ったのだが、Arduinoでの実験は成功したものの、raspiでの接続例は探しきれず断念。
部材は揃えたのでいつかやってやろうと思う。
タクトスイッチは6個。左画像の下の方のピンを使用した。GPIO7,8,9,10,11,25。
これを3.3V、10kオームの抵抗でプルアップして使用した。
ソフトウェア部はC library for Broadcom BCM 2835 as used in Raspberry Pi を使用して作成。
以下ソース。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 |
#include <stdio.h> #include <stdlib.h> #include <bcm2835.h> #include <signal.h> #include <string.h> #include <strings.h> #include <termios.h> #include <unistd.h> #include <fcntl.h> #include <stdarg.h> #include <unistd.h> #include <syslog.h> #include <errno.h> //スイッチのピン定義 #define SW1 RPI_V2_GPIO_P1_26 #define SW2 RPI_V2_GPIO_P1_24 #define SW3 RPI_V2_GPIO_P1_21 #define SW4 RPI_V2_GPIO_P1_19 #define SW5 RPI_V2_GPIO_P1_22 #define SW6 RPI_V2_GPIO_P1_23 //スイッチコマンド #define SW1_CMD "\rPOWR0000\r" //POWER OFF #define SW2_CMD "\rIAVD1 \r" //入力切り替え1 #define SW3_CMD "\rIAVD2 \r" // 2 #define SW4_CMD "\rIAVD3 \r" #define SW5_CMD "\rIAVD4 \r" #define SW6_CMD "\rIAVD5 \r" #define BAUDRATE B9600 /* 通信速度の設定 */ #define MODEMDEVICE "/dev/ttyAMA0" /* デバイスファイルの指定:COM1 */ #define FALSE 0 #define TRUE 1 #define MC 4 /* 読み込む文字数 */ volatile int STOP=FALSE; static void log_write(char *fmt, ...); // 割り込みコールバック関数 void signal_callback_handler(int signum) { //printf("\ndetect key interrupt\n",signum); log_write("detect interrupt",signum); bcm2835_close(); printf("stop daemon",0); exit(0); } //シリアルへのコマンド送信 int sendcmd(int cmdno) { int fd, c, res, i; /* fd:ファイルディスクリプタ res:受け取った文字数 */ struct termios oldtio, newtio; /* 通信ポートを制御するためのインターフェイス */ char buf[255]; /* 受信文字を格納 */ if((fd=open(MODEMDEVICE, O_RDWR | O_NOCTTY))== -1){ /* O_RDWR:読み書き両用 O_NOCTTY:tty制御をしない */ perror(MODEMDEVICE); return(-1); } tcgetattr(fd, &oldtio); /* 現在のシリアルポートの設定を退避させる */ bzero(&newtio, sizeof(newtio)); /* 新しいポートの設定の構造体をクリア */ newtio.c_cflag= (BAUDRATE | CS8 | CLOCAL | CREAD); /* CRTSCTS:フロー制御有り CS8:8ビット、ノンパリティ、ストップビット1 * CLOCAL:モデムの状態信号を無視 CREAD:受信可能にする */ newtio.c_iflag=IGNPAR; /* IGNPAR:パリティエラーの文字は無視 */ newtio.c_oflag=0; /* rawモード */ newtio.c_lflag=0; /* 非カノニカル入力 */ newtio.c_cc[VTIME]=0; /* キャラクタ間タイマは未使用 */ newtio.c_cc[VMIN]=MC; /* MC文字受け取るまでブロックする */ tcflush(fd,TCIFLUSH); /* ポートのクリア */ tcsetattr(fd, TCSANOW, &newtio); /* ポートの設定を有効にする */ char strbuf[20]; switch (cmdno){ case 1: strcpy(strbuf,SW1_CMD); break; case 2: strcpy(strbuf,SW2_CMD); break; case 3: strcpy(strbuf,SW3_CMD); break; case 4: strcpy(strbuf,SW4_CMD); break; case 5: strcpy(strbuf,SW5_CMD); break; case 6: strcpy(strbuf,SW6_CMD); break; default: strcpy(strbuf,"\rPOWR0000\r"); } //コマンド送信 write(fd,strbuf,sizeof(strbuf)); tcsetattr(fd, TCSANOW, &oldtio); /* 退避させた設定に戻す */ close(fd); /* COM1のシリアルポートを閉じる */ return(0); } static void become_daemon(void) { int n; if (chdir("/")<0) { log_write("chdir(2) failed: %s",strerror(errno)); exit(0); } freopen("/dev/null","r",stdin); freopen("/dev/null","w",stdout); freopen("/dev/null","w",stderr); n = fork(); if (n<0) log_write("fork(2) failed: %s",strerror(errno)); if (n !=0) _exit(0); if (setsid() <0) { log_write("setsid(2) failed: %s",strerror(errno)); _exit(0); } log_write("start daemon",0); } int main(int argc, char **argv) { //デーモン化を試みる。 openlog("remoteaquos",LOG_PID|LOG_NDELAY,LOG_DAEMON); become_daemon(); if (!bcm2835_init()) return 1; bcm2835_gpio_fsel(SW1, BCM2835_GPIO_FSEL_INPT); bcm2835_gpio_fsel(SW2, BCM2835_GPIO_FSEL_INPT); bcm2835_gpio_fsel(SW3, BCM2835_GPIO_FSEL_INPT); bcm2835_gpio_fsel(SW4, BCM2835_GPIO_FSEL_INPT); bcm2835_gpio_fsel(SW5, BCM2835_GPIO_FSEL_INPT); bcm2835_gpio_fsel(SW6, BCM2835_GPIO_FSEL_INPT); // VCCまでプルアップする bcm2835_gpio_set_pud(SW1, BCM2835_GPIO_PUD_UP); bcm2835_gpio_set_pud(SW2, BCM2835_GPIO_PUD_UP); bcm2835_gpio_set_pud(SW3, BCM2835_GPIO_PUD_UP); bcm2835_gpio_set_pud(SW4, BCM2835_GPIO_PUD_UP); bcm2835_gpio_set_pud(SW5, BCM2835_GPIO_PUD_UP); bcm2835_gpio_set_pud(SW6, BCM2835_GPIO_PUD_UP); signal(SIGINT, signal_callback_handler); //printf("press ^C to exit program ...\n"); while (1) { uint8_t sw_val1 = bcm2835_gpio_lev(SW1); uint8_t sw_val2 = bcm2835_gpio_lev(SW2); uint8_t sw_val3 = bcm2835_gpio_lev(SW3); uint8_t sw_val4 = bcm2835_gpio_lev(SW4); uint8_t sw_val5 = bcm2835_gpio_lev(SW5); uint8_t sw_val6 = bcm2835_gpio_lev(SW6); uint8_t value = sw_val1 +sw_val2 +sw_val3 +sw_val4 +sw_val5 +sw_val6; if (value != 6) { //何らかのスイッチが押されている。 log_write("read from pin: %d %d %d %d %d %d\n", sw_val1,sw_val2,sw_val3,sw_val4,sw_val5,sw_val6,0); if(sw_val1 == 0 ) { sendcmd(1); } if(sw_val2 == 0 ) { sendcmd(2); } if(sw_val3 == 0 ) { sendcmd(3); } if(sw_val4 == 0 ) { sendcmd(4); } if(sw_val5 == 0 ) { sendcmd(5); } if(sw_val6 == 0 ) { sendcmd(6); } } delay(50); // 0.005秒待つ } } static void log_write(char *fmt, ...) { va_list ap; va_start(ap, fmt); vsyslog(LOG_ERR,fmt,ap); va_end(ap); } |
gcc -o remoteaquos -l bcm2835 -lrt remoteaquos.c /usr/local/lib/libbcm2835.a
一応、デーモン化してログに出力するようにしている。
これでタクトスイッチで電源OFFと入力切替が可能になった。