注釈
こんにちは、SunFounder Raspberry Pi & Arduino & ESP32 愛好家コミュニティ(Facebook)へようこそ! Raspberry Pi、Arduino、ESP32 について、仲間と一緒により深く学びましょう。
参加する理由
専門的なサポート: 購入後の問題や技術的な課題を、コミュニティとチームがサポートします。
学びと共有: 技術や作例の情報交換でスキルを向上させます。
限定先行情報: 新製品の発表や先行プレビューを入手できます。
特別割引: 最新製品の限定割引を利用できます。
季節イベントと景品: プレゼント企画や季節のイベントに参加できます。
👉 ものづくりの世界を一緒に探求しませんか?[ここ] をクリックして今すぐ参加!
2.1.4 可変抵抗器(MCP3008)
はじめに
ADC(アナログ-デジタル変換)機能は、アナログ信号をデジタル値に変換するために使われます。 この実験では MCP3008 ADC チップを用いて変換を行います。 可変抵抗器を回すことで電圧が変化し、その変化を MCP3008 がデジタル値に変換し、Raspberry Pi で読み取り・処理します。
必要な部品
本プロジェクトで必要な部品は以下の通りです。
原理
MCP3008
MCP3008 は 8 チャンネル入力を持つ 10ビット逐次比較型ADC で、SPI(シリアルペリフェラルインタフェース)通信方式を採用しています。 マイコンと接続してアナログ信号をデジタルデータに変換し、処理に利用できます。
動作の流れ
MCP3008 との通信を始めるには、CS(チップセレクト)を Low にします。
マイコンから SPI 経由で3バイトの制御データを送信し、設定と読み出すチャンネルを指定します。
最初のバイトには開始ビットとシングル/差動選択ビットが含まれます。次のビットで CH0〜CH7 を選択します。
クロックの立ち上がりごとにデータが取り込まれ、同時に変換結果が送信されます。
内部で入力チャンネルの安定時間を確保した後、サンプル・アンド・ホールド回路と SAR コンパレータで10ビット変換を行います。
変換結果は MISO(Master In Slave Out)から MSB(最上位ビット)から順に送られます。
全10ビットのデータが送られると、次のコマンド待ち状態になります。
可変抵抗器
可変抵抗器は3端子を持つ抵抗部品で、つまみやスライダーの位置によって抵抗値を変えることができます。 抵抗体と可動接点から構成され、接点の位置によって抵抗値や出力電圧が変化します。
可変抵抗器の主な機能は以下の通りです。
分圧器として使う 軸やスライダーを動かすことで、可動接点が抵抗体上を移動し、その位置に応じて出力電圧が変化します。
回路図
T-Board 名 |
物理ピン |
WiringPi |
BCM |
|---|---|---|---|
SPICE0 |
pin24 |
10 |
8 |
SPIMOSI |
pin19 |
12 |
10 |
SPIMISO |
pin21 |
13 |
9 |
SPISCLK |
pin23 |
14 |
11 |
GPIO22 |
pin15 |
3 |
22 |
実験手順
手順1: 回路を組みます。
注釈
図の位置関係を参考にチップを配置してください。溝が左側になるように置きます。
手順2: コードファイルを開きます。
cd ~/davinci-kit-for-raspberry-pi/c/2.1.4-2/
手順3: コードをコンパイルします。
gcc 2.1.4_Potentiometer.c -lwiringPi
手順4: 実行します。
sudo ./a.out
プログラム実行後、可変抵抗器のつまみを回すと、LEDの明るさが変化します。
注釈
実行後に動作しない場合や 「wiringPi.h: No such file or directory」というエラーが出る場合は、wiringPi のインストールと確認 を参照してください。
コード
#include <wiringPi.h>
#include <wiringPiSPI.h>
#include <stdio.h>
#include <softPwm.h>
#define SPI_CHANNEL 0 // CE0
#define SPI_SPEED 1000000 // 1MHz
#define LedPin 3
int readADC(int channel) {
if (channel < 0 || channel > 7) return -1;
unsigned char buffer[3];
buffer[0] = 1; // 開始ビット
buffer[1] = (8 + channel) << 4; // シングルエンドモード + チャンネル指定
buffer[2] = 0;
wiringPiSPIDataRW(SPI_CHANNEL, buffer, 3);
int value = ((buffer[1] & 3) << 8) | buffer[2];
return value;
}
int main(void) {
if (wiringPiSetup() == -1) {
printf("WiringPi init failed!\n");
return 1;
}
if (wiringPiSPISetup(SPI_CHANNEL, SPI_SPEED) == -1) {
printf("SPI setup failed!\n");
return 1;
}
softPwmCreate(LedPin, 0, 100);
while (1) {
int analogVal = readADC(0); // CH0
printf("ADC Value: %d\n", analogVal);
int pwmVal = analogVal * 100 / 1023; // 0〜100 に正規化
softPwmWrite(LedPin, pwmVal);
delay(100);
}
return 0;
}
コード解説
#define SPI_CHANNEL 0 // CE0
#define SPI_SPEED 1000000 // 1MHz
#define LedPin 3
SPI チャンネルを CE0 に設定、通信速度を 1MHz に設定し、LED のピンを GPIO3 に割り当てています。
int readADC(int channel) {
if (channel < 0 || channel > 7) return -1;
unsigned char buffer[3];
buffer[0] = 1; // 開始ビット
buffer[1] = (8 + channel) << 4; // シングルエンドモード + チャンネル指定
buffer[2] = 0;
wiringPiSPIDataRW(SPI_CHANNEL, buffer, 3);
int value = ((buffer[1] & 3) << 8) | buffer[2];
return value;
}
この関数は MCP3008 からアナログデータを読み取ります。
チャンネル番号が 0〜7 の範囲かを確認します。
3バイト配列を準備し、
buffer[0]に開始ビットbuffer[1]にシングルエンドモードとチャンネル番号buffer[2]は結果受信用の空データ を格納します。
wiringPiSPIDataRWで SPI 送受信を行います。ビット演算で 10ビットの結果を抽出します。
int main(void) {
if (wiringPiSetup() == -1) {
printf("WiringPi init failed!\n");
return 1;
}
if (wiringPiSPISetup(SPI_CHANNEL, SPI_SPEED) == -1) {
printf("SPI setup failed!\n");
return 1;
}
softPwmCreate(LedPin, 0, 100);
while (1) {
int analogVal = readADC(0); // CH0
printf("ADC Value: %d\n", analogVal);
int pwmVal = analogVal * 100 / 1023; // 0〜100 に正規化
softPwmWrite(LedPin, pwmVal);
delay(100);
}
return 0;
}
メイン関数では、
wiringPiSetup()でライブラリを初期化wiringPiSPISetup()で SPI 通信を設定softPwmCreate()で GPIO3 に PWM を設定(0〜100)
その後無限ループに入り、
CH0 から ADC 値を読み取る
値を表示
PWM 用に 0〜100 に変換
LED の明るさを更新
delay(100) で 100ms 待機します。