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

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

ただいまの
回答率

90.51%

  • Arduino

    675questions

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

Arduino tone関数と7セグメント

解決済

回答 1

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 303

mameendo

score 1

アラーム時計を製作しています。
以下がプログラムです。
私がしたいのは、アラーム時刻になったときタッチボタンに触れているときボタン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ピンにつけられています。

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

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • keicha_hrs

    2018/12/22 13:33

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

    キャンセル

  • mameendo

    2018/12/22 17:22

    圧電スピーカー https://www.switch-science.com/catalog/472/
    タッチボタン https://www.switch-science.com/catalog/1600/
    温度センサ https://www.switch-science.com/catalog/2508/
    RTC https://www.switch-science.com/catalog/3036/
    7セグ http://akizukidenshi.com/catalog/g/gM-12643/
    lcd https://www.amazon.co.jp/gp/product/B073H1LG5X/ref=oh_aui_detailpage_o02_s00?ie=UTF8&amp;psc=1
    です。
    7セグメントはスケッチを参考にして、表示できることを確認しています。

    キャンセル

  • mameendo

    2018/12/22 17:23

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

    キャンセル

回答 1

checkベストアンサー

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は元の値のままです。

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

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/12/25 21:51

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

    キャンセル

  • 2018/12/28 15:41

    いろいろやり方はあると思いますが、当該のwhile文の中でも、ボタンなどを検査するようにするとかが単純な方法ですね。whileがネストしているので、たくさん書かないといけないかもしれませんが。

    あとは、時刻とボタンの状態などをまず全部取得する。それぞれの値などの組み合わせや状態遷移を表にまとめて、各状態で何をするかを決めたうえで、その通りにコーディングするとかですかね。

    キャンセル

  • 2018/12/28 21:19

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

    キャンセル

同じタグがついた質問を見る

  • Arduino

    675questions

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