Arduino Unoで次のプログラムを教えてください。 1秒間隔で、下記のように7セグメントLEDの表示が変化するプログラムを作成。

ベストアンサー

1

1人がナイス!しています

訂正ありがとうございます。 プログラムが極端に長いことは、承知です。 わかりずらいですが、「続き」とかかれたプログラムを 別に掲載しました。(1000字に収まらなかったため) そちらは合っていますか?

ThanksImg質問者からのお礼コメント

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

お礼日時:7/2 11:25

その他の回答(2件)

0

大幅に簡素化してみました。 const unsigned int LED7segx4[10] = { //<PORT B><PORT D> //7654321076543210 //--3AF21B0GC.DE-- 0b0001100100101100,// 0 0b0000000100100000,// 1 0b0001000101001100,// 2 0b0001000101101000,// 3 0b0000100101100000,// 4 0b0001100001101000,// 5 0b0001100001101100,// 6 0b0001100100100000,// 7 0b0001100101101100,// 8 0b0001100101101000 // 9 }; const unsigned int digitSelect[4] = { 0b0000000010000000,// 0 0b0000001000000000,// 1 0b0000010000000000,// 2 0b0010000000000000 // 3 }; int numbers_to_display = 0; // LEDに表示する数字を保持する変数 void setup() { PORTB &= 0b11000000; PORTD &= 0b00000011; DDRB = 0b00111111; DDRD = 0b11111100; } void loop() { int dig; int m, n; numbers_to_display = millis() / 1000; // テスト用 n = numbers_to_display; // number_to_displayの値を保持し変数にコピー for (dig = 0; dig < 4; dig++) { m = LED7segx4[n % 10] | digitSelect[dig]; PORTD = (PORTD & 0b00000011) | (m & 0b11111100); m >>= 8; n /= 10; PORTB = (PORTB & 0b11000000) | (m & 0b00111111); delayMicroseconds(1000); PORTB &= 0b11000000; PORTD &= 0b00000011; } }

訂正ありがとうございます。 プログラムが極端に長いことは、承知です。 わかりずらいですが、「続き」とかかれたプログラムを 別に掲載しました。(1000字に収まらなかったため) そちらは合っていますか?

0

7セグを表示させるだけならこのスケッチを元に組んでも良いのですけど、 これを元に何かを作るのはオススメしません。 つまり、一般的な表示器としてのスケッチとしては駄目なプログラムです。 ※理由 内容からいくと、コモンカソードの4桁のダイナミック点灯で、アノード、カソード共に直接接続(トランジスタ未使用)のものでしょう。 となると、回路的に7セグの明るさが暗くなりやすい条件です。 それに対して組み方に無駄があります。→より暗いスケッチになりやすいです。 7セグ表示にかなりのマイコンパワー(時間的な割合)を必要とするので、本来の表示元の部分の作業が取りにくい。 他の方のスケッチでは10msに1回表示しています。通常、その周波数で表示させればチラつきは起きません。 ただし、この提示された元スケッチからいくと、led の点灯時間は10ms間に100*4usしか点灯していません。 つまり、4%の時間しか点灯していません。 で、より明るくする為に、display_numbers();を呼び出す頻度を上げれば、他の作業がやり難くなるという事です。 ※根本的には、『点灯時間を専用として確保』している点が良くないです。 loop関数にdisplay_numbers();だけをするプログラムでもLEDの点灯時間は63%?程度にしかなりません。 例えば↓のようなスケッチなら、disp関数の実行時間は40us以下でしょうから、98%以上(2000/2040)はledの点灯に当てられています。 disp関数自体は桁の切り替えだけで、次のdisp関数の呼び出しまでが表示時間です。 (loop関数内は楽に書いたので見本にしない方が良い) 実際に動かしてみれば、明るさにだいぶ差があると思う。 const byte seg_pin[] = {12, 8, 5, 3, 2, 11, 6, 4}; //A-G const byte dig_pin[] = {7, 9, 10, 13}; const byte form[] = {0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};//数字形 byte NUM[4];//表示する数値 void seg_set(byte num) {//セグメントを表示形にする for(byte i=0; i<8; i++) digitalWrite(seg_pin[i],bitRead(form[num],i)); } void setNUM(word dat) { NUM[0]=dat%10; NUM[1]=dat/10%10; NUM[2]=dat/100%10; NUM[3]=dat/1000%10; } void disp() { static byte dig=3; pinMode(dig_pin[dig],INPUT);//桁をオフにして全消灯 dig=(dig+1)&3;//次の桁に seg_set(NUM[dig]);//セグメントを数字形に pinMode(dig_pin[dig],OUTPUT);//桁をオンにして表示 } void setup() { for(byte i=0; i<8; i++)pinMode(seg_pin[i], OUTPUT); } void loop() { setNUM(millis()/1000%102); delay(2); disp(); }

訂正ありがとうございます。 プログラムが極端に長いことは、承知です。 わかりずらいですが、「続き」とかかれたプログラムを 別に掲載しました。(1000字に収まらなかったため) そちらは合っていますか?