パソコン・スマホ備忘録

パソコン、スマホ、マイコン、家電などの備忘録と日記。使えるところを簡潔に解説!

Arduino

Arduinoで7セグメントLED4桁に様々パターンを表示させる

7セグメントLED4桁をATmega328単体で表示させることに成功したので、その基板を使って様々なパターンを表示できるようにスケッチを書いてみました。

前回作ったカウントプラグラムを変更して様々なパターンをランダムに表示させます。新たに付け加えた命令は「Serial.begin」「randomSeed」「random」「switch」です。

7セグメントLED4桁に様々パターンを表示させる

まずは完成したスケッチをご覧ください。

const int anode_pins[] = {12, 8, 5, 3, 2, 11, 6};    // アノードに接続するArduinoのピン
const int cathode_pins[] = {7, 9, 10, 13};  // カソードに接続するArduinoのピン
const int number_of_anode_pins = sizeof(anode_pins) / sizeof(anode_pins[0]);
const int number_of_cathode_pins = sizeof(cathode_pins) / sizeof(cathode_pins[0]);
 
const int digits[] = {
  0b00111111, // 0
  0b00000110, // 1
  0b01011011, // 2
  0b01001111, // 3
  0b01100110, // 4
  0b01101101, // 5
  0b01111101, // 6
  0b00100111, // 7
  0b01111111, // 8
  0b01101111, // 9
  0b00000000, // 10 全て消灯
  0b00000001, // 11 上
  0b01000000, // 12 中
  0b00001000, // 13 下
  0b00110000, // 14 左
};
 
// 1桁の数字(n)を表示する
void display_number (int n) {
  for (int i = 0; i < number_of_anode_pins; i++) {
    digitalWrite(anode_pins[i], digits[n] & (1 << i) ? HIGH : LOW);
  }
}
 
// アノードをすべてLOWに
void clear_segments() {
  for (int j = 0; j < number_of_anode_pins; j++) {
    digitalWrite(anode_pins[j], LOW);
  }
}
 
void display_numbers (int n) {
  for (int i = 0; i < number_of_cathode_pins; i++) {
    digitalWrite(cathode_pins[i], LOW);
    display_number(n % 10); // 最後の一桁を表示する
    delay(2);
    clear_segments();
    digitalWrite(cathode_pins[i], HIGH);
    n = n / 10; // 10で割る
  }
}
 

long randNumber;
// setup() は、最初に一度だけ実行される
// 乱数の配列をアナログ入力を元にする。
void setup(){
  Serial.begin(9600);
  randomSeed(analogRead(0));
  
  for (int i = 0; i < number_of_anode_pins; i++) {
    pinMode(anode_pins[i], OUTPUT);  // anode_pinsを出力モードに設定する
  }
  for (int i = 0; i < number_of_cathode_pins; i++) {
    pinMode(cathode_pins[i], OUTPUT);  // cathode_pinを出力モードに設定する
    digitalWrite(cathode_pins[i], HIGH);
  }
}
 
void loop () {
  int m = random(1,12);
  switch (m){
    case 1://8を左から右へ移動
    for (int t = 0; t < 10; t++) { 
      for (int i = 0; i < 4; i++) {
        digitalWrite(cathode_pins[3-i], LOW);
        display_number(8 % 10); 
        delay(500/t+1);
        digitalWrite(cathode_pins[3-i], HIGH);
      }
    }
    break;
    case 2: //8を右から左へ移動
    for (int t = 0; t < 10; t++) { 
      for (int i = 0; i < 4; i++) {
        digitalWrite(cathode_pins[i], LOW);
        display_number(8 % 10); 
        delay(500/t+1);
        digitalWrite(cathode_pins[i], HIGH);
      }
    }
    break;
   case 3: //「 88 」「8   8}の点滅
        digitalWrite(cathode_pins[0], LOW);
        digitalWrite(cathode_pins[1], LOW);
        digitalWrite(cathode_pins[2], LOW);
        digitalWrite(cathode_pins[3], LOW);
        display_number(8 % 15); 
   for (int t = 0; t < 5; t++) { 
        digitalWrite(cathode_pins[1], LOW);
        digitalWrite(cathode_pins[2], LOW);
        digitalWrite(cathode_pins[0], HIGH);
        digitalWrite(cathode_pins[3], HIGH);
        delay(1000);
        digitalWrite(cathode_pins[1], HIGH);
        digitalWrite(cathode_pins[2], HIGH);
        digitalWrite(cathode_pins[0], LOW);
        digitalWrite(cathode_pins[3], LOW);
        delay(1000);
   }
   break; 
   case 4: //0-9を左から右へ移動
   for (int t = 0; t < 10; t++) { 
      for (int i = 0; i < 4; i++) {
        digitalWrite(cathode_pins[3-i], LOW);
        display_number(t % 10); 
        delay(500/t+1);
        digitalWrite(cathode_pins[3-i], HIGH);
      }
    }
    break; 
    case 5: //0-9を右から左へ移動
    for (int t = 0; t < 10; t++) { 
      for (int i = 0; i < 4; i++) {
        digitalWrite(cathode_pins[i], LOW);
        display_number(t % 10); 
        delay(500/t+1);
        digitalWrite(cathode_pins[i], HIGH);
      }
    }
    break; 
   case 6: //8888の点滅
   for (int t = 0; t < 10; t++) { 
        digitalWrite(cathode_pins[0], LOW);
        digitalWrite(cathode_pins[1], LOW);
        digitalWrite(cathode_pins[2], LOW);
        digitalWrite(cathode_pins[3], LOW);
        display_number(8 % 15); 
        delay(100);
        digitalWrite(cathode_pins[0], HIGH);
        digitalWrite(cathode_pins[1], HIGH);
        digitalWrite(cathode_pins[2], HIGH);
        digitalWrite(cathode_pins[3], HIGH);
        delay(100);
   } 
   break; 
  case 7: //バーの移動
  for (int t = 0; t < 5; t++) { 
    digitalWrite(cathode_pins[3], LOW); //左から右
    display_number(14 % 15); 
    delay(50);
    display_number(1 % 15); 
    delay(50);
    digitalWrite(cathode_pins[3], HIGH);
    digitalWrite(cathode_pins[2], LOW);
    display_number(14 % 15); 
    delay(50);
    display_number(1 % 15); 
    delay(50);
    digitalWrite(cathode_pins[2], HIGH);
    digitalWrite(cathode_pins[1], LOW);
    display_number(14 % 15); 
    delay(50);
    display_number(1 % 15); 
    delay(50);
    digitalWrite(cathode_pins[1], HIGH);
    digitalWrite(cathode_pins[0], LOW);
    display_number(14 % 15); 
    delay(50);
    display_number(1 % 15); 
    delay(50);
    digitalWrite(cathode_pins[0], LOW); //上から下
    digitalWrite(cathode_pins[1], LOW);
    digitalWrite(cathode_pins[2], LOW);
    digitalWrite(cathode_pins[3], LOW);
    display_number(11 % 15); 
    delay(50);
    display_number(12 % 15);
    delay(50);
    display_number(13 % 15); 
    delay(50);
    digitalWrite(cathode_pins[0], HIGH);
    digitalWrite(cathode_pins[1], HIGH);
    digitalWrite(cathode_pins[2], HIGH);
    digitalWrite(cathode_pins[3], HIGH);
   }
   break; 
  case 8: //一桁カウント
  for (int i = 0; i < 1050; i++) {
    display_numbers(i);
  }
  break; 
  case 9: //一桁カウントダウン
  for (int i = 0; i < 1050; i++) {
    int l = 2050 - i;
    display_numbers(l);
  }  
  break; 
  case 19: //4桁カウント
  for (int i = 0; i < 50; i++){
    display_numbers(0000);
  }
  for (int i = 0; i < 50; i++){
    display_numbers(1111);
  }
  for (int i = 0; i < 50; i++){
    display_numbers(2222);
  }
  for (int i = 0; i < 50; i++){
    display_numbers(3333);
  }
  for (int i = 0; i < 50; i++){
    display_numbers(4444);
  }
  for (int i = 0; i < 50; i++){
    display_numbers(5555);
  }
  for (int i = 0; i < 50; i++){
    display_numbers(6666);
  }
  for (int i = 0; i < 50; i++){
    display_numbers(7777);
  }
  for (int i = 0; i < 50; i++){
    display_numbers(8888);
  }
  for (int i = 0; i < 50; i++){
    display_numbers(9999);
  }
  break; 
  case 11: //4桁カウントダウン
  for (int i = 0; i < 50; i++){
    display_numbers(9999);
  }
  for (int i = 0; i < 50; i++){
    display_numbers(8888);
  }
  for (int i = 0; i < 50; i++){
    display_numbers(7777);
  }
  for (int i = 0; i < 50; i++){
    display_numbers(6666);
  }
  for (int i = 0; i < 50; i++){
    display_numbers(5555);
  }
  for (int i = 0; i < 50; i++){
    display_numbers(4444);
  }
  for (int i = 0; i < 50; i++){
    display_numbers(3333);
  }
  for (int i = 0; i < 50; i++){
    display_numbers(2222);
  }
  for (int i = 0; i < 50; i++){
    display_numbers(1111);
  }
  for (int i = 0; i < 50; i++){
    display_numbers(0000);
  }
  break; 
  }
}

まず乱数を発生させる必要がありますが、その元になる値を設定するのがrandomSeedです。この値が同じだと擬似的に発生した乱数が同じになってしまいます。そこでシリアル通信を「Serial.begin(9600);」でシリアル通信の速度を9600bpsで行ない、arduinoのpin0からの値を読み込み乱数の元になる数値を適当に決めるようにします。pin0に何も接続されていないと、値が不安定になり外来ノイズから偶発的な値を読み取ることができます。よってarduinoのpin1にはプルアップやプルダウン抵抗など何も接続しません。

  Serial.begin(9600);
  randomSeed(analogRead(0));

これで擬似的な乱数の配列が出来上がります。

  int m = random(1,12);

この命令で最小値1から最大値12までのランダムな整数がmに置数されます。

発生した乱数mの値を元にswitchで分岐させます。「case 数値」でそれぞれのパターンに分岐します。

 switch (m){
    case 1:
      //パターン1
    break;
    case 2:
      //パターン2
    break;
    case 3:
      //パターン3
    break;
      ・
      ・
      ・
  }

例えば乱数mの値が1の場合case 1のパターンが実行され、「break;」によってループから抜け出ます。この乱数発生、それを元にパターンを実行を繰り返します。

-Arduino