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

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

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

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

Q&A

解決済

4回答

1367閲覧

人感センサーがオフになったときにブザーが終わるようにしたい

退会済みユーザー

退会済みユーザー

総合スコア0

Arduino

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

0グッド

0クリップ

投稿2020/10/23 02:59

前提・実現したいこと

人感センサーが検知されたときに音がなるようにし、
人感センサーがオフになったときに音も瞬時にオフになるようにしたいのですが、
delayだと他の処理ができないことなのでmillisでやりたいと思うのですが
どう組めばいいのか分かりません。どなたかアドバイス、解決方法お願いします。

該当のソースコード

const int Sensor_LED = 25; const int Buzzer = 14; const int My_sensor = 13; int BEAT = 400 ; int counter = 0; void setup() { pinMode(Sensor_LED, OUTPUT); digitalWrite(Sensor_LED, LOW); ledcSetup(1,12000, 8); ledcAttachPin(Buzzer,1); } //パッシブブザー/////////////////////////////////////////////////////////////// void playmusic1(){ ledcWriteTone(1, 3136); // ソ delay(BEAT); ledcWriteTone(1, 2960); // ♯ファ delay(BEAT); ledcWriteTone(1, 2489); // ♯レ delay(BEAT); ledcWriteTone(1, 1760); // ラ delay(BEAT); ledcWriteTone(1, 1661); // ♯ソ delay(BEAT); ledcWriteTone(1, 2637); // ミ delay(BEAT); ledcWriteTone(1, 3322); // ♯ソ delay(BEAT); ledcWriteTone(1, 4186); // ド delay(BEAT); ledcWriteTone(1, 0); // 音を止める } void loop() { if(digitalRead(My_sensor) == HIGH){ if(counter == 0) playmusic1();or playmusic2 }else{ ledcWriteTone(1, 0); counter = 0; } }

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

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

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

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

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

guest

回答4

0

これとお題がとても似ているのは課題かなにかなんでしょうか?

そういえばESP32って普通マルチコアだったよね、ということで、音を鳴らすコアとセンサを検出するコアを分けてみました。millis()を使っていないという点では質問者の意図に沿っていないのですが。

Arduino

1const int Sensor_LED = 25; 2const int Buzzer = 14; 3const int My_sensor = 13; 4int BEAT = 400 ; 5volatile int counter = 0; 6 7void setup() 8{ 9 pinMode(Sensor_LED, OUTPUT); 10 digitalWrite(Sensor_LED, LOW); 11 12 ledcSetup(1, 12000, 8); 13 ledcAttachPin(Buzzer, 1); 14} 15 16//パッシブブザー/////////////////////////////////////////////////////////////// 17 18void playmusic1() { 19 20 ledcWriteTone(1, 3136); // ソ 21 delay(BEAT); 22 ledcWriteTone(1, 2960); // ♯ファ 23 delay(BEAT); 24 ledcWriteTone(1, 2489); // ♯レ 25 delay(BEAT); 26 ledcWriteTone(1, 1760); // ラ 27 delay(BEAT); 28 ledcWriteTone(1, 1661); // ♯ソ 29 delay(BEAT); 30 ledcWriteTone(1, 2637); // ミ 31 delay(BEAT); 32 ledcWriteTone(1, 3322); // ♯ソ 33 delay(BEAT); 34 ledcWriteTone(1, 4186); // ド 35 delay(BEAT); 36 ledcWriteTone(1, 0); // 音を止める 37} 38 39void task1(void* p) { 40 while (1) { 41 if (counter == 0) 42 playmusic1(); //or playmusic2 43 } 44} 45 46TaskHandle_t th1; 47 48void loop() { 49 static bool lastSense = false; 50 bool currentSense = digitalRead(My_sensor); 51 if (!currentSense) {//センサー不感 52 ledcWriteTone(1, 0); 53 if (th1) { //タスクがあるなら 54 vTaskDelete(th1); //タスク終了 55 } 56 th1 = NULL; 57 } else { 58 if (!lastSense) {//センサーがOFF->ONになったとき 59 //音を鳴らすタスク起動 60 xTaskCreatePinnedToCore( 61 task1, 62 "Task1", 63 1024,//スタックサイズ 妥当性の検討はしていない 64 NULL, 65 8,//タスク優先度 妥当性の検討はしていない 66 &th1, 67 0 //CPU番号。loop()はCPU1で実行される 68 ); 69 delay(1);//タスク起動を待つ。 妥当性の検討はしていない 70 } 71 } 72 lastSense = currentSense; 73}

とりあえず動かしてみただけですので、タスク管理まわりほんとに大丈夫?というところはあるかも。

LED追加。loop()差し替え。ここもスレッドを立てろの声もあるかも知れないけど「普通」に処理。で、millis()使ったヨ。

Arduino

1unsigned long t0; 2bool ledStat; 3void loop() { 4 static bool lastSense = false; 5 unsigned long currentTime=millis(); 6 bool currentSense = digitalRead(My_sensor); 7 if (!currentSense) {//センサー不感 8 ledcWriteTone(1, 0); 9 if (th1) { //タスクがあるなら 10 vTaskDelete(th1); //タスク終了 11 } 12 th1 = NULL; 13 ledStat=false; 14 } else { 15 if (!lastSense) {//センサーがOFF->ONになったとき 16 //音を鳴らすタスク起動 17 xTaskCreatePinnedToCore( 18 task1, 19 "Task1", 20 1024,//スタックサイズ 妥当性の検討はしていない 21 NULL, 22 8,//タスク優先度 妥当性の検討はしていない 23 &th1, 24 0 //CPU番号。loop()はCPU1で実行される 25 ); 26 delay(1);//タスク起動を待つ。 妥当性の検討はしていない 27 t0=currentTime; 28 ledStat=true; 29 } 30 if(currentTime-t0>BEAT){ 31 ledStat=!ledStat; 32 t0=currentTime; 33 } 34 } 35 lastSense = currentSense; 36 digitalWrite(Sensor_LED,ledStat); 37}

投稿2020/10/27 02:48

編集2020/10/27 03:42
thkana

総合スコア7703

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

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

0

ベストアンサー

LED BLINK 機能追加

#define LED_P 13 // led port #define LED_ON HIGH #define LED_OFF LOW #define LED_T 200 // 200ms LED BLINK TIME const unsigned int MusicData[] = { 3136,2960,2489,1760,1661,2637,3322,4186,0 }; void playMusic3(void){ unsigned char i=0; unsigned long mi,mi2,mi_now; if ( MusicData[ i ] == 0 ){ return; } mi = millis(); mi2 = mi; digitalWrite( LED_P , LED_ON ); ledcWriteTone( 1 , MusicData[i] ); i++; while( MusicData[ i ] != 0 && digitalRead( My_sensor ) == SENSOR_ON ){ mi_now = millis(); if ( ( mi_now - mi ) >= BEAT ){ ledcWriteTone( 1 , MusicData[i] ); i++; mi = mi_now; } // if if ( ( mi_now - mi2 ) >= LED_T ){ digitalWrite( LED_P , 1 - digitalRead( LED_P ) ); // blink mi2 = mi_now; } // if } // while digitalWrite( LED_P , LED_OFF ); ledcWriteTone( 1 , 0 ); }

set up に追加

pinMode( LED_P , OUTPUT ); digitalWrite( LED_P , LED_OFF );

投稿2020/10/27 01:28

koujikuu

総合スコア401

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

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

退会済みユーザー

退会済みユーザー

2020/10/27 02:23

うまく動作しました。ありがとうございます。 このコードをどういう仕組みでどこがどう動いてるのか改めて勉強します。 思うように動かないことが多くあったので非常に助かりました。 まだまだ勉強不足なところが多くあり、教えてくださったことはしっかり頭の中に入れます。
guest

0

演奏データを配列に格納して millis() を使ってみました

const unsigned int MusicData[] = { 3136,2960,2489,1760,1661,2637,3322,4186,0 }; void playMusic2(void){ unsigned char i=0; unsigned long mi; while(1){ ledcWriteTone( 1, MusicData[i] ); if ( MusicData[i] == 0 ){ return; } // data end i++; mi = millis(); while( ( millis() - mi ) < BEAT ){ if ( digitalRead( My_sensor ) == SENSOR_OFF ){ ledcWriteTone( 1, 0 ); return; } } // while } // while }

投稿2020/10/23 11:06

koujikuu

総合スコア401

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

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

退会済みユーザー

退会済みユーザー

2020/10/26 01:01

下記にて動作を実行しましたが、音階が正しく出ない?と雑音が入るのですが、 何かコード間違えているところありますでしょうか? const int Buzzer = 14; const int PIR_IN = 13; int BEAT = 400 ; int counter = 0; const unsigned int MusicData[] = { 3136,2960,2489,1760,1661,2637,3322,4186,0 }; void setup() { pinMode(PIR_IN, INPUT); ledcSetup(1,12000, 8); ledcAttachPin(Buzzer,1); } void playmusic1(void){ unsigned char i=0; unsigned long mi; while(1){ ledcWriteTone( 1, MusicData[i] ); if ( MusicData[i] == 0 ){ return; } // data end i++; mi = millis(); while( ( millis() - mi ) < BEAT ){ if ( digitalRead( PIR_IN ) == LOW ){ ledcWriteTone( 1,0 ); return; } } // while } // while } void loop() { if(digitalRead(PIR_IN) == HIGH){ if(counter == 0) playmusic1(); }else{ ledcWriteTone(1,0); counter = 0; } }
退会済みユーザー

退会済みユーザー

2020/10/26 02:23

ledcWriteTone() これの周波数を3桁ぐらいまで下げたら正常になったのですが、何か違いあるのでしょうか?
退会済みユーザー

退会済みユーザー

2020/10/26 08:31

Lチカの処理も同時に実行したいのですが、void playmusic1(void)とは同時処理はできないのでしょうか? playmusic1→Lチカという順番になってしまっています
koujikuu

2020/10/27 01:21

Arduino UNO では 問題ないので、ESP32 特有の現象だと思います
guest

0

こんな感じでどうですか?

void playMusic(void){ unsigned char i=0; while( digitalRead( My_sensor ) == SW_ON && i<8 ){ switch( i ){ case 0: ledcWriteTone(1, 3136); break; // ソ case 1: ledcWriteTone(1, 2960); break; // ♯ファ case 2: ledcWriteTone(1, 2489); break; // ♯レ case 3: ledcWriteTone(1, 1760); break; // ラ case 4: ledcWriteTone(1, 1661); break; // ♯ソ case 5: ledcWriteTone(1, 2637); break; // ミ case 6: ledcWriteTone(1, 3322); break; // ♯ソ case 7: ledcWriteTone(1, 4186); break; // ド } // switch i++; delay(BEAT); } // while ledcWriteTone(1, 0); // 音を止める }

投稿2020/10/23 07:53

koujikuu

総合スコア401

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

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

退会済みユーザー

退会済みユーザー

2020/10/26 00:59

下記にて動作を実行しましたが、音階が正しく出ない?と雑音が入るのですが、 何かコード間違えているところありますでしょうか? const int Buzzer = 14; const int PIR_IN = 13; int BEAT = 400 ; int counter = 0; const unsigned int MusicData[] = { 3136,2960,2489,1760,1661,2637,3322,4186,0 }; void setup() { pinMode(PIR_IN, INPUT); ledcSetup(1,12000, 8); ledcAttachPin(Buzzer,1); } void playmusic1(void){ unsigned char i=0; unsigned long mi; while(1){ ledcWriteTone( 1, MusicData[i] ); if ( MusicData[i] == 0 ){ return; } // data end i++; mi = millis(); while( ( millis() - mi ) < BEAT ){ if ( digitalRead( PIR_IN ) == LOW ){ ledcWriteTone( 1,0 ); return; } } // while } // while } void loop() { if(digitalRead(PIR_IN) == HIGH){ if(counter == 0) playmusic1(); }else{ ledcWriteTone(1,0); counter = 0; } }
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問