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

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

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

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

mbed

mbed(エンベッド)は、Webサイト上でC++を使って開発を行う、ワンボードマイコンのプロトタイピングツールです。PCに開発環境をインストールする必要がなく、Webにアクセスできればどこにいても開発を行うことができます。

Q&A

2回答

693閲覧

ストップウォッチをジャストで止めたときに音が鳴らすようにしたい

退会済みユーザー

退会済みユーザー

総合スコア0

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

mbed

mbed(エンベッド)は、Webサイト上でC++を使って開発を行う、ワンボードマイコンのプロトタイピングツールです。PCに開発環境をインストールする必要がなく、Webにアクセスできればどこにいても開発を行うことができます。

0グッド

0クリップ

投稿2020/01/29 04:38

編集2020/01/30 03:34

あれから試行錯誤したり書籍を購入したりして何とかストップウォッチを作成することができました。
次は第二段階として秒以下を00で止めたときに圧電スピーカーで音を鳴らすようにしたいと考えています。
以下がストップウォッチのプログラムになります。

C++

1#include "mbed.h" 2 3DigitalOut a(p10); 4DigitalOut b(p11); 5DigitalOut c(p12); 6DigitalOut d(p13); 7DigitalOut e(p14); 8DigitalOut f(p15); 9DigitalOut g(p16); 10DigitalOut dp(p17); 11 12DigitalOut dig1(p21); 13DigitalOut dig2(p22); 14DigitalOut dig3(p23); 15DigitalOut dig4(p24); 16 17PwmOut mysp1(p25); 18DigitalIn mysw(p9); 19 20Ticker timer_tick; //測定用タイマ 21Ticker led; //ダイナミック点灯用タイマ 22int sw_time=0; 23unsigned char seg[4]; //7セグ表示用 24 25const char set_num[10] = {0xfc,0x60,0xda,0xf2,0x66,0xb6,0xbe,0xe0,0xfe,0xf6}; 26 27//7セグ,パターンセット 28void set_7seg(char bit,char num){ 29 switch(num){ 30 case 1: dig1=0;dig2=1;dig3=1;dig4=1; 31 break; 32 case 2: dig1=1;dig2=0;dig3=1;dig4=1; 33 break; 34 case 3: dig1=1;dig2=1;dig3=0;dig4=1; 35 break; 36 case 4: dig1=1;dig2=1;dig3=1;dig4=0; 37 break; 38 default:dig1=1;dig2=1;dig3=1;dig4=1; 39 break; 40 } 41 a = (bit&0x80)>>7; 42 b = (bit&0x40)>>6; 43 c = (bit&0x20)>>5; 44 d = (bit&0x10)>>4; 45 e = (bit&0x08)>>3; 46 f = (bit&0x04)>>2; 47 g = (bit&0x02)>>1; 48 dp = (bit&0x01); 49} 50 51void stop_watch(void){ 52 int time_now; 53 char digit[4]; 54 sw_time++; 55 if(sw_time>9999) sw_time=0; 56 time_now = sw_time; 57 digit[0] = time_now/1000; time_now%=1000; 58 digit[1] = time_now/100; time_now%=100; 59 digit[2] = time_now/10; time_now%=10; 60 digit[3] = time_now; 61 seg[0] = set_num[digit[0]]; 62 seg[1] = set_num[digit[1]]|0x01; 63 seg[2] = set_num[digit[2]]; 64 seg[3] = set_num[digit[3]]; 65} 66 67void blink_seg(void){ 68 static int n; 69 n++; 70 if(n>5) n=0; 71 set_7seg(seg[n-1],n); 72} 73 74int main(){ 75 76 timer_tick.attach_us(&stop_watch, 10000); //割り込みタイマ10ms 77 led.attach_us(&blink_seg, 1000); //割り込みタイマ1ms 78 sw_time=0; 79 //loop 80 81 82 while(1) { 83 84 85 if (mysw==1){ 86 timer_tick.detach(); 87 88 if (dig3==dig4==(?)){ 89 mysp1.period(1.0/261.626); // ド 90 mysp1.write(0.5); 91 wait(1); 92 mysp1.period(1.0/293.665); // レ 93 mysp1.write(0.5); 94 wait(1); 95 mysp1.period(1.0/329.628); // ミ 96 mysp1.write(0.5); 97 wait(1); 98 mysp1.period(1.0/349.228); // ファ 99 mysp1.write(0.5); 100 wait(1); 101 mysp1.period(1.0/391.995); // ソ 102 mysp1.write(0.5); 103 wait(1); 104 mysp1.period(1.0/440.00); // ラ 105 mysp1.write(0.5); 106 wait(1); 107 mysp1.period(1.0/493.883); // シ 108 mysp1.write(0.5); 109 wait(1); 110 mysp1.period(1.0/261.626/2); // ド 111 mysp1.write(0.5); 112 wait(3); 113 } 114 115 } 116 } 117} 118

最後のif分(音を定義しているもの)を省くとストップウォッチとして機能していたし、別のプログラムで圧電スピーカーが鳴るのも確認しました。このプログラムでは秒以下の数字のところを左からdig3、dig4としています。dig3とdig4が0と表示されているときに音を鳴らせばいいとわかっているのですが

C++

1if (dig3==dig4==0)

0が消灯、1が点灯で、またダイナミック点灯を用いているのでこのように入力するとどの数字でも音が鳴ってしまうというのは理解できますが、他の入力方法(?)が思いつきません。
どなたかアドバイスを頂けると嬉しいです。

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

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

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

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

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

dodox86

2020/01/29 04:47

? ご質問は、if (dig3==dig4==0) と言うコードを書いたけど思った通り動かない。多分間違っている気がするけど、他のコーディングの仕方が思い付かない、と言うことでしょうか?
退会済みユーザー

退会済みユーザー

2020/01/29 04:54

そういうニュアンスです。間違っていることはわかっていますが他のものが思いつきません、、。
dodox86

2020/01/29 04:58

y_waiwaiさんの回答ですね。if (dig3 == dig4 == 0) とすると、(dig3==dig4)を最初に評価で真。次に(真==0)で偽、となってダメです。
退会済みユーザー

退会済みユーザー

2020/01/29 05:03

私もy_waiwaiさんの回答をみて「あっ…」となりました。丁寧な説明ありがとうございます。
guest

回答2

0

両方とも0という条件では、

if (dig3==0 && dig4==0){なんやかや}

と書きますが、、これらの変数定義がないですが、ここらへんどうなってるでしょう

投稿2020/01/29 04:45

y_waiwai

総合スコア87747

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

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

退会済みユーザー

退会済みユーザー

2020/01/29 05:01

あっ、、、お恥ずかしいです。超初心者なもので、、。 mbedのTickerを使って時間計測してそれをそのまま7セグLEDに出力するようにしているので変数を定義していませんでした。。確かに必要ですね。
y_waiwai

2020/01/29 05:38

まあ、これでコンパイルが通ってるなら、どこかでうまいことやってるんだとは思いますが。。 ちなみに、 dig3==dig4==0 という式では、 (dig3==dig4)==0 と解釈されてしまいます
退会済みユーザー

退会済みユーザー

2020/01/29 07:12

dodoxさんの返信で理解しました。なるほどとなりました。丁寧な回答ありがたいです。
guest

0

両方とも0という条件なら
if (dig3==0 && dig4==0){なんやかや} 

とすべき、という y_waiwai さんのお答えですが、その条件は的外れです。
set_7seg()関数の switch() 文をよくご覧なさい。dig3 = 0; と dig4 = 0; が同時に実行されることはありません。

そもそもdig1〜dig4は、4桁ある7SEG-LEDの、どの桁を点灯するかを指定する、各1ビットの信号です。この意味が理解できていないから、そんな条件を考えてしまうんですね。ハードウェアの構造が理解できていないと、こういうプログラムはうまく書けないものです。

ちなみに、そのコードで表示できているなら、0 を出力すると点灯する負論理のポートだと分かります。前の質問に私が書いたコードは、dig1〜dig4が正論理と仮定しましたので、後で直しておきます。ダイナミック点灯する場合、ある時点ではひと桁しか点灯させないので、一つだけ0を出力する、即ち2つが同時に0になることはないのです。

正しい条件は、表示する「数字が2桁とも0」の場合です。
その2つの数字が、ご自分で動かしているコードの、どこにあるか?そこ分かってますか?考えてみてください。

P.S.
led.attach_us(&blink_seg, 100); //割り込みタイマ0.1ms

ダイナミック点灯の、表示桁の切り替え時間が 0.1 ms とは短かすぎ。5 msec 周期まで伸ばして構いません。こういう時間を不必要に短くすると、システム全体が重くなるものです。余裕が無くなるのです。

それと、set_7seg()関数の中の処理の流れは正しくありません。前に私が回答した通り、次の手順にすべきです。

  1. 全桁を消灯する。つまり dig1〜dig4の全てに1を出力する
  2. 表示する桁の数字(フォント)を a 〜 g, dp に出力する
  3. 表示する桁だけ点灯。ここで dig1〜dig4 のどれかに0を出力する

投稿2020/01/29 12:20

編集2020/01/29 12:46
rubato6809

総合スコア1380

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

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

退会済みユーザー

退会済みユーザー

2020/01/29 12:23

試行錯誤したら鳴らすことが出来ました、digではなくsw_timeの値に焦点をあてたらできました。回答ありがとうございます。
rubato6809

2020/01/29 12:33

sw_timeですか・・・if (sw_time % 100 == 0) かな?ま、それも手だけどねえ。。。 試行錯誤でも動かないよりマシだけど、何がどうなれば目的を達成できるか、という見通しをあらかじめ立てることが大事です。それが設計というもの。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

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

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

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問