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

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

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

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

Q&A

2回答

2044閲覧

Ardunioの割り込み処理による作業をリセットするプログラムを作りたいです。

saki1892

総合スコア0

Arduino

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

0グッド

0クリップ

投稿2021/09/07 15:51

Ardunioの割り込み処理が分かりません。

下記のプログラムを使い

割り込み処理ボタンを押し、割り込み処理によりvoid loop()の処理を停止し
再度ボタンを押すことでもう一度void loop()の作業を行うプログラムを作りたいです。

#include "pitches.h"

int melody[] = {NOTE_G5, NOTE_A5, NOTE_B5, NOTE_A5, NOTE_G5, NOTE_G5, NOTE_A5, NOTE_B5, NOTE_A5, NOTE_G5, NOTE_A5};
int tempo[] = {200, 200, 400, 100, 100, 70, 70, 70, 70, 70, 800};

int onkai[] = {NOTE_C4, NOTE_D4, NOTE_E4, NOTE_F4, NOTE_G4, NOTE_A4, NOTE_B4, NOTE_C5};

#define LEDC_CHANNEL_0 0
#define LEDC_TIMER_13_BIT 13
#define LEDC_BASE_FREQ 5000

#define BZZ 16
#define START_SW 4
#define R_LED 14
#define G_LED 5

#define DI_1() portENTER_CRITICAL_ISR(&mux_1);
#define EI_1() portEXIT_CRITICAL_ISR(&mux_1);

#define SERIAL_SPEED 115200

const byte SW1 = 32;

portMUX_TYPE mux_1 = portMUX_INITIALIZER_UNLOCKED;

int arrayM = sizeof melody / sizeof melody[0];
int arrayO = sizeof onkai / sizeof onkai[0];

void IRAM_ATTR handleInterrupt_1() {
DI_1();

EI_1();
}

void tone_n(int channel, int frq, int time_w) {
ledcWriteTone (channel, frq);
delay(time_w);
ledcWriteTone (channel, 0);
}

void setup() {
Serial.begin(115200);
pinMode(SW1, INPUT_PULLUP);
attachInterrupt (digitalPinToInterrupt(SW1), handleInterrupt_1, FALLING);
//
ledcSetup(LEDC_CHANNEL_0, LEDC_BASE_FREQ, LEDC_TIMER_13_BIT);
ledcAttachPin(BZZ, LEDC_CHANNEL_0);
delay(500);
// GPIO設定
pinMode(START_SW, INPUT_PULLUP);
pinMode(R_LED, OUTPUT);
pinMode(G_LED, OUTPUT);
digitalWrite(R_LED, 0);
digitalWrite(G_LED, 1);
tone_n(LEDC_CHANNEL_0, onkai[0], 0);
}

void loop() {
int in;
in = digitalRead(START_SW);
if (in == 0) {

for ( int i = 0; i < arrayO; i++) {// C4~C5 if (in == 0){ Serial.println(i); digitalWrite(G_LED, 0); delay(980); digitalWrite(R_LED, 1); tone_n (LEDC_CHANNEL_0, onkai[i], 20); digitalWrite(R_LED, 0); } } delay(1000); if (in == 0){ digitalWrite(G_LED, 1); for (int i = 0; i < arrayM; i++) { tone_n (LEDC_CHANNEL_0, melody[i], tempo[i]); delay(80); }

}
}
}

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

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

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

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

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

y_waiwai

2021/09/07 17:11

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

回答2

0

まず、質問中のソースコードはヘルプなどを参照して適切に記述してください。

Arduinoと言ってもいろいろ機種があります。さらには、Arduino IDEを開発に使用しているだけのものもあります。一般的なポート出力とかならともかく、割り込みなどはどうしてもCPUの色が表に出てきますから、どういうボードを使っているか等の重要な情報は質問にちゃんと含めてください。

で。割り込み処理ってなにか、まずはちゃんと調べてください。
割り込みとは、割り込みイベントが起こると、プログラムの実行を(機械語単位で)中断し、割り込みハンドラに飛んで、割り込みハンドラの実行を終わったら中断した次から実行を再開する動作です。
・わけも分からず割り込みハンドラにミューテックス並べてもなにも起こりません。DIとかEIとか、マクロに付けている名前も不適切に思います。
・割り込みハンドラが呼ばれたらそこでずっとメインコンテキストのプログラムの実行が中断されるわけではありません。
・割り込み中で別の割り込みを受けるつもりなら、そのようなプログラムにしなければいけませんが、普通はそのようなややこしいことはしません。
・delay()やtone()など実行時間のかかる処理を中断/再開する場合はこれとの兼ね合いをしっかり決めておく必要があります。

「ボタンを押したら処理を停止し、再度ボタンを押すことで再開する」程度であれば、まず割り込みを使わない処理を検討し、それで不都合があるなら割り込みを使用することを考えるべきかと思います。

投稿2021/09/07 23:22

thkana

総合スコア7703

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

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

0

提示のコードがまともに読めないので一般論とします

割り込み処理ボタンを押し、割り込み処理によりvoid loop()の処理を停止し

再度ボタンを押すことでもう一度void loop()の作業を行うプログラムを作りたいです。

loop()の処理を停止する、ってのがいまいち意味不明ですが、
なにかフラグを用意して、それでloop()の中身を実行したり実行しなかったりするようにしておきます
そして、割り込み処理でそのフラグを立てたり下ろしたりすればいいです

んで、割り込み処理ボタンを押し、ってところですが、チャタリング処理をちゃんとしとかないと、
ちゃんと動かないのでそのつもりで。

#だいたいボタンで割り込みさせるというのが悪手ですねー

投稿2021/09/07 17:15

編集2021/09/07 17:42
y_waiwai

総合スコア88042

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

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

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

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問