質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

Q&A

1回答

1896閲覧

ラズパイのシグナルハンドラ、タクトスイッチON、OFFの入力を反映させたい

mkm

総合スコア15

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

0グッド

0クリップ

投稿2021/04/26 11:53

編集2021/04/26 21:39

実現したいこと
ラズパイにて
タクトスイッチオン→LEDとブザーがON
もう一度タクトスイッチを押す→LEDとブザーがOF
システム終了をしない限りは、上記の繰り返しを行うシステムを実現させたいです

現状ではタクトスイッチを押した際にLEDとブザーは反応するのですが
再度タクトスイッチを押下してもLEDとブザーが反応したままになっています。
また、シグナルハンドラを呼び出した際にもLEDとブザーが反応したままなので、消したいです。

#include<stdio.h> #include<string.h> #include<wiringPi.h> #include<signal.h> #define GPIO_LED 21 #define GPIO_TCT 20 #define GPIO_BUZ 5 void motion_on(int flag2); void motion_off(void); void Signal (int sig_name); void SetSignal(int sig_name); void tct_callbak(void); volatile sig_atomic_t flag = 0; int main(void){ if(wiringPiSetupGpio()==-1){ return 1; } pinMode(GPIO_LED,OUTPUT); pinMode(GPIO_TCT,INPUT); pinMode(GPIO_BUZ,OUTPUT); pullUpDnControl(GPIO_TCT,PUD_DOWN); pullUpDnControl(GPIO_LED,PUD_DOWN); pullUpDnControl(GPIO_BUZ,PUD_DOWN); signal(SIGINT,Signal); wiringPiISR(GPIO_TCT,INT_EDGE_BOTH,tct_callbak); while(flag==0){ }; return 0; } void tct_callbak(void){ if(digitalRead(GPIO_TCT)==HIGH){ motion_on(1); }else if(digitalRead(GPIO_TCT)==LOW){ motion_off() ; } } void motion_on(int flag2){ digitalWrite(GPIO_BUZ,HIGH); for(int i=0; i<10;i++){ digitalWrite(GPIO_LED,HIGH); delay(500); digitalWrite(GPIO_LED,LOW); delay(500); } flag2=1; while(flag2==1){ digitalWrite(GPIO_LED,HIGH); digitalWrite(GPIO_BUZ,HIGH); } } void motion_off(void){ printf("OFFのよびだし"); digitalWrite(GPIO_BUZ,LOW); digitalWrite(GPIO_LED,LOW); motion_on(0); } void SetSignal(int sig_name){ f(signal(sig_name , Signal)==SIG_ERR){ printf("シグナル設定が出来ませんでした"); } } void Signal (int sig_name){ char str[3]; char str2[]="YES"; printf("システムを終了しますか。YES/NO\n"); scanf("%s",str); if(strcmp (str,str2)==0){ flag=1; }else{ flag=0; } }

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

y_waiwai

2021/04/26 11:55

このままではコードが見づらいので、質門を編集し、<code>ボタンで、出てくる’’’の枠の中にコードを貼り付けてください
y_waiwai

2021/04/26 12:31

行番号抜きましょうよ。。
guest

回答1

0

「システム終了」というと普通はRaspberryPiをシャットダウンするようなことをいうと思うけど...このプログラムだけの話なら「プログラム終了」とか「アプリケーション終了」とか。

それはともかく。flagとかflag2とか、体を表さない名前で混乱している面もあるのではないでしょうか。

ついでに言えば、singalとSignalとか、数文字の大文字小文字で別のシンボルになるような命名も混乱の元です。

C

1 void motion_on(int flag2){ 2 3 digitalWrite(GPIO_BUZ,HIGH); 4 5 for(int i=0; i<10;i++){ 6 digitalWrite(GPIO_LED,HIGH); 7 delay(500); 8 digitalWrite(GPIO_LED,LOW); 9 delay(500); 10 } 11 12 flag2=1; //<--flag2を1にしているのだから... 13 while(flag2==1){ //ここでは常にflag2==1は真なので無限ループ 14 digitalWrite(GPIO_LED,HIGH); 15 digitalWrite(GPIO_BUZ,HIGH); 16 } 17 }

motion_on()は一度入ると絶対に抜けられないブラックホールのような関数になっています。その中で、LEDやブザーをONしているのですから、それ以外の動作はできません。

シグナルハンドラを呼び出した際にもLEDとブザーが反応したまま

シグナルハンドラによって変数が書き換えられたらメインのプログラムを終了する動作をしているのですから、その終了動作にLEDとブザーをOFFにする処理を加えれば止まります。

投稿2021/04/26 22:38

thkana

総合スコア7703

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

mkm

2021/04/26 23:32

回答ありがとうございます 命名については変えてみます。 void motion_on(int flag2)のところに「0」が入ってきても「flag2=1」で常に「1」 になってしまう、ということですかね
thkana

2021/04/26 23:47

「なってしまう」というか、あなたがプログラムで「そうしろ」と書いているからなのですけれど。そもそもどういう意図だったのでしょう?
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問