Quantcast
Channel: JH7UBCブログ
Viewing all articles
Browse latest Browse all 440

Arduino レシプロカル式カウンタ(7セグメントLED表示)

$
0
0
 Si5351Aの勉強が一段落しましたので、今年の課題のうち、簡単そうなものを一つ片付けました。

 以前に製作したAreduinoレシプロカル式周波数カウンタを7セグメントLED表示にする実験をしました。

 レシプロカル式とは、逆数式という意味で、信号の周期Tを測定して、その逆数を計算することによって、周波数fを得る方式です。つまりf = 1/T の式を使います。

 7セグメントLEDは、秋月電子で販売している超高輝度4桁7セグメントLED(OSL-40562-LRA)を使います。

 約5mAで十分な輝度が得られると書いてあります。予備実験をしました。

イメージ 1

 5Vの電圧のとき、電流制限抵抗が、680Ωの時、電流は4.5mAで、十分な輝度が得られました。

 ということは、7セグメントすべて点灯(8のとき)したとの電流が最大で、31.5mAとなり、Arduinoのデジタルポートで、ドライブできます。

 7セグメントLEDは、ダイナミック点灯です。

 周期の測定は、外部割り込みattachInterrupt(interrupt,function,mode)を利用し、割り込み番号は0(ピン2)、トリガは立ち上がり(RISING)とします。

 回路図です。

イメージ 2

ブレッドボードです。

イメージ 3

スケッチです。

/*
 *レシプロカル式周波数カウンタ
 *7セグメントLEDダイナミック点灯
 * 2016.12.29
 * JH7UBC Keiji Hata
 *
 *   D2   INPUT
 *   D3   7segLED A
 *   D4   7segLED B
 *   D5   7segLED C
 *   D6   7segLED D
 *   D7   7segLED E
 *   D8   7segLED F
 *   D9   7segLED G
 *   D10  7segLED #1
 *   D11  7segLED #2
 *   D12  7segLED #3
 *   D13  7segLED #4
 */

volatile unsigned long duration=0;
volatile unsigned long prevMicros=0;
unsigned int frequency;
int ZeroFlag;    //ゼロフラッグ
int N[4];        //表示する数字(4桁)
int Nx;
//LED レイアウト定義 A,B,C,D,E,F,Gセグメントの順
boolean Num_Array[11][7]={
  {1,1,1,1,1,1,0}, //0
  {0,1,1,0,0,0,0}, //1
  {1,1,0,1,1,0,1}, //2
  {1,1,1,1,0,0,1}, //3
  {0,1,1,0,0,1,1}, //4
  {1,0,1,1,0,1,1}, //5
  {1,0,1,1,1,1,1}, //6
  {1,1,1,0,0,1,0}, //7
  {1,1,1,1,1,1,1}, //8
  {1,1,1,1,0,1,1}, //9
  {0,0,0,0,0,0,0}  //space
  };
//LED配列 
boolean Led_Array[4][4]={
  {0,1,1,1},  //LED1
  {1,0,1,1},  //LED2
  {1,1,0,1},  //LED3
  {1,1,1,0}   //LED4
};

void setup()
{
  attachInterrupt(0, periodIrq, RISING);
  for (int i=3;i<=13;i++)   //pin2~13を出力に設定
  {
    pinMode(i,OUTPUT);
  }
}
void loop()
{
  frequency = 1000000 / duration; //f=1/T
  Num_set(frequency);             //周波数の値をN[0]~N[3]にセット
  int var = 0;
  while(var < 20){                   //20の値は、要調節
   for(int i=0;i<4;i++){
      LedActive(i);
      NumPrint(N[i]);
      delay(6);
      NumPrint(10);     //一旦表示を消す
  }
  var++;
  }
}
void periodIrq() // interrupt handler
{
  unsigned long currentMicros = micros();
  duration = currentMicros - prevMicros;
  prevMicros = currentMicros;
}
//数字表示
void NumPrint(int Number){
  for (int w=0; w<=6; w++){
  digitalWrite(w+3,Num_Array[Number][w]);
  }
}
//LED点灯
void LedActive(int Number){
  for (int w=0; w<=3; w++){
    digitalWrite(w+10,Led_Array[Number][w]);
  }
}
//数字の分解(1000の位、100の位、10の位、1の位)とセット
void Num_set(int X){
  ZeroFlag=1;
  N[0] = X / 1000;
  if (N[0] == 0){
    N[0]=10;        //10=space
  }else{
    ZeroFlag=0;
  }
  Nx = X % 1000;
  N[1] = Nx / 100;
  if (N[1] == 0 & ZeroFlag == 1){
    N[1]=10;
  }else{
    ZeroFlag = 0;
  }
 
  Nx = X % 100;
  N[2] = Nx / 10;
  if (N[2] == 0 & ZeroFlag ==1){
    N[2]=10;
   }
  N[3] = X % 10;
}

このスケッチで10Hz~5000Hzまで、OKです。

こんな低い周波数しか測れないカウンタが、どうして必要なのかと言いますと、普通の周波数カウンタは、1秒ごとにしか周波数を測定すりことができません。(0.1秒の場合もあります)レシプロカル式は、1周期の時間があれば良いので、極端なことを言えば、1000Hzは1/1000秒=1msecあれば周波数を測定することができます。

つまり、短い時間で周波数を測定したい時に有効なカウンタなのです。

使い方としては、楽器のチューニングやドップラー効果の測定などが考えられます。


Viewing all articles
Browse latest Browse all 440

Trending Articles