#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);
}