pinewell's farmer blog 農業と電子工作、ソフトウェア、バイク、車

2013年1月28日

RaspberryPiのリモコン化2

Filed under: 未分類 — pinewell @ 2:29 PM

前回は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

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

コメントはまだありません »

No comments yet.

RSS feed for comments on this post. TrackBack URL

Leave a comment

Powered by WordPress