Arduinoを使った7セグメントLEDの制御

この投稿ではArduinoを使って7セグメントLED(516AS)を制御しようと思います。
目標は点灯箇所を2進数で制御し、7セグメントのLEDを0から9のパターンで点灯させることです。
初めての投稿で、至らない点多いと思いますが、質問等をコメントしていただければ可能な限り対応したいと思います。


回路の作成

516ASとArduinoを下の写真のように接続します。Arduinoは2番から8番ピンを使用しています。抵抗は220Ωを使用しています。7セグメントのD.Pは使用しません。

Arduinoと7セグメントの接続

コードの作成

2進数を使った制御概要

今回は7セグメントのLEDを0から9の値で点灯させることを目標とします。7セグメントの制御には主に配列を使ったLED制御が使用されると思います。

配列を使用するメリットとして、指定した桁数へのアクセスが容易な一方で、論理和やシフト操作などの操作がめんどくさいことが短所として挙げられます。

そのため、今回の記事では制御は2進数を用いることで、配列を使った制御で発生していた問題の解決を行います。

2進数の任意の桁にアクセスする

2進数の任意の桁にアクセスするために使用する式は、このサイトで紹介されている式を参考にします。

任意の10進数を2進数に変換したうえで任意の桁数にアクセスする式を以下に示します。

$$
\frac{(x \% 2^{n+1}) - (x \% 2^{n})}{2^{n}}
$$

この式で、xは任意の10進数を示し、nはアクセスする桁(0以上の整数)を示します。

この式を使ったコードは以下の関数定義します。
このコードを使うことで2進数の任意の桁にアクセスすることができます。

// 2進数の任意の桁にアクセスする関数
 inline bool access_digit(uint8_t num, uint8_t digit){
  return (((num % (1 << digit+1)))-(num % (1 << digit)))/(1 << digit); //powを使うとintに変換したときに誤差が大きいので、シフト演算子を使う
}

この関数では2の乗数を求めるために、左シフトを使用しています。Arduinoには乗数を求めるためにpow()関数が用意されていますが、計算結果がdouble型で返され、int型に変換する際に誤差が発生します。そのため、pow()関数ではなく、シフトを使用しています。

作成したソースコード

ソースコードの全体を以下に示します。segs[]で0から9のセグメントの点灯パターンを定義しています(2進表記と16進表記が混合していてもうしわけないです)。

const uint8_t segment_pins[] = {2, 3, 4, 5, 6, 7, 8, 9}; //7セグメントと接続するピン番号

uint8_t segs[] = {0x3F, 0x09, B01011110, 0x5B, 0x69, B01110011, B01110111, B00011001, 0x7F, B01111011}; //7セグメントの対応

// 2進数の任意の桁にアクセスする関数
 inline bool access_digit(uint8_t num, uint8_t digit){
  return (((num % (1 << digit+1)))-(num % (1 << digit)))/(1 << digit); //powを使うとintに変換したときに誤差が大きいので、シフト演算子を使う
}

void setup() {
  Serial.begin(115200);
  pinMode(A0, INPUT);
  for(uint8_t i = 0; i < sizeof(segment_pins)/sizeof(segment_pins[0]); i++){
    pinMode(segment_pins[i], OUTPUT);
  }
}

void loop() {
  for(uint8_t i = 0; i < sizeof(segs)/sizeof(segs[0]); i++){
    for(uint8_t j = 0; j < sizeof(segment_pins)/sizeof(segment_pins[0]); j++){
      Serial.println(digitalRead(A0));
      digitalWrite(segment_pins[j], access_digit(segs[i], j));
    }
  delay(10);
  }
}

この記事が気に入ったらサポートをしてみませんか?