前回は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やら設定ファイルやらで変えられるのが望ましいのだが、めんどい。