Arduinoで周波数カウンタ【改良版・Seeeduino Xiao】

Arduinoで周波数カウンタ【Seeeduino Xiao】
Arduinoで周波数カウンタ【Seeeduino Xiao】

この記事では、Arduinoで作る周波数カウンタを紹介する。今回の周波数カウンタは、前回の改良版となる。

前回の周波数カウンタは、Arduinoの割り込み処理によるもので非常に簡単に周波数を測定できた。しかし、信号を測定してみると20kHz程度が限界となってしまうようだ。

前回の周波数カウンタはこちら

そこで、今回は数百キロHz以上の高周波を測定できるように改良してみた。

プログラムの改善とともに、自作のデジタルインタフェースも改良した。詳しくはこちらの記事を参考に。

なお、Arduino互換機であるSeeeduino Xiaoを使用している。

周波数カウンタのプログラム

こちらが、改良を行なった周波数カウンタのプログラムである。

#include <U8g2lib.h>
#define FREQ_PIN A2
U8G2_SSD1306_128X32_UNIVISION_F_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE);

int sampleCount = 9;

void setup() {
  Serial.begin(9600);
  u8g2.begin();
  pinMode(FREQ_PIN, INPUT);
}


void loop() {
  float f = countFreq();
  displayOLCD(f);
  delay(1000);
}


float countFreq() {
  float s[sampleCount];
  for(int i=0; i < sampleCount; i++) {
    int pulseHigh = pulseIn(FREQ_PIN, HIGH);
    int pulseLow = pulseIn(FREQ_PIN, LOW);
    s[i] = pulseHigh + pulseLow; // Time period of the pulse in microseconds
  }
  return 1e6/medianFilter(s);
}


float medianFilter(float s[]) {
  int total = sizeof(s);
  for (int i=0; i<total; ++i) {
    for (int j=i+1; j<total; ++j) {
      if (s[i] > s[j]) {
        float tmp =  s[i];
        s[i] = s[j];
        s[j] = tmp;
      }
    }
  }
  int m = total / 2;
  return s[m];
}


void displayOLCD(float f) {
    char buf[15];
    if(f>10000) {
     snprintf(buf, 15, "%.1f [kHz]", f/1000);
    } else if(f>1000) {
     snprintf(buf, 15, "%.2f [kHz]", f/1000);
    } else {
      snprintf(buf, 15, "%.1f [Hz]", f);
    }
    u8g2.clearBuffer();
    u8g2.setFont(u8g2_font_crox3hb_tf);
    u8g2.drawStr(0, 16, buf);
    u8g2.sendBuffer();
}

周波数測定の方法

前回の周波数カウンタでは、割り込み処理の呼び出しにより信号の周期を測定した。しかし、どうも呼び出し速度に限界があるようだ。そこで今回は、pulseIn関数を使って周期の測定を行なっている。

pulseIn(ピン番号, HIGH)にすると、信号がHIGHになっている間の時間をマイクロ秒で返してくれる。pulseIn(ピン番号, LOW)にすれば、同じく信号がLOWになっている時間を返してくれる。よって、それぞれを足し合わせれば信号の1周期の時間が分かるという仕組みだ。

pulseIn() - Reference

メディアンフィルタ

メディアンフィルタの仕組み
メディアンフィルタの仕組み

プログラム中では、ノイズを除去しつつ精度を上げるためにメディアンフィルタを使用している。図のように、周りの数字が1・2・3のように低いのに、明らかに不自然な7という大きなノイズが入った場合を考えてみよう。

メディアンフィルタでは、サンプル(周囲の値)を小さい順に並べ、真ん中の値を採用するもの。これによって、明らかなノイズを除去できるのだ。

平均値だとノイズ値も加算されてしまうが、メディアンフィルタだと完全に除去することができる。この利点を活かして、画像のフィルタリングなどでメディアンフィルタは大活躍している。今回のような周波数測定でも、有効なフィルタだ。

Median filter - Wikipedia

さて、プログラムでは周期のサンプルを9回取り、それを昇順に並べ変えてその中央値を信号の周期として採用した。

Arduinoで周波数カウンタ【Seeeduino Xiao】
Arduinoで周波数カウンタ【Seeeduino Xiao】

こちらの写真は、約130kHzの正弦波を測定したものである。周波数が高くになるにつれ、誤差が出てしまうが前回の周波数カウンタから比べると大分マシになったと思う。

ちなみに発振器は、こちらの記事で作ったコルピッツ発振回路で作ったものだ。よかったら参考に。

この記事で扱った製品はこちら

Seeed Studio Seeeduino XIAO-Arduino IDE 互換ボード SAMD21 Cortex M0+搭載 ブレッドボード互換 USB Type-C
Seeed Studio Seeeduino XIAO-Arduino IDE 互換ボード SAMD21 Cortex M0+搭載 ブレッドボード互換 USB Type-C

Seeeduino XIAO開発ボードは、ARMCortex-M0+ 32ビット48MHzマイクロコントローラー(SAMD21G18)を搭載し、低消費電力です。クロック周波数は48MHzと、Arduino Uno、Arduino Nanoの3倍です。 又、このArduino IDE互換ボードには256KBのフラッシュメモリ、32KBのSRAMも搭載されています。

AmazonRakuten
DSD TECH 2 PCS OLED 0.91インチディスプレイ IIC I2C シリアルポート Arduino ARM用
DSD TECH 2 PCS OLED 0.91インチディスプレイ IIC I2C シリアルポート Arduino ARM用

0.91インチのOLEDディスプレイ:解像度128 * 32、非常にクリア、黒の背景、青色のテキスト表示。 IIC(I2C)インタフェース:SPIインタフェース画面よりも4つのPIN(VCC、GND、SCL、SDA)だけが簡単です。 他のセンサーを接続するために、さらに多くのポートを残すことができます。

AmazonRakuten

こんな商品も人気です!

1.54インチ 電子ペーパーモジュール 200x200ラズベリーパイ エンベデッドコントローラ付き E-Inkディスプレイ画面
1.54インチ 電子ペーパーモジュール 200x200ラズベリーパイ エンベデッドコントローラ付き E-Inkディスプレイ画面

バックライトがなく、電源を切っても最後のコンテンツが長時間表示される。 超低消費電力、基本的に電力はリフレッシュにのみ必要です。 SPIインターフェイス、Raspberry Pi / Arduino / Nucleoなどのコントローラーボードとの接続用。

AmazonRakuten
M5Stack 開発ボード M5Stack Core2 開発キットデュアルコア32ビット240Mhz LX6プロセッサーUIFlow, MicroPython, A r d u i n o用
M5Stack 開発ボード M5Stack Core2 開発キットデュアルコア32ビット240Mhz LX6プロセッサーUIFlow, MicroPython, A r d u i n o用

Amazon
ELEGOO Arduino用 Nanoボード V3.0 CH340/ATmega328P、Nano V3.0互換
ELEGOO Arduino用 Nanoボード V3.0 CH340/ATmega328P、Nano V3.0互換

NanoはArduinoと互換性があり、ATmega328PやCH340と同じの公式バージョンで使用しています。 これは、最小で、完全で、ブレッドボードに優しいボードです。より多くのアナログ入力ピンとオンボード+ 5V AREFジャンパを備えた(電気的に)すべてが備わっています。

Amazon
ELEGOO Arduino用の 2.8 Inches TFT ターチスクリーン カードソケット付
ELEGOO Arduino用の 2.8 Inches TFT ターチスクリーン カードソケット付

無料チュートリアル(CDに収録)、より良い価格、より良いサービス。 (技術データ付き) 2.8インチ多彩なディスプレイ液晶画面 タッチペンも付き

AmazonRakuten

Arduinoの参考書

ESP32&Arduino 電子工作 プログラミング入門
ESP32&Arduino 電子工作 プログラミング入門

電子工作ファンに人気のマイコンArduino、そしてWiFiとBluetooth内蔵でネットワーク接続しやすいESP32。それらのマイコンでプログラムを組む際に使うのが「Arduino言語」です。「電子工作は好きだけどプログラミングはよくわからない」あるいは「プログラミングの経験がある。それを活かして電子工作を楽しみたい」--そんなみなさまのための電子工作プログラミング入門が本書です。

KindleAmazonRakuten
電子部品ごとの制御を学べる! Arduino 電子工作実践講座 改訂第2版
電子部品ごとの制御を学べる! Arduino 電子工作実践講座 改訂第2版

電子パーツを自由自在に組み合わせて電子工作ができるように、Arduinoによる電子部品ごとの制御方法を詳しく解説。初心者や電子工作に躓いた人でも安心して取り組めるよう、豊富な図・写真で徹底解説。2018年発刊の「Arduino 電子工作 実践講座」の改訂版です。

KindleAmazonRakuten
Arduinoをはじめよう 第3版 (Make:PROJECTS)
Arduinoをはじめよう 第3版 (Make:PROJECTS)

本書では、開発者自らが、Arduinoの哲学、ハードウェア、ソフトウェアの基礎を解説、誰にでもできる簡単なチュートリアルを行います。

AmazonRakuten

Amazonでお得に購入するなら、Amazonギフト券がオススメ!

\Amazonギフトがお得/

コンビニ・ATM・ネットバンキングで¥5,000以上チャージすると、プライム会員は最大2.5%ポイント、通常会員は最大2%ポイントがもらえます!
Amazonギフト券

\この記事をシェアする/