秋月電子通商の7セグ4桁アノードコモン青色をArduinoで動かす

[ダイナミック接続４桁高輝度赤色７セグメントＬＥＤ表示器　アノードコモンアノード共通接続 [OSL40562-IR]](http://akizukidenshi.com/catalog/g/gI-03672/) を動かすコードです。

自分の要件では、-999から9999までを表示するコードが欲しかったのですが、負の表示対応のものは残念ながらネットで見つからなかったので自分で書きました。抵抗は特に使っていません。

![IMG_8560.JPG](https://qiita-image-store.s3.amazonaws.com/0/2382/20233ca5-08ca-72f6-ad8a-5b052c6a775f.jpeg)

![IMG_8559.JPG](https://qiita-image-store.s3.amazonaws.com/0/2382/30105e70-1e13-9425-9668-192fd0c97ff3.jpeg)

こんな感じで、9999までの正の整数値と-999までの負の整数を出すことができます。また、存在しない桁は0埋めしないようになっています。

データシートは、
http://akizukidenshi.com/download/OSL40562-IR.pdf
を参照ください。

よくある左下から反時計回りに1~12ピンになっているやつで、1~7のセグメントの青色LEDとドットがあります。しかしながら今回は小数点以下は表示不要だったので、メソッドとしては実装してありますが利用していません。

アノードコモンで実装してありますので、アソードコモンを利用する方はHIGHTとLOWを置換すると動くのではないかと思います。

コメントにも書いてありますが、Aのセグメントは11ピンなのでArduinoの1につなぐ、というような形です。Bのセグメントは7ピンなのでArduinoの2につなぎます。配線的にArduinoのデジタルソケットの1からつないで行けるよう工夫してみました。

ただし、シリアル通信と同居させようとする場合は、Arduino のデジタル1ソケットはTXとして使われてしまいますので、 `int a = 13; // 11` デジタル13ソケットに変更するなどしてください。

```
/*
 * ダイナミック接続４桁高輝度青色７セグメントＬＥＤ表示器　アノードコモン　アノード共通接続 [OSL40562-IB]
 * http://akizukidenshi.com/catalog/g/gI-04450/
 * MIT License
 */

int a = 1; // 11
int b = 2; //  7
int c = 3; //  4
int d = 4; //  2
int e = 5; //  1
int f = 6; // 10
int g = 7; //  5
int p = 8; //  3 (DP)

int d4 = 9;  // 6
int d3 = 10; // 8
int d2 = 11; // 9
int d1 = 12; // 12

long del = 5;

void setup()
{
  pinMode(d1, OUTPUT);
  pinMode(d2, OUTPUT);
  pinMode(d3, OUTPUT);
  pinMode(d4, OUTPUT);
  pinMode(a, OUTPUT);
  pinMode(b, OUTPUT);
  pinMode(c, OUTPUT);
  pinMode(d, OUTPUT);
  pinMode(e, OUTPUT);
  pinMode(f, OUTPUT);
  pinMode(g, OUTPUT);
  pinMode(p, OUTPUT);

}

void loop()
{
  long i;
  for (i = 0; i < 1000000; i++)
  {
    showNum(i / 1000);
  }
}

/*
 * 9999 ～ - 999 まで表示
 */
void showNum(int n)
{
  boolean isNega = n < 0;
  
  clearLEDs();
  pickDigit(1);
  if  (n >= 1000) { // 1000以上なら4桁目表示
    pickNumber(n % 10000 / 1000);
  } else if (isNega) { // 負なら反転
    n = -1 * n;
  }
  if (isNega && abs(n) >= 100) dispHyphen();
  delayMicroseconds(del);

  clearLEDs();
  pickDigit(2);
  if (abs(n) >= 100) { // 絶対値100以上なら3桁目表示
    pickNumber(n % 1000 / 100);
  }
  if (isNega && abs(n) < 100 && abs(n) >= 10) dispHyphen();
  delayMicroseconds(del);

  clearLEDs();
  pickDigit(3);
  if (abs(n) >= 10) { // 絶対値10以上なら3桁目表示
    pickNumber(n % 100 / 10);
  }
  if (isNega && abs(n) < 10 && abs(n) >= 1) dispHyphen();
  delayMicroseconds(del);

  clearLEDs();
  pickDigit(4);
  pickNumber(n % 10);
  delayMicroseconds(del);
  n++;
}

void pickDigit(int x)
{
  digitalWrite(d1, LOW);
  digitalWrite(d2, LOW);
  digitalWrite(d3, LOW);
  digitalWrite(d4, LOW);

  switch (x)
  {
    case 1:
      digitalWrite(d1, HIGH);
      break;
    case 2:
      digitalWrite(d2, HIGH);
      break;
    case 3:
      digitalWrite(d3, HIGH);
      break;
    default:
      digitalWrite(d4, HIGH);
      break;
  }
}

void pickNumber(int x)
{
  switch (x)
  {
    default:
      zero();
      break;
    case 1:
      one();
      break;
    case 2:
      two();
      break;
    case 3:
      three();
      break;
    case 4:
      four();
      break;
    case 5:
      five();
      break;
    case 6:
      six();
      break;
    case 7:
      seven();
      break;
    case 8:
      eight();
      break;
    case 9:
      nine();
      break;
  }
}

void dispDec()
{
  digitalWrite(p, LOW);
}

void dispHyphen()
{
  digitalWrite(g, LOW);
}

void clearLEDs()
{
  digitalWrite(a, HIGH);
  digitalWrite(b, HIGH);
  digitalWrite(c, HIGH);
  digitalWrite(d, HIGH);
  digitalWrite(e, HIGH);
  digitalWrite(f, HIGH);
  digitalWrite(g, HIGH);
  digitalWrite(p, HIGH);
}

void zero()
{
  digitalWrite(a, LOW);
  digitalWrite(b, LOW);
  digitalWrite(c, LOW);
  digitalWrite(d, LOW);
  digitalWrite(e, LOW);
  digitalWrite(f, LOW);
  digitalWrite(g, HIGH);
}

void one()
{
  digitalWrite(a, HIGH);
  digitalWrite(b, LOW);
  digitalWrite(c, LOW);
  digitalWrite(d, HIGH);
  digitalWrite(e, HIGH);
  digitalWrite(f, HIGH);
  digitalWrite(g, HIGH);
}

void two()
{
  digitalWrite(a, LOW);
  digitalWrite(b, LOW);
  digitalWrite(c, HIGH);
  digitalWrite(d, LOW);
  digitalWrite(e, LOW);
  digitalWrite(f, HIGH);
  digitalWrite(g, LOW);
}

void three()
{
  digitalWrite(a, LOW);
  digitalWrite(b, LOW);
  digitalWrite(c, LOW);
  digitalWrite(d, LOW);
  digitalWrite(e, HIGH);
  digitalWrite(f, HIGH);
  digitalWrite(g, LOW);
}

void four()
{
  digitalWrite(a, HIGH);
  digitalWrite(b, LOW);
  digitalWrite(c, LOW);
  digitalWrite(d, HIGH);
  digitalWrite(e, HIGH);
  digitalWrite(f, LOW);
  digitalWrite(g, LOW);
}

void five()
{
  digitalWrite(a, LOW);
  digitalWrite(b, HIGH);
  digitalWrite(c, LOW);
  digitalWrite(d, LOW);
  digitalWrite(e, HIGH);
  digitalWrite(f, LOW);
  digitalWrite(g, LOW);
}

void six()
{
  digitalWrite(a, LOW);
  digitalWrite(b, HIGH);
  digitalWrite(c, LOW);
  digitalWrite(d, LOW);
  digitalWrite(e, LOW);
  digitalWrite(f, LOW);
  digitalWrite(g, LOW);
}

void seven()
{
  digitalWrite(a, LOW);
  digitalWrite(b, LOW);
  digitalWrite(c, LOW);
  digitalWrite(d, HIGH);
  digitalWrite(e, HIGH);
  digitalWrite(f, HIGH);
  digitalWrite(g, HIGH);
}

void eight()
{
  digitalWrite(a, LOW);
  digitalWrite(b, LOW);
  digitalWrite(c, LOW);
  digitalWrite(d, LOW);
  digitalWrite(e, LOW);
  digitalWrite(f, LOW);
  digitalWrite(g, LOW);
}

void nine()
{
  digitalWrite(a, LOW);
  digitalWrite(b, LOW);
  digitalWrite(c, LOW);
  digitalWrite(d, LOW);
  digitalWrite(e, HIGH);
  digitalWrite(f, LOW);
  digitalWrite(g, LOW);
}
```

こんな実装です。ビット演算とかを使えばもっと短く書けますが、たまに不良部品に当たったりして1ピンずつ調べる際に不便なのでそうしていません。ディレイは組み合わせる実装に合わせて適宜コントロールしてください。

浮動小数点数表示とかにしたい際には、適宜いじったりしてやってください。ちなみに[GitHubのsifue/arduino-akitsuki-7seg](https://github.com/sifue/arduino-akitsuki-7seg)にもあげてあります。

参考: http://garretlab.web.fc2.com/arduino/introduction/beginning_with_7segment_led/index.html