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

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

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

Arduinoは、AVRマイコン、単純なI/O(入出力)ポートを備えた基板、C言語を元としたArduinoのプログラム言語と、それを実装した統合開発環境から構成されたシステムです。

Q&A

解決済

1回答

1207閲覧

arduino 割り込み方法

FumiKili

総合スコア7

Arduino

Arduinoは、AVRマイコン、単純なI/O(入出力)ポートを備えた基板、C言語を元としたArduinoのプログラム言語と、それを実装した統合開発環境から構成されたシステムです。

0グッド

0クリップ

投稿2017/10/10 07:54

編集2017/10/10 07:56

よろしくお願いします。

arduinoを使用して2つのリレーを制御したいのです。
リレーはタイマーを使用してボタンを押すと指定時間通電する。

ここまでは達成できました。

Aボタン 1番リレー(30秒で切れる)
Bボタン 2番リレー(30秒で切れる)
Cボタン 1、2番リレーが作動中でも強制停止

このCボタンのA,Bリレー作動中の強制停止ができません。

コードはardublockで作りました。
Cボタンを押すとA,Bリレーが作動中でも強制停止するコードを教えて下さい。
CボタンはD4番に入っています。

boolean __ardublockDigitalRead(int pinNumber)
{
pinMode(pinNumber, INPUT);
return digitalRead(pinNumber);
}

void setup()
{
pinMode( 8 , OUTPUT);
pinMode( 9 , OUTPUT);
}

void loop()
{
while ( __ardublockDigitalRead(2) )
{
digitalWrite(8 , HIGH);
delay( 3000 );
digitalWrite(8 , LOW);
}

while ( __ardublockDigitalRead(3) )
{
digitalWrite(9 , HIGH);
delay( 3000 );
digitalWrite(9 , LOW);
}

}

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

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

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

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

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

guest

回答1

0

ベストアンサー

ardublockは使ったことが無いので多くの人が使用してるarduino IDEを用いて回答します。
まず割り込みに関してはハード的に割り込みを掛けれるのは’attachInterrupt(interrupt, function, mode)'を用いて割り込みを定義しての方法。arduinoの種類が分かりませんので一般的に使われているUNOとしてはUNOの場合は2つのピンに定義できます。
参考になるサイトはArduinoで遊ぶブログ等です。
さて貴殿の質問ではスイッチがpull upされているのか?それとも押下で0Vになるのかが不明です。(ハード、特に結線)が示されると的確な回答が可能かと思われます。

前置きの説明と貴殿のソースの比較から説明します。
'loop'の中では”ポーリング”でAとBのスイッチの状態で’3秒’だけPinの8もしくは9がHighになる。(30秒の場合は引数が30000)。そしてこの間に割り込み処理をするとすれば前述の’attachInterrupt(interrupt, function, mode)’をsetup中で定義しその際に関数’function’に強制的にPin8及び9をLOWにする処理を書けば解決すると思われます。

追記。私ならばのソースを追加。
arduino UNOでarduino IDEの場合。

arduino

1#define relay_1 8 2#define relay_2 9 3#define sw_a 4 // optimaize.original as pin2 4#define sw_b 3 5#define sw_c 2 6void function(void){ 7 digitalWrite(relay_1,LOW); 8 digitalWrite(relay_2,LOW); 9} 10void setup(){ 11 pinMode(relay_1,OUTPUT); 12 pinMode(relay_2,OUTPUT); 13 pinMode(sw_a,INPUT_PULLUP); 14 pinMode(sw_b,INPUT_PULLUP); 15 pinMode(sw_c,INPUT_PULLUP); 16 attachInterrupt(0, function, FALLING); 17} 18void loop(){ 19 if(digitalRead(sw_a) == 0){ // ポーリングでAとBの個別処理 20 digitalWrite(relay_1,HIGH); 21 delay(30000); 22 digitalWrite(relay_1,LOW); 23 } 24 if(digitalRead(sw_b) == 0){ 25 digitalWrite(relay_2,HIGH); 26 delay(30000); 27 digitalWrite(relay_2,LOW); 28 } 2930

ポーリングなのでAとBが同時の押された場合は先に検知した方が優先ですが。
別々の30秒づつならばMsTimer2辺りのタイマー割り込みで処理が必要です。

投稿2017/10/10 13:54

編集2017/10/12 00:41
MasahikoHirata

総合スコア3747

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

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

FumiKili

2017/10/11 08:09

回答ありがとうございます。スイッチはプルアップで組んであります。 使用しているのはarduino unoです。 【関数’function’に強制的にPin8及び9をLOWにする処理を書けば解決すると思われます。】 この辺が・・・ぜんぜん理解できません。 このページに http://easylabo.com/2015/04/arduino/8357/ dailyには割り込みができい。←? 割り込みが掛けられるのは2.3ピン と記載されていました。
MasahikoHirata

2017/10/11 10:14

はい。物理的な割り込み(他にはタイマー割り込みも割り込みの一種)。Unoでは2番3番がINT0とINT1の物理割り込みです。そこで動作中のプログラムに関係なく、ピンの値が私の回答にある参考ページにもある変化の4種類①RISING②CHANGE③FALLING④LOWのいずれかをきっかけにattachInterrupt関数の中で何をするかの関数functionで定義します。貴殿の回答からPULLUPの場合HIGHからLOWに遷移するのでFALLINGを起因にして、functionの中では強制的にdigitalWrite(8,LOW);とdigitalWrite(9,LOW);だけを記載すれば動きます。
FumiKili

2017/10/11 10:44

すいません 意味は解るんですがコードが書けません。エラーになってしまいます。
MasahikoHirata

2017/10/11 11:43

分かりました。回答を編集してソースを掲示します。
FumiKili

2017/10/11 12:12

Arduino:1.6.9 (Windows 10), ボード:"Arduino/Genuino Uno" led_button:29: error: stray '\357' in program ?ス? ^ led_button:29: error: stray '\275' in program led_button:29: error: stray '\235' in program C:\Users\kili\Desktop\ch2\led_button\led_button.ino: In function 'void loop()': led_button:19: error: 'degitalRead' was not declared in this scope if(degitalRead(sw_a) == 0){ // 繝昴?シ繝ェ繝ウ繧ー縺ァA縺ィB縺ョ蛟句挨蜃ヲ逅? ^ led_button:24: error: 'degitalRead' was not declared in this scope if(degitalRead(sw_b) == 0){ ^ led_button:28: error: expected '}' at end of input } ^ exit status 1 stray '\357' in program 「ファイル」メニューの「環境設定」から 「より詳細な情報を表示する:コンパイル」を有効にすると より詳しい情報が表示されます。
FumiKili

2017/10/11 12:13

このエラーが出ます。 それにしても 自分の書いたコードは絵ですね・・・・
MasahikoHirata

2017/10/11 14:58

失礼。degitalReadはdigitalReadの誤りです。ここを修正して再度コンパイルを。机上でしたので。
FumiKili

2017/10/11 16:09

ありがとうございます。 コンパイルできました。 今の状態は2つのリレーが連続して30秒交互に動いています。 停止ボタンも作動しますが10秒経過すると元に戻り リレーが交互に動き始めます。 ボタンを押してから リレーがON  何も無ければ30秒で停止 停止ボタンを押したら リレーOFF このようにしたいのですが どうでしょうか?
FumiKili

2017/10/11 16:27

すいません。 スイッチの配線が逆でした。 ありがとうございます。完成しました。 もう一つだけ よろしいでしょうか 停止ボタンで停止後 30秒間 A,Bボタンも無効になってしまいます。 できれば停止ボタンで停止後 ボタンを押すと すぐにONになるようには できますか?
FumiKili

2017/10/12 23:06

やはり 自分では無理でした・・・・・
FumiKili

2017/10/13 08:10

MsTimer2タイマーと上にありましたね。すいません
MasahikoHirata

2017/10/13 09:53

MsTimer2を使用すると周期的にキーの状態を取得できます(最低分解能が1ms、つまり1000分の1秒)。これを利用してA,B,Cのキーの状態を判断してloop内で処理すれば細やかな制御が可能かと。まずは考えをまとめて”どのように動かしたい”から”状態遷移図”を書いてみる。例えば”AとB”を同時に押したら”とか。単純な割り込みの場合、片方の割り込み処理して、若干遅れたキーの処理。となるが、TsTimerでは同時にキーの状態を取得できる(Pin毎ではなくポートを読み込む)なので。また”C"ボタンの情報も。それで自分の意図する動きを想像。これがスタート。
FumiKili

2017/10/13 10:37

ありがとうございます。やってみます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問