Skip to content

可変抵抗器の使い方

このセクションでは、可変抵抗器(ポテンショメータ)の使い方を学びます。可変抵抗器は、ツマミを回すことで抵抗値を連続的に変化させられる電子部品です。音量の調整(ボリューム)など、ユーザーからの直感的なアナログ入力を受け付けるために広く使われます。

動作原理と分圧回路

可変抵抗器は、内部の抵抗体の上の接点をツマミで動かすことで、抵抗値を変化させます。通常3本の端子があり、両端の端子に電圧(例えば3.3VとGND)をかけると、真ん中の端子からはツマミの位置に応じた0Vから3.3Vまでの電圧が出力されます。これは、マイコンでアナログ値を読み取るための最も基本的な回路である分圧回路そのものです。

  • ツマミをGND側に回し切ると、出力電圧は0Vに近づきます。
  • ツマミを3.3V側に回し切ると、出力電圧は3.3Vに近づきます。

このように、物理的なツマミの角度を、連続的に変化する電圧の値であるアナログ信号に変換できるのです。マイコンはADC (Analog to Digital Converter) という機能を使って、このアナログ電圧をデジタル値に変換して処理します。

回路図と接続

可変抵抗器の3本の端子を、Raspberry Pi Picoに接続します。真ん中の端子を、ADCが使えるアナログ入力ピン(例えばGP26)に接続します。

(ここに circuits.drawio で作成した可変抵抗器の回路図を挿入)

可変抵抗器 Raspberry Pi Pico
VCC (or 3V3) 3.3V (OUT)
GND GND
OUT (or SIG) GP26 (ADC0)

プログラム

以下のプログラムは、GP26ピンから可変抵抗器の値を読み取り、シリアルモニタに表示します。まずはこのコードを書き込んで、ツマミを回したときに値がどう変化するか観察してみましょう。

#include <Arduino.h>
#define SENSOR_PIN 26 // 可変抵抗器の出力を接続するピン (ADC0)

void setup() {
    Serial.begin(115200); // シリアル通信の開始
    analogReadResolution(12); // ADCの解像度を12ビットに設定 (0〜4095)
}

long readAverage(int pin, int samples) {
    long sum = 0;
    for (int i = 0; i < samples; i++) {
        sum += analogRead(pin);
        delay(1); // わずかな時間をおいてサンプリング
    }
    return sum / samples;
}

void loop() {
    // analogReadでセンサーの値を読み取る (0〜4095の範囲)
    int sensorValue = analogRead(SENSOR_PIN);

    // 読み取った値をシリアルモニタに表示
    Serial.print("Sensor Value: ");
    Serial.println(sensorValue);

    delay(500); // 0.5秒待機
}

コードの解説

  • #define SENSOR_PIN 26: センサーを接続したピンを定数として定義します。PicoのアナログピンはGP26, 27, 28です。それぞれADC0, 1, 2に対応します。
  • analogRead(SENSOR_PIN): 指定したアナログピンの電圧を読み取ります。Raspberry Pi PicoのADCは12ビットの分解能を持つため、0Vから3.3Vの電圧を0から4095のデジタル値に変換して返します。Arduino Unoなどは10ビット(0-1023)なので、マイコンによって分解能が違う点に注意が必要です。
  • ツマミを回すと、シリアルモニタに表示される値が0から4095まで変化することを確認してみましょう。

ノイズ対策:より安定した値を得るために

シリアルモニタの値をじっと見ていると、ツマミを固定しているのに、値が細かく変動(ふらつく)ことに気づくかもしれません。これは部品の故障ではなく、電源や周囲の環境から来るノイズの影響です。

実用的なシステムでは、このような不安定な生の値をそのまま使うことは稀です。最も簡単で効果的なノイズ対策は、複数回測定してその平均値を使うことです。これを移動平均フィルターと呼びます。

サンプルコードのloop()を以下のように変更し、10回の測定の平均値を使うようにしてみましょう。

void loop() {
    // 10回の測定値の平均を取る
    int sensorValue = readAverage(SENSOR_PIN, 10); 

    // 読み取った値をシリアルモニタに表示
    Serial.print("Sensor Value: ");
    Serial.println(sensorValue);

    delay(500); // 0.5秒待機
}

loopの中から値を1回だけ読んでいた処理を、10回読んで平均を返すreadAverage関数に置き換えました。こうすることで、突発的なノイズの影響が緩和され、より安定した測定値が得られるようになります。