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

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

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

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

Q&A

解決済

1回答

1803閲覧

Arduino tone関数と7セグメント

mameendo

総合スコア13

Arduino

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

0グッド

0クリップ

投稿2018/12/21 16:38

編集2018/12/22 08:17

アラーム時計を製作しています。
以下がプログラムです。
私がしたいのは、アラーム時刻になったときタッチボタンに触れているときボタンP1を押したときに、7セグメントにランダムで数字を0~9表示させ、0になったときのみ、アラーム音を停止させることです。しかし、タッチボタンがHIGHでP1がLOWのとき、7セグメントには何も表示されず、音が出るだけです。
しかも、この時他のボタンを押しても無反応でlcd自体も応答していません。おそらくSPI通信でミスがあると思うのですが、アドバイスいただけますか?!
「問題となっている部分を抜粋」

while ( now.hour() == alarmHours && now.minute() == alarmMinutes ){ while((digitalRead(TOUCH_BUTTON_PIN) == LOW)) { tone(buzzer,880); delay (300); } while((digitalRead(TOUCH_BUTTON_PIN) == HIGH)) { if(digitalRead(P1)==LOW){ noTone (buzzer); i=random(0,10); SPI.begin(); SPI.transfer(moji[i]); SPI.end(); } } if(i==0){ noTone (buzzer); DateTime now = RTC.now(); } } コード

プログラム文

//************libraries**************// #include <Wire.h> #include <RTClib.h> #include <LiquidCrystal_I2C.h> #include <SPI.h>__ //************************************// LiquidCrystal_I2C lcd(0x27,2, 1, 0, 4, 5, 6, 7, 3, POSITIVE); // Display I2C 20 x 4 RTC_DS1307 RTC; //************Button*****************// int P1=6; // Button SET MENU' int P2=7; // Button + int P3=8; // Button - int P4=9; // SWITCH Alarm //**************Alarm***************// #define buzzer 12 #define SS 10 // Chip Select #define MOSI 11 #define SCK 13 int i; int vol; char moji[10]{ B00111111, // 0 B00000110, // 1 B01011011, // 2 B01001111, // 3 B01100110, // 4 B01101101, // 5 B01111101, // 6 B00000111, // 7 B01111111, // 8 B01100111, // 9 }; float a_in; // アナログ入力値(0〜203) float temp = 0; // 1回目摂氏値( ℃ ) float chap = 0; int TOUCH_BUTTON_PIN = 2; //************Variables**************// int hourupg; int minupg; int yearupg; int monthupg; int dayupg; int menu =0; int setAll =0; uint8_t alarmHours = 0, alarmMinutes = 0; // Holds the current alarm time void setup() { lcd.begin(20,4); lcd.backlight(); lcd.clear(); pinMode(P1,INPUT_PULLUP); pinMode(P2,INPUT_PULLUP); pinMode(P3,INPUT_PULLUP); pinMode(P4,INPUT_PULLUP); pinMode(buzzer, OUTPUT); // Set buzzer as an output pinMode(TOUCH_BUTTON_PIN, INPUT); pinMode(SS,OUTPUT); digitalWrite(SS,1); printAllOff(); Serial.begin(9600); Wire.begin();; RTC.begin(); if (! RTC.isrunning()) { Serial.println("RTC is NOT running!"); // Set the date and time at compile time RTC.adjust(DateTime(__DATE__, __TIME__)); } // RTC.adjust(DateTime(__DATE__, __TIME__)); //removing "//" to adjust the time // The default display shows the date and time int menu=0; } void loop() { if((digitalRead(P2)== LOW)&&(digitalRead(P3)== LOW)) { DisplaySetHourAll(); DisplaySetMinuteAll(); lcd.clear(); lcd.setCursor(5,0); lcd.print("ALARM"); lcd.setCursor(5,1); lcd.print(alarmHours, DEC); lcd.print(":"); lcd.print(alarmMinutes, DEC); delay(1000); lcd.clear(); } DisplayDateTime(); // void DisplayDateTime Alarm(); // Alarm control tempreture(); } void DisplayDateTime () { // We show the current date and time DateTime now = RTC.now(); lcd.setCursor(0, 2); lcd.print("Hour : "); if (now.hour()<=9) { lcd.print("0"); } lcd.print(now.hour(), DEC); hourupg=now.hour(); lcd.print(":"); if (now.minute()<=9) { lcd.print("0"); } lcd.print(now.minute(), DEC); minupg=now.minute(); lcd.print(":"); if (now.second()<=9) { lcd.print("0"); } lcd.print(now.second(), DEC); lcd.setCursor(0, 1); lcd.print("Date : "); if (now.day()<=9) { lcd.print("0"); } lcd.print(now.day(), DEC); dayupg=now.day(); lcd.print("/"); if (now.month()<=9) { lcd.print("0"); } lcd.print(now.month(), DEC); monthupg=now.month(); lcd.print("/"); lcd.print(now.year(), DEC); yearupg=now.year(); char DOW[][10]={"Sunday ","Monday ","Tuesday ","Wednesday","Thursday ","Friday ","Saturday "}; lcd.setCursor(0, 0); lcd.print("Day : "); lcd.print(DOW[now.dayOfTheWeek()]); //lcd.print(DOW[now.dayOfWeek()]); } void tempreture() { a_in = analogRead(0); temp = ((5 * a_in) / 1024) * 100; lcd.setCursor(13, 4); lcd.print(temp); lcd.setCursor(18,4); lcd.write(0xDF); lcd.setCursor(19,4); lcd.print("c"); } void DisplaySetHourAll()// Setting the alarm minutes { while(digitalRead(P1)==HIGH){ lcd.clear(); if(digitalRead(P2)==LOW) { if(alarmHours==23) { alarmHours=0; } else { alarmHours=alarmHours+1; } } if(digitalRead(P3)==LOW) { if(alarmHours==0) { alarmHours=23; } else { alarmHours=alarmHours-1; } } lcd.setCursor(0,0); lcd.print("Set HOUR Alarm:"); lcd.setCursor(0,1); lcd.print(alarmHours,DEC); delay(200); } delay(200); } void DisplaySetMinuteAll()// Setting the alarm minutes { while(digitalRead(P1)==HIGH){ lcd.clear(); if(digitalRead(P2)==LOW) { if (alarmMinutes==59) { alarmMinutes=0; } else { alarmMinutes=alarmMinutes+1; } } if(digitalRead(P3)==LOW) { if (alarmMinutes==0) { alarmMinutes=59; } else { alarmMinutes=alarmMinutes-1; } } lcd.setCursor(0,0); lcd.print("Set MIN. Alarm:"); lcd.setCursor(0,1); lcd.print(alarmMinutes,DEC); delay(200); } delay(200); } void printAllOn(){ lcd.setCursor(0,3); lcd.print("Alarm: "); if (alarmHours <= 9) { lcd.print("0"); } lcd.print(alarmHours, DEC); lcd.print(":"); if (alarmMinutes <= 9) { lcd.print("0"); } lcd.print(alarmMinutes, DEC); } void printAllOff() { lcd.setCursor(0, 3); lcd.print("Alarm: Off "); } void Alarm(){ if(digitalRead(P4)== LOW) { setAll=setAll+1; } if (setAll==0) { printAllOff(); noTone (buzzer); } if (setAll==1) { printAllOn(); DateTime now = RTC.now(); while ( now.hour() == alarmHours && now.minute() == alarmMinutes ){ while((digitalRead(TOUCH_BUTTON_PIN) == LOW)) { tone(buzzer,880); delay (300); } while((digitalRead(TOUCH_BUTTON_PIN) == HIGH)) { if(digitalRead(P1)==LOW){ noTone (buzzer); i=random(0,10); SPI.begin(); SPI.transfer(moji[i]); SPI.end(); } } if(i==0){ noTone (buzzer); DateTime now = RTC.now(); } } } if (setAll==2) { setAll=0; } delay(200); } コード

イメージ説明
画像にはタッチボタンが配線されてませんが、2ピンにつけられています。

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

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

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

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

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

y_waiwai

2018/12/21 21:58

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

2018/12/21 22:54

また、実体配線図ではなく、回路図の提示はできませんか。 なんのデバイスを使ってるかわかりませんし、7セグLEDも、この配線でまともに表示できるとは思われません
ozwk

2018/12/21 23:09

7セグに適当な数字出すだけのプログラム書いて、使い方あってるか確認してください
keicha_hrs

2018/12/22 04:33

タグが誤っていますので、こちらも修正してください。 ✕ Android ○ Arduino
mameendo

2018/12/22 08:22

mameendo

2018/12/22 08:23

すみません、回路図は書いていません
guest

回答1

0

ベストアンサー

直接の回答にはなってなくて申し訳ありませんが、気になる点をいくつか。

  • TOUCH_BUTTON_PINは、HIGHになっていますか? 症状から考えるとwhile((digitalRead(TOUCH_BUTTON_PIN) == LOW)) のループから脱出できていないような気がします。

  • if(digitalRead(P1)==LOW) が成立した後、noTone()していますが、意図したコードですか?

  • 以下のコードだと、iが0のときにだけ、このif文の直後のブロックの中でだけ有効なDateTime型のnowを新たに定義して、RTC.now()の結果を代入しています。while文のnowは元の値のままです。

arduino

1DateTime now = RTC.now(); // 最初のnow 2while ( now.hour() == alarmHours && now.minute() == alarmMinutes ){ // 最初のnowを利用 3 省略 4 if(i==0){ 5 noTone (buzzer); 6 DateTime now = RTC.now(); // このnowは、このif文の中でだけ有効な、最初のnowとは違うnow 7 } 8}
  • また、上記を修正したとしても、1分間はwhile ( now.hour() == alarmHours && now.minute() == alarmMinutes )を実行し続けるのではないかと思います。このwhile文の中ではブザーの操作と7セグの操作しかしていないので、P2等のボタンの検査やLCDの更新は行われないと思います。

投稿2018/12/23 00:33

編集2018/12/23 03:08
mkgt00

総合スコア165

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

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

mameendo

2018/12/25 12:51

なるほど、では while ( now.hour() == alarmHours && now.minute() == alarmMinutes )の文を 変更しなければ、ボタンなどは使えないということでしょうか? 具体的にはどのように変更するべきでしょうか?
mkgt00

2018/12/28 06:41

いろいろやり方はあると思いますが、当該のwhile文の中でも、ボタンなどを検査するようにするとかが単純な方法ですね。whileがネストしているので、たくさん書かないといけないかもしれませんが。 あとは、時刻とボタンの状態などをまず全部取得する。それぞれの値などの組み合わせや状態遷移を表にまとめて、各状態で何をするかを決めたうえで、その通りにコーディングするとかですかね。
mameendo

2018/12/28 12:19

分かりました。ありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問